From 1371efbf0086da87140bd920290689da62e5414b Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sat, 13 Aug 2022 06:03:45 +0800 Subject: [PATCH 001/463] generalize EllipticCurve_field.division_field() to composite orders --- src/sage/schemes/elliptic_curves/ell_field.py | 141 +++++++++++------- 1 file changed, 86 insertions(+), 55 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 5a5fdf1fcb6..42d813ca841 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -779,18 +779,17 @@ def descend_to(self, K, f=None): Elist = [E.minimal_model() for E in Elist] return Elist - def division_field(self, l, names='t', map=False, **kwds): + def division_field(self, n, names='t', map=False, **kwds): r""" - Given an elliptic curve over a number field or finite field `F` - and a prime number `\ell`, construct the `\ell`-division field - `F(E[\ell])`. + Given an elliptic curve over a number field or finite field `F` and + a positive integer `n`, construct the `n`-division field `F(E[n])`. - The `\ell`-division field is the smallest extension of `F` over - which all `\ell`-torsion points of `E` are defined. + The `n`-division field is the smallest extension of `F` over which + all `n`-torsion points of `E` are defined. INPUT: - - `\ell` -- a prime number (an element of `\ZZ`) + - `n` -- a positive integer - ``names`` -- (default: ``'t'``) a variable name for the division field - ``map`` -- (default: ``False``) also return an embedding of the :meth:`base_field` into the resulting field @@ -807,7 +806,7 @@ def division_field(self, l, names='t', map=False, **kwds): .. WARNING:: This can take a very long time when the degree of the division - field is large (e.g. when `\ell` is large or when the Galois + field is large (e.g. when `n` is large or when the Galois representation is surjective). The ``simplify`` flag also has a big influence on the running time over number fields: sometimes ``simplify=False`` is faster, sometimes the default @@ -832,8 +831,8 @@ def division_field(self, l, names='t', map=False, **kwds): Number Field in b with defining polynomial x^6 + 10*x^5 + 24*x^4 - 212*x^3 + 1364*x^2 + 24072*x + 104292 - For odd primes `\ell`, the division field is either the splitting - field of the `\ell`-division polynomial, or a quadratic extension + For odd primes `n`, the division field is either the splitting + field of the `n`-division polynomial, or a quadratic extension of it. :: sage: E = EllipticCurve('50a1') @@ -864,8 +863,7 @@ def division_field(self, l, names='t', map=False, **kwds): by y^2 = x^3 + 5*a0*x^2 + (-200*a0^2)*x + (-42000*a0^2+42000*a0+126000) over Number Field in a0 with defining polynomial x^3 - 3*x^2 + 3*x + 9 sage: K. = E.division_field(3, simplify_all=True); K # optional - sage.rings.number_field - Number Field in b with defining polynomial - x^12 + 5*x^10 + 40*x^8 + 315*x^6 + 750*x^4 + 675*x^2 + 2025 + Number Field in b with defining polynomial x^12 - 25*x^10 + 130*x^8 + 645*x^6 + 1050*x^4 + 675*x^2 + 225 Some higher-degree examples:: @@ -938,9 +936,35 @@ def division_field(self, l, names='t', map=False, **kwds): sage: K. = E.division_field(7); K # optional - sage.rings.finite_rings Finite Field in v of size 433^16 + It also works for composite orders:: + + sage: E = EllipticCurve(GF(11), [5,5]) + sage: E.change_ring(E.division_field(8)).abelian_group().torsion_subgroup(8).invariants() + (8, 8) + sage: E.change_ring(E.division_field(9)).abelian_group().torsion_subgroup(9).invariants() + (9, 9) + sage: E.change_ring(E.division_field(10)).abelian_group().torsion_subgroup(10).invariants() + (10, 10) + sage: E.change_ring(E.division_field(36)).abelian_group().torsion_subgroup(36).invariants() + (36, 36) + sage: E.change_ring(E.division_field(11)).abelian_group().torsion_subgroup(11).invariants() + (11,) + sage: E.change_ring(E.division_field(66)).abelian_group().torsion_subgroup(66).invariants() + (6, 66) + + ...also over number fields:: + + sage: R. = PolynomialRing(QQ) + sage: K. = NumberField(x^2 + 1) + sage: E = EllipticCurve([0,0,0,0,i]) + sage: L,emb = E.division_field(6, names='b', map=True); L + Number Field in b with defining polynomial x^24 + 12*x^23 + 66*x^22 - 504*x^21 + 92415*x^20 + 1372020*x^19 + 9791248*x^18 + 9161712*x^17 + 2248687014*x^16 + 39282444252*x^15 + 319379172870*x^14 + 1647604458936*x^13 + 6124888492503*x^12 + 17596271352348*x^11 + 40654930682496*x^10 + 76552797892176*x^9 + 116296878586974*x^8 + 139157022368196*x^7 + 127681305928690*x^6 + 87539428627680*x^5 + 43598049444279*x^4 + 15182945758692*x^3 + 3479289119772*x^2 + 468890060424*x + 28234163953 + sage: E.change_ring(emb).torsion_subgroup().invariants() + (6, 6) + .. SEEALSO:: - To compute a basis of the `\ell`-torsion once the base field + To compute a basis of the `n`-torsion once the base field has been extended, you may use :meth:`sage.schemes.elliptic_curves.ell_number_field.EllipticCurve_number_field.torsion_subgroup` or @@ -948,7 +972,7 @@ def division_field(self, l, names='t', map=False, **kwds): TESTS: - Some random testing:: + Some random for prime orders:: sage: def check(E, l, K): ....: EE = E.change_ring(K) @@ -994,71 +1018,78 @@ def division_field(self, l, names='t', map=False, **kwds): ``splitting_field`` method, moved from ``gal_reps.py``, make it work over number fields. - Lorenz Panny (2022): extend to finite fields + - Lorenz Panny (2023): extend to composite `n`. """ from sage.misc.verbose import verbose - l = rings.Integer(l) - if not l.is_prime(): - raise ValueError("l must be a prime number") + n = rings.Integer(n) + if n <= 0: + raise ValueError("n must be a positive integer") + + verbose("Adjoining X-coordinates of %s-torsion points" % n) - verbose("Adjoining X-coordinates of %s-torsion points" % l) F = self.base_ring() - f = self.division_polynomial(l) - if l == 2 or f.is_constant(): - # For l = 2, the division field is the splitting field of + f = self.division_polynomial(n) + + if n == 2 or f.is_constant(): + # For n = 2, the division field is the splitting field of # the division polynomial. - # If f is a non-zero constant, the l-torsion is trivial: - # This means the curve must be supersingular and l == p. + # If f is a non-zero constant, the n-torsion is trivial: + # This means the curve must be supersingular and n == p. return f.splitting_field(names, map=map, **kwds) + # We divide out the part defining points of non-maximal order. + # Clearly all points of non-maximal order are multiples of points + # of maximal order, so they cannot be defined over a larger field. + if not n.is_prime(): + for d in n.prime_divisors(): + g = self.division_polynomial(n // d) + f //= f.gcd(g) + # Compute splitting field of X-coordinates. - # The Galois group of the division field is a subgroup of GL(2,l). - # The Galois group of the X-coordinates is a subgroup of GL(2,l)/{-1,+1}. - # We need the map to change the elliptic curve invariants to K. + # The Galois group of the division field is a subgroup of GL(2,n). + # The Galois group of the X-coordinates is a subgroup of GL(2,n)/{-1,+1}. if F in NumberFields(): - deg_mult = F.degree() * l * (l+1) * (l-1)**2 // 2 + from sage.misc.misc_c import prod + deg_mult = F.degree() * prod(l * (l+1) * (l-1)**2 * l**(4*(e-1)) for l,e in n.factor()) // 2 K, F_to_K = f.splitting_field(names, degree_multiple=deg_mult, map=True, **kwds) elif F in FiniteFields(): K, F_to_K = f.splitting_field('u', map=True, **kwds) else: raise NotImplementedError('only number fields and finite fields are currently supported') - verbose("Adjoining Y-coordinates of %s-torsion points" % l) + verbose("Adjoining Y-coordinates of %s-torsion points" % n) - # THEOREM (Cremona, https://github.com/sagemath/sage/issues/11905#comment:21). - # Let K be a field, E an elliptic curve over K and p an odd - # prime number. Assume that K contains all roots of the - # p-division polynomial of E. Then either K contains all - # p-torsion points on E, or it does not contain any p-torsion - # point. + # THEOREM + # (Cremona, https://github.com/sagemath/sage/issues/11905#comment:21) + # (Later generalized to composite n by Lorenz Panny) + # + # Let K be a field, E an elliptic curve over K and n a positive + # integer. Assume that K contains all roots of the n-division + # polynomial of E, and that at least one point P of full order n + # is defined over K. Then K contains all n-torsion points on E. # # PROOF. Let G be the absolute Galois group of K (every element - # in it fixes all elements of K). For any p-torsion point P + # in it fixes all elements of K). For any n-torsion point Q # over the algebraic closure and any sigma in G, we must have - # either sigma(P) = P or sigma(P) = -P (since K contains the - # X-coordinate of P). Now assume that K does not contain all - # p-torsion points. Then there exists a point P1 and a sigma in - # G such that sigma(P1) = -P1. Now take a different p-torsion - # point P2. Since sigma(P2) must be P2 or -P2 and - # sigma(P1+P2) = sigma(P1)+sigma(P2) = sigma(P1)-P2 must - # be P1+P2 or -(P1+P2), it follows that sigma(P2) = -sigma(P2). - # Therefore, K cannot contain any p-torsion point. + # either sigma(Q) = Q or sigma(Q) = -Q (since K contains the + # X-coordinate of Q). Similarly, sigma(P+Q) must equal either + # P+Q or -(P+Q). However, since sigma is a group homomorphism, + # we have sigma(P+Q) = sigma(P) + sigma(Q) = P + sigma(Q), + # so either P + sigma(Q) = P+Q, which implies sigma(Q) = Q, + # or P + sigma(Q) = -(P+Q), which implies sigma(Q) = -2P-Q. + # The latter is impossible except for the easier case n = 2. + # Hence, sigma(Q) = Q in all cases. # # This implies that it suffices to adjoin the Y-coordinate - # of just one point. - - # First factor f over F and then compute a root X of f over K. - g = f.factor()[0][0] - X = g.map_coefficients(F_to_K).roots(multiplicities=False)[0] + # of just one full-order point. - # Polynomial defining the corresponding Y-coordinate - curve = self.defining_polynomial().map_coefficients(F_to_K) - ypol = curve(X, rings.polygen(K), 1) - L = ypol.splitting_field(names, map=map, **kwds) + x = f.change_ring(F_to_K).any_root(assume_squarefree=True) + h = self.defining_polynomial().change_ring(F_to_K)(x, rings.polygen(K), 1) + L = h.splitting_field(names, map=map, **kwds) if map: L, K_to_L = L - return L, F_to_K.post_compose(K_to_L) - else: - return L + L = L, F_to_K.post_compose(K_to_L) + return L def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, algorithm=None): r""" From 07379442e8a27ec4416995312816d89b19075a0a Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 8 Sep 2023 17:19:04 -0400 Subject: [PATCH 002/463] src/sage/doctest/control.py: double the default test timeout When running the test suite on an older machine, many files time out. For example, $ sage -t src/sage/manifolds/differentiable/tensorfield.py ... File "src/sage/manifolds/differentiable/tensorfield.py", line 248, in sage.manifolds.differentiable.tensorfield.TensorField Warning: Consider using a block-scoped tag by inserting the line 'sage: # long time' just before this line to avoid repeating the tag 4 times s = t(a.restrict(U), b) ; s # long time Timed out (and interrupt failed) ... ---------------------------------------------------------------------- Total time for all tests: 360.3 seconds cpu time: 0.0 seconds cumulative wall time: 0.0 seconds This has run over the default (non-long) test timeout of 300s. This commit doubles that default, a change that should be unobjectionable for a few reasons: 1. This timeout is a last line of defense intended to keep the test suite from looping forever when run unattended. For that purpose, ten minutes is as good as five. 2. As more tests get added to each file, those files take longer to test on the same hardware. It should therefore be expected that we will sometimes need to increase the timeout. (Basically, if anyone is hitting it, it's too low.) 3. We now use Github CI instead of patchbots for most automated testing, and Github has its own timeout. 4. There is a separate mechanism, --warn-long, intended to catch tests that run for too long. The test timeout should not be thought of as a solution to that problem. Closes: https://github.com/sagemath/sage/issues/32973 --- 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 9261c69dd4b..10338ec9549 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -417,7 +417,7 @@ def __init__(self, options, args): elif options.long: options.timeout = int(os.getenv('SAGE_TIMEOUT_LONG', 30 * 60)) else: - options.timeout = int(os.getenv('SAGE_TIMEOUT', 5 * 60)) + options.timeout = int(os.getenv('SAGE_TIMEOUT', 10 * 60)) # For non-default GC options, double the timeout if options.gc: options.timeout *= 2 From 27c60d767b60ba132ed942eb5113009ee624e5ab Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Wed, 20 Sep 2023 16:17:12 +0200 Subject: [PATCH 003/463] add is_noetherian and divides, for univariate --- src/sage/rings/polynomial/laurent_polynomial.pyx | 6 ++++++ src/sage/rings/polynomial/laurent_polynomial_ring_base.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index cd79996eed7..61ba3870357 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -1969,3 +1969,9 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): 0 """ return self.__u[-self.__n] + + def divides(self, other): + R = self.parent().polynomial_ring() + p = R(self.polynomial_construction()[0]) + q = R(other.polynomial_construction()[0]) + return p.divides(q) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py index 0c9022c492c..f160502d43f 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py @@ -166,7 +166,7 @@ def is_noetherian(self): ... NotImplementedError """ - raise NotImplementedError + return self.base_ring().is_noetherian() def construction(self): """ From e4e3ced9931b4f1a34f4dbf55da90fc55b8e08bd Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Wed, 20 Sep 2023 23:17:32 +0200 Subject: [PATCH 004/463] . --- .../polynomial/laurent_polynomial_mpair.pyx | 53 +++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index 5db2df9dbbd..2e846ed7a53 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -113,16 +113,16 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): if isinstance(k, tuple): k = ETuple(k) D[k] = x_k - self._mon = self._mon.emin(k) # point-wise min of _mon and k + self._mon = self._mon.emin(k) # point-wise min of _mon and k else: x = D - if not self._mon.is_constant(): # factor out _mon + if not self._mon.is_constant(): # factor out _mon x = {k.esub(self._mon): x_k for k, x_k in x.iteritems()} elif (isinstance(x, LaurentPolynomial_mpair) and parent.variable_names() == x.parent().variable_names()): self._mon = (x)._mon x = (x)._poly - else: # since x should coerce into parent, _mon should be (0,...,0) + else: # since x should coerce into parent, _mon should be (0,...,0) self._mon = ETuple({}, int(parent.ngens())) self._poly = parent._R(x) CommutativeAlgebraElement.__init__(self, parent) @@ -275,7 +275,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): self._mon = ETuple({}, int(self._parent.ngens())) return - #cdef dict D = self._poly._mpoly_dict_recursive( + # cdef dict D = self._poly._mpoly_dict_recursive( # self._parent.variable_names(), # self._parent.base_ring() # ) @@ -310,7 +310,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: a.dict() # indirect doctest {(0, 0): 3, (2, -1): 1} """ - #cdef dict D = self._poly._mpoly_dict_recursive(self._parent.variable_names(), + # cdef dict D = self._poly._mpoly_dict_recursive(self._parent.variable_names(), # self._parent.base_ring()) cdef dict D = self._poly.dict() cdef dict DD @@ -1236,7 +1236,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): """ if kwds: f = self.subs(**kwds) - if x: # More than 1 non-keyword argument + if x: # More than 1 non-keyword argument return f(*x) else: return f @@ -1251,7 +1251,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): raise TypeError("number of arguments does not match the number" " of generators in parent") - #Check to make sure that we aren't dividing by zero + # Check to make sure that we aren't dividing by zero cdef Py_ssize_t m for m in range(l): if x[m] == 0: @@ -1514,11 +1514,40 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): x = 'x' i = 0 - #construct ring if none + # construct ring if none if R is None: R = LaurentPolynomialRing(self.base_ring(), x) - return R({m[i]: c for m,c in self.dict().iteritems()}) + return R({m[i]: c for m, c in self.dict().iteritems()}) + + def monomial_reduction(self): + """ + Factor ``self`` into a polynomial and a monomial. + + OUTPUT: + + A tuple ``(p, v)`` where ``p`` is the underlying polynomial and ``v`` + is a monomial. + + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(QQ) + sage: f = y / x + x^2 / y + 3 * x^4 * y^-2 + sage: f.monomial_reduction() + (3*x^5 + x^3*y + y^3, 1/(x*y^2)) + sage: f = y * x + x^2 / y + 3 * x^4 * y^-2 + sage: f.monomial_reduction() + (3*x^3 + y^3 + x*y, x/y^2) + sage: x.monomial_reduction() + (1, x) + sage: (y^-1).monomial_reduction() + (1, 1/y) + """ + self._normalize() + ring = self._parent._R + g = ring.gens() + mon = ring.prod(g[i] ** j for i, j in enumerate(self._mon)) + return (self._poly, mon) def factor(self): """ @@ -1825,3 +1854,9 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): if new_ring is not None: return new_ring(ans) return ans + + def divides(self, other): + R = self.parent().polynomial_ring() + p = R(self.monomial_reduction()[0]) + q = R(other.monomial_reduction()[0]) + return p.divides(q) From df7ed6f7836a303a62c38bf105e06faadd144edf Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Wed, 20 Sep 2023 23:33:56 +0200 Subject: [PATCH 005/463] divides --- src/sage/rings/polynomial/laurent_polynomial.pyx | 2 ++ src/sage/rings/polynomial/laurent_polynomial_mpair.pyx | 2 ++ src/sage/rings/polynomial/laurent_polynomial_ring.py | 5 +++-- src/sage/rings/polynomial/laurent_polynomial_ring_base.py | 4 +--- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 61ba3870357..ff043140e48 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -1972,6 +1972,8 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): def divides(self, other): R = self.parent().polynomial_ring() + if not R.base_ring().is_integral_domain(): + raise NotImplementedError("divisibility test only implemented for polynomials over an integral domain") p = R(self.polynomial_construction()[0]) q = R(other.polynomial_construction()[0]) return p.divides(q) diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index 2e846ed7a53..fe199d281e3 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1857,6 +1857,8 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): def divides(self, other): R = self.parent().polynomial_ring() + if not R.base_ring().is_integral_domain(): + raise NotImplementedError("divisibility test only implemented for polynomials over an integral domain") p = R(self.monomial_reduction()[0]) q = R(other.monomial_reduction()[0]) return p.divides(q) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index ac40e815724..fcd7c90f2f6 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -442,9 +442,10 @@ def __init__(self, R): TESTS:: - sage: TestSuite(LaurentPolynomialRing(Zmod(4), 'y')).run() + # sage: TestSuite(LaurentPolynomialRing(Zmod(4), 'y')).run() sage: TestSuite(LaurentPolynomialRing(ZZ, 'u')).run() - sage: TestSuite(LaurentPolynomialRing(Zmod(4)['T'], 'u')).run() + + # sage: TestSuite(LaurentPolynomialRing(Zmod(4)['T'], 'u')).run() """ if R.ngens() != 1: raise ValueError("must be 1 generator") diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py index f160502d43f..c10cbb219b0 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py @@ -162,9 +162,7 @@ def is_noetherian(self): EXAMPLES:: sage: LaurentPolynomialRing(QQ, 2, 'x').is_noetherian() - Traceback (most recent call last): - ... - NotImplementedError + True """ return self.base_ring().is_noetherian() From 28530fb0a6ea28eb99290ebda0ed9c13ab177587 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Thu, 21 Sep 2023 16:18:20 +0200 Subject: [PATCH 006/463] avoid non integral domains --- .../rings/polynomial/laurent_polynomial.pyx | 3 +- .../polynomial/laurent_polynomial_ideal.py | 32 +++++++++++-------- .../polynomial/laurent_polynomial_ring.py | 5 ++- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index ff043140e48..b134b63ac5e 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -1970,10 +1970,9 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): """ return self.__u[-self.__n] + @coerce_binop def divides(self, other): R = self.parent().polynomial_ring() - if not R.base_ring().is_integral_domain(): - raise NotImplementedError("divisibility test only implemented for polynomials over an integral domain") p = R(self.polynomial_construction()[0]) q = R(other.polynomial_construction()[0]) return p.divides(q) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index aa18314e523..be0e109738d 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -24,6 +24,7 @@ from sage.rings.ideal import Ideal_generic from sage.structure.richcmp import op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE +from sage.arith.misc import GCD class LaurentPolynomialIdeal( Ideal_generic ): def __init__(self, ring, gens, coerce=True, hint=None): @@ -399,31 +400,36 @@ def polynomial_ideal(self, saturate=True): Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y over Rational Field """ - if self._poly_ideal is not None and (self._saturated or not saturate): - return self._poly_ideal P = self.ring() Q = self._poly_ring + if len(P.gens()) == 1: + a = [Q(p.polynomial_construction()[0]) for p in self.gens()] + if P.is_integral_domain(): + a = GCD(a) + return Q.ideal(a) + if self._poly_ideal is not None and (self._saturated or not saturate): + return self._poly_ideal gens = self.gens() if len(gens) == 0: - I = Q.ideal([]) - self._poly_ideal = I - self._hint = I + id = Q.ideal([]) + self._poly_ideal = id + self._hint = id self._saturated = True - return I + return id l2 = [f.__reduce__()[1][0] for f in gens] hint = self._hint l2 += list(hint.groebner_basis()) - I = Q.ideal(l2) + id = Q.ideal(l2) if not saturate: - self._poly_ideal = I - self._hint = I + self._poly_ideal = id + self._hint = id return Q.ideal(l2) n = P.ngens() - I = I.saturation(Q.ideal([Q.monomial(*((1,) * n))]))[0] - self._poly_ideal = I - self._hint = I + id = id.saturation(Q.ideal([Q.monomial(*((1,) * n))]))[0] + self._poly_ideal = id + self._hint = id self._saturated = True - return I + return id def groebner_basis(self, saturate=True): """ diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index fcd7c90f2f6..22d97975cd6 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -442,10 +442,9 @@ def __init__(self, R): TESTS:: - # sage: TestSuite(LaurentPolynomialRing(Zmod(4), 'y')).run() + sage: TestSuite(LaurentPolynomialRing(Zmod(2), 'y')).run() sage: TestSuite(LaurentPolynomialRing(ZZ, 'u')).run() - - # sage: TestSuite(LaurentPolynomialRing(Zmod(4)['T'], 'u')).run() + sage: TestSuite(LaurentPolynomialRing(Zmod(2)['T'], 'u')).run() """ if R.ngens() != 1: raise ValueError("must be 1 generator") From fe8dbac479c135371f9d2825978a0264ce36b7cf Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Fri, 22 Sep 2023 09:04:24 +0200 Subject: [PATCH 007/463] typo in __contains__ --- src/sage/rings/polynomial/laurent_polynomial_ideal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index be0e109738d..b9ead02ea3e 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -197,7 +197,7 @@ def __contains__(self, f): if not f or f in self.gens(): return True f = self.ring()(f) - g = f.__reduce__()[1][0] + g = f.__reduce__()[1][1] return (g in self.polynomial_ideal()) # Operations on ideals From e79852927082127fd5c39fe03348877eee0b3367 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Fri, 22 Sep 2023 18:18:24 +0200 Subject: [PATCH 008/463] reduction of matrices of Laurent polynomials --- src/sage/matrix/matrix_mpolynomial_dense.pyx | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/sage/matrix/matrix_mpolynomial_dense.pyx b/src/sage/matrix/matrix_mpolynomial_dense.pyx index d8819bdc7cc..4679f1c72a7 100644 --- a/src/sage/matrix/matrix_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_mpolynomial_dense.pyx @@ -21,6 +21,7 @@ from sage.matrix.matrix_generic_dense cimport Matrix_generic_dense from sage.matrix.matrix2 cimport Matrix from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular +from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular from sage.libs.singular.function import singular_function @@ -554,3 +555,24 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): self.cache('det', d) return d + + def laurent_matrix_reduction(self): + R = self._base_ring + n_rows, n_cols = self.dimensions() + mat_l = identity_matrix(R, n_rows) + mat_r = identity_matrix(R, n_cols) + if not isinstance(R, LaurentPolynomialRing_generic): + return mat_l, self, mat_r + res = self + for j, rw in enumerate(self.rows()): + for t in R.gens(): + n = min(mon.degree(t) for a in rw for cf, mon in a) + res.rescale_row(j, t ** -n) + mat_l.rescale_col(j, t ** n) + for j, cl in enumerate(self.columns()): + for t in R.gens(): + n = min(mon.degree(t) for a in cl for cf, mon in a) + res.rescale_col(j, t ** -n) + mat_r.rescale_row(j, t ** n) + res = res.change_ring(R.polynomial_ring()) + return mat_l, res, mat_r From 97bd76c4f3e6057faa84c47da56ce7fafe8c37f1 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Fri, 22 Sep 2023 18:23:10 +0200 Subject: [PATCH 009/463] import identity --- src/sage/matrix/matrix_mpolynomial_dense.pyx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/matrix/matrix_mpolynomial_dense.pyx b/src/sage/matrix/matrix_mpolynomial_dense.pyx index 4679f1c72a7..ad8e8bceba3 100644 --- a/src/sage/matrix/matrix_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_mpolynomial_dense.pyx @@ -19,6 +19,7 @@ AUTHOR: #***************************************************************************** from sage.matrix.matrix_generic_dense cimport Matrix_generic_dense from sage.matrix.matrix2 cimport Matrix +from sage.matrix.constructor import identity_matrix from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic From 2888c7bdf8613dca8ff6cc71808bff9492815387 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sat, 23 Sep 2023 01:29:29 +0200 Subject: [PATCH 010/463] doctests --- src/sage/matrix/matrix_mpolynomial_dense.pyx | 76 ++-- .../rings/polynomial/laurent_polynomial.pyx | 58 ++- .../polynomial/laurent_polynomial_ideal.py | 35 +- .../polynomial/laurent_polynomial_mpair.pyx | 10 +- .../polynomial/laurent_polynomial_ring.py | 6 +- .../laurent_polynomial_ring_base.py | 5 +- .../rings/polynomial/laurent_reduction.py | 50 +++ .../rings/polynomial/polynomial_element.pyx | 344 +++++++++--------- 8 files changed, 328 insertions(+), 256 deletions(-) create mode 100644 src/sage/rings/polynomial/laurent_reduction.py diff --git a/src/sage/matrix/matrix_mpolynomial_dense.pyx b/src/sage/matrix/matrix_mpolynomial_dense.pyx index ad8e8bceba3..0a7ba60db75 100644 --- a/src/sage/matrix/matrix_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_mpolynomial_dense.pyx @@ -9,20 +9,18 @@ AUTHOR: * Martin Albrecht """ -#***************************************************************************** +# ***************************************************************************** # Copyright (C) 2013 Martin Albrecht # # 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.matrix.matrix_generic_dense cimport Matrix_generic_dense from sage.matrix.matrix2 cimport Matrix -from sage.matrix.constructor import identity_matrix from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular -from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular from sage.libs.singular.function import singular_function @@ -101,7 +99,8 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): [ 0 -x + y] """ x = self.fetch('echelon_form_'+algorithm) - if x is not None: return x + if x is not None: + return x if algorithm == "frac": E = self.matrix_over_field() @@ -116,8 +115,8 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): if algorithm == "frac": self.cache('pivots', E.pivots()) elif algorithm == "bareiss": - l = E.swapped_columns() - self.cache('pivots', tuple(sorted(l))) + l1 = E.swapped_columns() + self.cache('pivots', tuple(sorted(l1))) elif algorithm == "row_reduction": pass @@ -154,7 +153,7 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): x = self.fetch('pivots') if x is None: - raise RuntimeError("BUG: matrix pivots should have been set but weren't, matrix parent = '%s'"%self.parent()) + raise RuntimeError("BUG: matrix pivots should have been set but weren't, matrix parent = '%s'" % self.parent()) return x def echelonize(self, algorithm='row_reduction', **kwds): @@ -262,7 +261,7 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): self.clear_cache() singular_bareiss = singular_function("bareiss") - E, l = singular_bareiss(self.T) + E, ln = singular_bareiss(self.T) m = len(E) n = len(E[0]) @@ -277,33 +276,33 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): self.set_unsafe(r, c, R._zero_element) from sage.rings.integer_ring import ZZ - l = [ZZ(e-1) for e in l] + ln = [ZZ(e-1) for e in ln] - self.cache('in_echelon_form_bareiss',True) + self.cache('in_echelon_form_bareiss', True) self.cache('rank', len(E)) self.cache('pivots', tuple(range(len(E)))) - self.cache('swapped_columns', tuple(l)) + self.cache('swapped_columns', tuple(ln)) elif can_convert_to_singular(self.base_ring()): self.check_mutability() self.clear_cache() - E,l = self.T._singular_().bareiss()._sage_(self.base_ring()) + E, ln = self.T._singular_().bareiss()._sage_(self.base_ring()) # clear matrix for r from 0 <= r < self._nrows: for c from 0 <= c < self._ncols: - self.set_unsafe(r,c,R._zero_element) + self.set_unsafe(r, c, R._zero_element) for r from 0 <= r < E.nrows(): for c from 0 <= c < E.ncols(): - self.set_unsafe(c,r, E[r,c]) + self.set_unsafe(c, r, E[r, c]) - self.cache('in_echelon_form_bareiss',True) + self.cache('in_echelon_form_bareiss', True) self.cache('rank', E.nrows()) self.cache('pivots', tuple(range(E.nrows()))) - self.cache('swapped_columns', l) + self.cache('swapped_columns', ln) else: @@ -387,14 +386,14 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): if x is not None: return # already known to be in echelon form - nr,nc = self.nrows(),self.ncols() + nr, nc = self.nrows(), self.ncols() F = self.base_ring().base_ring() - cdef Matrix d = matrix(F,nr,nc) + cdef Matrix d = matrix(F, nr, nc) start_row = 0 for r from 0 <= r < nr: for c from 0 <= c < nc: - p = self.get_unsafe(r,c) + p = self.get_unsafe(r, c) if p.is_constant(): d.set_unsafe(r, c, p.constant_coefficient()) @@ -404,25 +403,25 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): if d.get_unsafe(rc, c): r = rc break - if r!=-1: - a_inverse = ~self.get_unsafe(r,c) - self.rescale_row_c(r, a_inverse , c) + if r != -1: + a_inverse = ~self.get_unsafe(r, c) + self.rescale_row_c(r, a_inverse, c) self.swap_rows_c(r, start_row) for i from 0 <= i < nr: if i != start_row: - minus_b = -self.get_unsafe(i,c) + minus_b = -self.get_unsafe(i, c) self.add_multiple_of_row(i, start_row, minus_b, 0) - start_row +=1 + start_row += 1 d = d._parent(0) for i from start_row <= i < nr: for j from c+1 <= j < nc: - if self.get_unsafe(i,j).is_constant(): - d.set_unsafe(i,j, self.get_unsafe(i,j).constant_coefficient()) + if self.get_unsafe(i, j).is_constant(): + d.set_unsafe(i, j, self.get_unsafe(i, j).constant_coefficient()) - self.cache('in_echelon_form_row_reduction',True) + self.cache('in_echelon_form_row_reduction', True) def swapped_columns(self): """ @@ -556,24 +555,3 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): self.cache('det', d) return d - - def laurent_matrix_reduction(self): - R = self._base_ring - n_rows, n_cols = self.dimensions() - mat_l = identity_matrix(R, n_rows) - mat_r = identity_matrix(R, n_cols) - if not isinstance(R, LaurentPolynomialRing_generic): - return mat_l, self, mat_r - res = self - for j, rw in enumerate(self.rows()): - for t in R.gens(): - n = min(mon.degree(t) for a in rw for cf, mon in a) - res.rescale_row(j, t ** -n) - mat_l.rescale_col(j, t ** n) - for j, cl in enumerate(self.columns()): - for t in R.gens(): - n = min(mon.degree(t) for a in cl for cf, mon in a) - res.rescale_col(j, t ** -n) - mat_r.rescale_row(j, t ** n) - res = res.change_ring(R.polynomial_ring()) - return mat_l, res, mat_r diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index b134b63ac5e..917943f5619 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -592,11 +592,11 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): elif e == 0: var = "" else: - var = "*{}^{}".format(X,e) - s += "{}{}".format(x,var) + var = "*{}^{}".format(X, e) + s += "{}{}".format(x, var) first = False s = s.replace(" + -", " - ") - s = s.replace(" 1*"," ") + s = s.replace(" 1*", " ") s = s.replace(" -1*", " -") return s[1:] @@ -701,7 +701,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): # degrees cdef long result = 0 cdef long result_mon - cdef int i,j + cdef int i, j cdef long var_hash_name = hash(self.__u._parent._names[0]) for i in range(self.__u.degree()+1): result_mon = hash(self.__u[i]) @@ -913,11 +913,11 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): j = i - self.__n if j >= 0: self.__u._unsafe_mutate(j, value) - else: # off to the left + else: # off to the left if value != 0: self.__n = self.__n + j R = self._parent.base_ring() - coeffs = [value] + [R.zero() for _ in range(1,-j)] + self.__u.list() + coeffs = [value] + [R.zero() for _ in range(1, -j)] + self.__u.list() self.__u = self.__u._parent(coeffs) self._normalize() @@ -1282,7 +1282,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): Fraction Field of Univariate Polynomial Ring in t over Rational Field """ cdef LaurentPolynomial_univariate ret - if self.__u.is_constant(): # this has a single term c*x^n + if self.__u.is_constant(): # this has a single term c*x^n ret = self._new_c() if self.__u.is_unit(): ret.__u = self.__u.inverse_of_unit() @@ -1599,7 +1599,6 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): """ return self.__n == 0 and self.__u.is_constant() - def is_square(self, root=False): r""" Return whether this Laurent polynomial is a square. @@ -1846,10 +1845,10 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): cdef list a = self.__u.list(copy=False) if n < 0: - v = [a[i]/(n+i+1) for i in range(min(-1-n,len(a)))] + [0] + v = [a[i] / (n + i + 1) for i in range(min(-1 - n, len(a)))] + [0] else: v = [] - v += [a[i]/(n+i+1) for i in range(max(-n,0), len(a))] + v += [a[i] / (n + i + 1) for i in range(max(-n, 0), len(a))] try: u = self._parent._R(v) except TypeError: @@ -1888,7 +1887,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): """ if kwds: f = self.subs(**kwds) - if x: # If there are non-keyword arguments + if x: # If there are non-keyword arguments return f(*x) else: return f @@ -1972,6 +1971,43 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): @coerce_binop def divides(self, other): + r""" + Return ``True`` if ``self`` divides ``other``. + + This method is only implemented for Laurent polynomials over an integral domain. + + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(ZZ) + sage: (2*x**-1 + 1).divides(4*x**-2 - 1) + True + sage: (2*x + 1).divides(4*x**2 + 1) + False + sage: (2*x + x**-1).divides(R(0)) + True + sage: R(0).divides(2*x ** -1 + 1) + False + sage: R(0).divides(R(0)) + True + sage: R. = LaurentPolynomialRing(Zmod(6)) + sage: p = 4*x + 3*x^-1 + sage: q = 5*x^2 + x + 2*x^-2 + sage: p.divides(q) + Traceback (most recent call last): + ... + NotImplementedError: divisibility test only implemented for Laurent polynomials over an integral domain + + + sage: R. = GF(2)[] + sage: S. = LaurentPolynomialRing(R) + sage: p = (x+y+1) * z**-1 + x*y + sage: q = (y^2-x^2) * z**-2 + z + x-y + sage: p.divides(q), p.divides(p*q) # needs sage.libs.singular + (False, True) + """ + if not self.base_ring().is_integral_domain(): + raise NotImplementedError("divisibility test only implemented for Laurent polynomials over an integral domain") + R = self.parent().polynomial_ring() p = R(self.polynomial_construction()[0]) q = R(other.polynomial_construction()[0]) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index b9ead02ea3e..fbfa99fd8ac 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -26,7 +26,8 @@ from sage.structure.richcmp import op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE from sage.arith.misc import GCD -class LaurentPolynomialIdeal( Ideal_generic ): + +class LaurentPolynomialIdeal(Ideal_generic): def __init__(self, ring, gens, coerce=True, hint=None): r""" Create an ideal in a Laurent polynomial ring. @@ -92,7 +93,7 @@ def __init__(self, ring, gens, coerce=True, hint=None): """ Ideal_generic.__init__(self, ring, gens, coerce=coerce) self._poly_ring = ring.polynomial_ring() - self._poly_ideal = None # Create only as needed + self._poly_ideal = None # Create only as needed self._saturated = False if hint is None: self._hint = self._poly_ring.zero_ideal() @@ -167,11 +168,11 @@ def _richcmp_(self, right_r, op): True """ if op in (op_EQ, op_NE): - if set(self.gens()) == set(right_r.gens()): # Early abort + if set(self.gens()) == set(right_r.gens()): # Early abort return (op == op_EQ) return ((self.polynomial_ideal() == right_r.polynomial_ideal()) == (op == op_EQ)) elif op == op_LE: - if all(f in right_r.gens() for f in self.gens()): # Early abort + if all(f in right_r.gens() for f in self.gens()): # Early abort return True return self.polynomial_ideal(saturate=False) <= right_r.polynomial_ideal() elif op == op_GE: @@ -298,10 +299,10 @@ def apply_coeff_map(self, f, new_base_ring=None, forward_hint=True): else: R = ring.change_ring(new_base_ring) if forward_hint: - apply_to_hint = lambda x,f=f: x.map_coefficients(f) + apply_to_hint = lambda x, f=f: x.map_coefficients(f) else: apply_to_hint = None - return self.apply_map(lambda x,f=f: + return self.apply_map(lambda x, f=f: x.map_coefficients(f, new_base_ring=new_base_ring), new_ring=R, apply_to_hint=apply_to_hint) @@ -443,8 +444,8 @@ def groebner_basis(self, saturate=True): sage: (I + J).groebner_basis() (x - 1, y + 1) """ - l = self.polynomial_ideal(saturate=saturate).groebner_basis() - return tuple(self.ring()(x) for x in l) + gb = self.polynomial_ideal(saturate=saturate).groebner_basis() + return tuple(self.ring()(x) for x in gb) def is_one(self): """ @@ -476,10 +477,10 @@ def is_binomial(self, groebner_basis=False): True """ if groebner_basis: - l = self.groebner_basis() + gb = self.groebner_basis() else: - l = self.gens() - return all(not f or f.number_of_terms() == 2 for f in l) + gb = self.gens() + return all(not f or f.number_of_terms() == 2 for f in gb) def associated_primes(self): """ @@ -499,9 +500,9 @@ def associated_primes(self): Ideal (z^2 - y, y*z + 2, y^2 + 2*z) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field) """ - l = self.polynomial_ideal(saturate=False).associated_primes() - l2 = [self.ring().ideal(I.gens(), hint=I) for I in l] - return tuple(I for I in l2 if not I.is_one()) + ap = self.polynomial_ideal(saturate=False).associated_primes() + ap2 = [self.ring().ideal(id.gens(), hint=id) for Iid in ap] + return tuple(id for id in ap2 if not id.is_one()) def minimal_associated_primes(self, saturate=False): """ @@ -521,9 +522,9 @@ def minimal_associated_primes(self, saturate=False): Ideal (z^3 + 2, -z^2 + y) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field) """ - l = self.polynomial_ideal(saturate=saturate).minimal_associated_primes() - l2 = [self.ring().ideal(I.gens(), hint=I) for I in l] - return tuple(I for I in l2 if not I.is_one()) + ap = self.polynomial_ideal(saturate=saturate).minimal_associated_primes() + ap2 = [self.ring().ideal(id.gens(), hint=id) for id in ap] + return tuple(id for id in ap2 if not id.is_one()) def radical(self): """ diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index fe199d281e3..efab709fd44 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1241,19 +1241,19 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): else: return f - cdef int l = len(x) + cdef int ln = len(x) - if l == 1 and isinstance(x[0], (tuple, list)): + if ln == 1 and isinstance(x[0], (tuple, list)): x = x[0] - l = len(x) + ln = len(x) - if l != self._parent.ngens(): + if ln != self._parent.ngens(): raise TypeError("number of arguments does not match the number" " of generators in parent") # Check to make sure that we aren't dividing by zero cdef Py_ssize_t m - for m in range(l): + for m in range(ln): if x[m] == 0: if self.has_inverse_of(m): raise ZeroDivisionError diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index 22d97975cd6..38f9f7a8ebb 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -327,8 +327,8 @@ def extract(T, indices): if not all(r == 0 for r in extract(K, remaining)): raise SplitDictError('split not possible') G = extract(K, group_by) - I = extract(K, indices) - result.setdefault(G, dict()).update({I: V}) + In = extract(K, indices) + result.setdefault(G, dict()).update({In: V}) if not group_by: return result.popitem()[1] else: @@ -755,7 +755,7 @@ def _element_constructor_(self, x, mon=None): P = parent(x) if P is self.polynomial_ring(): from sage.rings.polynomial.polydict import ETuple - return self.element_class( self, x, mon=ETuple({}, int(self.ngens())) ) + return self.element_class(self, x, mon=ETuple({}, int(self.ngens()))) elif isinstance(x, Expression): return x.laurent_polynomial(ring=self) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py index c10cbb219b0..95ea676e0d3 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py @@ -278,8 +278,7 @@ def _coerce_map_from_(self, R): f = self._coerce_map_via([self._R], R) if f is not None: return f - if (isinstance(R, LaurentPolynomialRing_generic) - and self._R.has_coerce_map_from(R._R)): + if isinstance(R, LaurentPolynomialRing_generic) and self._R.has_coerce_map_from(R._R): return self._generic_coerce_map(R) def __eq__(self, right): @@ -480,7 +479,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:: diff --git a/src/sage/rings/polynomial/laurent_reduction.py b/src/sage/rings/polynomial/laurent_reduction.py new file mode 100644 index 00000000000..c26b667b492 --- /dev/null +++ b/src/sage/rings/polynomial/laurent_reduction.py @@ -0,0 +1,50 @@ +from sage.matrix.constructor import identity_matrix +from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic + + +def laurent_matrix_reduction(A): + """ + From a matrix `A` of Laurent polynomials, apply elementary operations + to obtain a matrix `P` of polynomials such that the variables do not divide + no column and no row. + + OUTPUT: Three matrices `L`, `P`, `R` such that `A = L P R`, where `L` and + `R` are diagonal with monomial entries. + + EXAMPLES: + + sage: from sage.rings.polynomial.laurent_reduction import laurent_matrix_reduction + sage: R. = LaurentPolynomialRing(QQ) + sage: L = [1/3*x^-1*y - 6*x^-2*y^2 - 1/2*x^-2*y, 1/5*x + 1/2*y + 1/6] + sage: L += [1/2 - 5*x^-1*y - 2*x^-1, -1/3*y^-2 - 4*x^-1*y^-1 + 11*x^-1*y^-2] + sage: A = matrix(R, 2, L) + sage: lf, P, rg = laurent_matrix_reduction(A) + sage: lf + [ x^-2 0] + [ 0 x^-1*y^-2] + sage: P + [ 1/3*x - 6*y - 1/2 1/5*x^3 + 1/2*x^2*y + 1/6*x^2] + [ 1/2*x*y - 5*y^2 - 2*y -1/3*x - 4*y + 11] + sage: rg + [y 0] + [0 1] + """ + R = A.base_ring() + n_rows, n_cols = A.dimensions() + mat_l = identity_matrix(R, n_rows) + mat_r = identity_matrix(R, n_cols) + if not isinstance(R, LaurentPolynomialRing_generic): + return mat_l, A, mat_r + res = A + for j, rw in enumerate(A.rows()): + for t in R.gens(): + n = min(mon.degree(t) for a in rw for cf, mon in a) + res.rescale_row(j, t ** -n) + mat_l.rescale_col(j, t ** n) + for j, cl in enumerate(A.columns()): + for t in R.gens(): + n = min(mon.degree(t) for a in cl for cf, mon in a) + res.rescale_col(j, t ** -n) + mat_r.rescale_row(j, t ** n) + res = res.change_ring(R.polynomial_ring()) + return mat_l, res, mat_r diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index c5a1129aecf..06b5ab0eb43 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -213,7 +213,7 @@ cdef class Polynomial(CommutativePolynomial): .. automethod:: _mul_trunc_ """ - def __init__(self, parent, is_gen = False, construct=False): + def __init__(self, parent, is_gen=False, construct=False): """ The following examples illustrate creation of elements of polynomial rings, and some basic arithmetic. @@ -357,7 +357,7 @@ cdef class Polynomial(CommutativePolynomial): from sage.plot.all import plot, point if R.characteristic() == 0: if xmin is None and xmax is None: - (xmin, xmax) = (-1,1) + (xmin, xmax) = (-1, 1) elif xmin is None or xmax is None: raise AttributeError("must give both plot endpoints") return plot(self.__call__, (xmin, xmax), *args, **kwds) @@ -365,10 +365,10 @@ cdef class Polynomial(CommutativePolynomial): if R.is_finite(): v = list(R) v.sort() - w = dict([(v[i],i) for i in range(len(v))]) + w = dict([(v[i], i) for i in range(len(v))]) z = [(i, w[self(v[i])]) for i in range(len(v))] return point(z, *args, **kwds) - raise NotImplementedError("plotting of polynomials over %s not implemented"%R) + raise NotImplementedError("plotting of polynomials over %s not implemented" % R) cpdef _lmul_(self, Element left): """ @@ -832,7 +832,7 @@ cdef class Polynomial(CommutativePolynomial): # is more permissive about its arguments than we are. top = top(*args, **kwds) except TypeError: - if args: # bwd compat: nonsense *keyword* arguments are okay + if args: # bwd compat: nonsense *keyword* arguments are okay raise TypeError("Wrong number of arguments") else: eval_coeffs = True @@ -912,7 +912,7 @@ cdef class Polynomial(CommutativePolynomial): d = pol.degree() if d <= 0 or (isinstance(a, Element) and R.is_exact() and a.is_zero()): - return cst # with the right parent thanks to the above coercion + return cst # with the right parent thanks to the above coercion elif pol._parent is R and a.is_gen(): return pol elif hasattr(a, "_evaluate_polynomial"): @@ -1078,18 +1078,18 @@ cdef class Polynomial(CommutativePolynomial): cdef Py_ssize_t d2 = pol.degree() # Special case constant polynomials - if d1 == -1: # self is the 0 polynomial + if d1 == -1: # self is the 0 polynomial if d2 == -1: - return rich_to_bool(op, 0) # both polynomials are 0 + return rich_to_bool(op, 0) # both polynomials are 0 elif d2 == 0: return richcmp(self._parent._base.zero(), pol.get_unsafe(0), op) - return rich_to_bool_sgn(op, -1) # we have d2 > 0 - elif d1 == 0: # self is a nonzero constant + return rich_to_bool_sgn(op, -1) # we have d2 > 0 + elif d1 == 0: # self is a nonzero constant if d2 == -1: return richcmp(self.get_unsafe(0), pol._parent._base.zero(), op) elif d2 == 0: return richcmp(self.get_unsafe(0), pol.get_unsafe(0), op) - return rich_to_bool_sgn(op, -1) # we have d2 > d1 == 0 + return rich_to_bool_sgn(op, -1) # we have d2 > d1 == 0 # For different degrees, compare the degree if d1 != d2: @@ -1272,12 +1272,12 @@ cdef class Polynomial(CommutativePolynomial): TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' """ - cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap + cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap cdef long result_mon cdef long c_hash cdef long var_name_hash cdef int i - for i from 0<= i <= self.degree(): + for i from 0 <= i <= self.degree(): if i == 1: # we delay the hashing until now to not waste it on a constant poly var_name_hash = hash(self._parent._names[0]) @@ -1331,7 +1331,7 @@ cdef class Polynomial(CommutativePolynomial): a = im_gens[0] d = self.degree() if d == -1: - return codomain.zero() # Special case: 0 should always coerce to 0 + return codomain.zero() # Special case: 0 should always coerce to 0 if base_map is None: base_map = codomain.coerce_map_from(self.base_ring()) result = base_map(self.get_unsafe(d)) @@ -1661,9 +1661,9 @@ cdef class Polynomial(CommutativePolynomial): for i in range(n+1): for j in range(n-1): M[i+j, j+n] = m[i] - v = vector(R, [R.one()] + [R.zero()]*(2*n-2)) # the constant polynomial 1 + v = vector(R, [R.one()] + [R.zero()]*(2*n-2)) # the constant polynomial 1 if M.is_invertible(): - x = M.solve_right(v) # there has to be a better way to solve + x = M.solve_right(v) # there has to be a better way to solve return a.parent()(list(x)[0:n]) else: raise ValueError("Impossible inverse modulo") @@ -1846,7 +1846,7 @@ cdef class Polynomial(CommutativePolynomial): This is the default implementation that does the multiplication and then truncate! There are custom implementations in several subclasses: - - :meth:`on dense polynomial over integers (via FLINT) ` + - :meth:`on dense polynomial over integers (via FLINT) ` - :meth:`on dense polynomial over Z/nZ (via FLINT) ` @@ -1961,7 +1961,7 @@ cdef class Polynomial(CommutativePolynomial): """ if self.degree() < 0: raise ValueError("square-free decomposition not defined for zero polynomial") - if hasattr(self.base_ring(),'_squarefree_decomposition_univariate_polynomial'): + if hasattr(self.base_ring(), '_squarefree_decomposition_univariate_polynomial'): return self.base_ring()._squarefree_decomposition_univariate_polynomial(self) raise NotImplementedError("square-free decomposition not implemented for this polynomial") @@ -2188,11 +2188,11 @@ cdef class Polynomial(CommutativePolynomial): raise ValueError("ring must be an extension of the base ring") if not (ring.is_field() and ring.is_finite()): raise NotImplementedError - allowed_deg_mult = Integer(ring.factored_order()[0][1]) # generally it will be the quotient of this by the degree of the base ring. + allowed_deg_mult = Integer(ring.factored_order()[0][1]) # generally it will be the quotient of this by the degree of the base ring. if degree is None: x = self._parent.gen() if allowed_deg_mult == 1: - xq = pow(x,q,self) + xq = pow(x, q, self) self = self.gcd(xq-x) degree = -1 if self.degree() == 0: @@ -2210,7 +2210,7 @@ cdef class Polynomial(CommutativePolynomial): break while d < allowed_deg_mult: d = d+1 - xq = pow(xq,q,self) + xq = pow(xq, q, self) if d.divides(allowed_deg_mult): break A = self.gcd(xq-x) @@ -2234,8 +2234,8 @@ cdef class Polynomial(CommutativePolynomial): break while True: # we waste a little effort here in computing the xq again. - d = d+1 - xq = pow(xq,q,self) + d = d + 1 + xq = pow(xq, q, self) if allowed_deg_mult.divides(d): break A = self.gcd(xq-x) @@ -2257,7 +2257,7 @@ cdef class Polynomial(CommutativePolynomial): raise ValueError("no roots D %s" % self) break d = d+1 - xq = pow(xq,q,self) + xq = pow(xq, q, self) if d == degree: break A = self.gcd(xq-x) @@ -2273,13 +2273,13 @@ cdef class Polynomial(CommutativePolynomial): if degree == 1: ring = self.base_ring() else: - ring = self.base_ring().extension(degree) # this won't work yet. + ring = self.base_ring().extension(degree) # this won't work yet. # now self has only roots of degree ``degree``. # for now, we only implement the Cantor-Zassenhaus split k = self.degree() // degree if k == 1: try: - return self.roots(ring, multiplicities=False)[0] # is there something better to do here? + return self.roots(ring, multiplicities=False)[0] # is there something better to do here? except IndexError: raise ValueError("no roots F %s" % self) if q % 2 == 0: @@ -2289,8 +2289,8 @@ cdef class Polynomial(CommutativePolynomial): continue T = T.monic() C = T - for i in range(degree-1): - C = T + pow(C,q,self) + for i in range(degree - 1): + C = T + pow(C, q, self) h = self.gcd(C) hd = h.degree() if hd != 0 and hd != self.degree(): @@ -2536,7 +2536,7 @@ cdef class Polynomial(CommutativePolynomial): else: v = [R.zero()]*right + [R.one()] return self.parent()(v, check=False) - if right > 20: # no gain below + if right > 20: # no gain below try: p = self.parent().characteristic() except (AttributeError, NotImplementedError): @@ -2557,7 +2557,7 @@ cdef class Polynomial(CommutativePolynomial): q, r = q.quo_rem(p) if r != 0: if sparse: - tmp = self.parent()({e*k : d[k]**e for k in d}) + tmp = self.parent()({e * k: d[k] ** e for k in d}) else: tmp = [0] * (e * len(c) - e + 1) for i in range(len(c)): @@ -2728,19 +2728,19 @@ cdef class Polynomial(CommutativePolynomial): if y.find("-") == 0: y = y[1:] if not atomic_repr and n > 0 and (y.find("+") != -1 or y.find("-") != -1): - x = "(%s)"%x + x = "(%s)" % x if n > 1: - var = "*%s^%s"%(name,n) - elif n==1: - var = "*%s"%name + var = "*%s^%s" % (name, n) + elif n == 1: + var = "*%s" % name else: var = "" sbuf.write(x) sbuf.write(var) s = sbuf.getvalue() s = s.replace(" + -", " - ") - s = re.sub(r' 1(\.0+)?\*',' ', s) - s = re.sub(r' -1(\.0+)?\*',' -', s) + s = re.sub(r' 1(\.0+)?\*', ' ', s) + s = re.sub(r' -1(\.0+)?\*', ' -', s) if s == " ": return "0" return s[1:] @@ -2813,7 +2813,7 @@ cdef class Polynomial(CommutativePolynomial): x = "\\left(%s\\right)" % x if n > 1: var = "|%s^{%s}" % (name, n) - elif n==1: + elif n == 1: var = "|%s" % name else: var = "" @@ -3150,12 +3150,12 @@ cdef class Polynomial(CommutativePolynomial): - Didier Deshommes (2006-05-25) """ - return self._parent(polynomial_fateman._mul_fateman_mul(self,right)) + return self._parent(polynomial_fateman._mul_fateman_mul(self, right)) @cython.boundscheck(False) @cython.wraparound(False) @cython.overflowcheck(False) - def _mul_karatsuba(self, right, K_threshold = None): + def _mul_karatsuba(self, right, K_threshold=None): r""" Compute the product of two polynomials using the Karatsuba divide and conquer multiplication algorithm. This is only used over a @@ -3328,8 +3328,8 @@ cdef class Polynomial(CommutativePolynomial): if n <= K_threshold or m <= K_threshold: return self._new_generic(do_schoolbook_product(f, g, -1)) if n == m: - return self._new_generic(do_karatsuba(f,g, K_threshold, 0, 0, n)) - return self._new_generic(do_karatsuba_different_size(f,g, K_threshold)) + return self._new_generic(do_karatsuba(f, g, K_threshold, 0, 0, n)) + return self._new_generic(do_karatsuba_different_size(f, g, K_threshold)) @cython.boundscheck(False) @cython.wraparound(False) @@ -3487,7 +3487,7 @@ cdef class Polynomial(CommutativePolynomial): if var not in variables: x = base_ring(self) if base_ring else self const_ix = ETuple((0,)*len(variables)) - return { const_ix: x } + return {const_ix: x} cdef tuple prev_variables = variables[:variables.index(var)] const_ix = ETuple((0,)*len(prev_variables)) @@ -3509,7 +3509,7 @@ cdef class Polynomial(CommutativePolynomial): cdef dict D = {} cdef tuple leftovers = (0,) * (len(variables) - len(prev_variables) - 1) for k in range(len(mpolys)): - for i,a in mpolys[k].iteritems(): + for i, a in mpolys[k].iteritems(): j = ETuple((k,) + leftovers) D[i + j] = a @@ -3680,7 +3680,7 @@ cdef class Polynomial(CommutativePolynomial): for y in x: d = d.lcm(y.denominator()) return d - except(AttributeError): + except (AttributeError): return self.base_ring().one() def numerator(self): @@ -3951,7 +3951,7 @@ cdef class Polynomial(CommutativePolynomial): """ return [self.diff()] - def integral(self,var=None): + def integral(self, var=None): """ Return the integral of this polynomial. @@ -4571,39 +4571,39 @@ cdef class Polynomial(CommutativePolynomial): # PARI for smaller degree over other rings besides Z, and use # NTL in general. # A remark from Bill Hart (2007-09-25) about the above observation: - ## NTL uses the Berlekamp-Zassenhaus method with van Hoeij's improvements. - ## But so does Magma since about Jul 2001. - ## - ## But here's the kicker. PARI also uses this algorithm. Even Maple uses - ## it! - ## - ## NTL's LLL algorithms are extremely well developed (van Hoeij uses - ## LLL). There is also a possible speed difference in whether one uses - ## quadratic convergence or not in the Hensel lift. But the right choice - ## is not always what one thinks. - ## - ## But more than likely NTL is just better for large problems because - ## Victor Shoup was very careful with the choice of strategies and - ## parameters he used. Paul Zimmerman supplied him with a pile of - ## polynomials to factor for comparison purposes and these seem to have - ## been used to tune the algorithm for a wide range of inputs, including - ## cases that van Hoeij's algorithm doesn't usually like. - ## - ## If you have a bound on the coefficients of the factors, one can surely - ## do better than a generic implementation, but probably not much better - ## if there are many factors. - ## - - ## HUGE TODO, refactor the code below here such that this method will - ## have as only the following code - ## - ## R = self.parent().base_ring() - ## return R._factor_univariate_polynomial(self) - ## - ## in this way we can move the specific logic of factoring to the - ## self.parent().base_ring() and get rid of all the ugly - ## is_SomeType(R) checks and get way nicer structured code - ## 200 lines of spaghetti code is just way to much! + # # NTL uses the Berlekamp-Zassenhaus method with van Hoeij's improvements. + # # But so does Magma since about Jul 2001. + # # + # # But here's the kicker. PARI also uses this algorithm. Even Maple uses + # # it! + # # + # # NTL's LLL algorithms are extremely well developed (van Hoeij uses + # # LLL). There is also a possible speed difference in whether one uses + # # quadratic convergence or not in the Hensel lift. But the right choice + # # is not always what one thinks. + # # + # # But more than likely NTL is just better for large problems because + # # Victor Shoup was very careful with the choice of strategies and + # # parameters he used. Paul Zimmerman supplied him with a pile of + # # polynomials to factor for comparison purposes and these seem to have + # # been used to tune the algorithm for a wide range of inputs, including + # # cases that van Hoeij's algorithm doesn't usually like. + # # + # # If you have a bound on the coefficients of the factors, one can surely + # # do better than a generic implementation, but probably not much better + # # if there are many factors. + # # + + # # HUGE TODO, refactor the code below here such that this method will + # # have as only the following code + # # + # # R = self.parent().base_ring() + # # return R._factor_univariate_polynomial(self) + # # + # # in this way we can move the specific logic of factoring to the + # # self.parent().base_ring() and get rid of all the ugly + # # is_SomeType(R) checks and get way nicer structured code + # # 200 lines of spaghetti code is just way to much! if self.degree() < 0: raise ArithmeticError("factorization of {!r} is not defined".format(self)) @@ -4617,7 +4617,7 @@ cdef class Polynomial(CommutativePolynomial): try: F = flatten(self).factor(**kwargs) unflatten = flatten.section() - return Factorization(((unflatten(f),m) for (f,m) in F), unit = F.unit()) + return Factorization(((unflatten(f), m) for (f, m) in F), unit=F.unit()) except NotImplementedError: pass @@ -4650,7 +4650,7 @@ cdef class Polynomial(CommutativePolynomial): # This was copied from the general multivariate implementation try: if R.is_finite(): - if R.characteristic() > 1<<29: + if R.characteristic() > 1 << 29: raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") P = self._parent @@ -4658,8 +4658,8 @@ cdef class Polynomial(CommutativePolynomial): S = self._singular_().factorize() factors = S[1] exponents = S[2] - v = sorted([( P(factors[i+1]), - sage.rings.integer.Integer(exponents[i+1])) + v = sorted([(P(factors[i + 1]), + sage.rings.integer.Integer(exponents[i + 1])) for i in range(len(factors))]) unit = P.one() for i in range(len(v)): @@ -4936,7 +4936,7 @@ cdef class Polynomial(CommutativePolynomial): raise NotImplementedError("splitting_field() is only implemented over number fields and finite fields") - def pseudo_quo_rem(self,other): + def pseudo_quo_rem(self, other): r""" Compute the pseudo-division of two polynomials. @@ -4996,7 +4996,7 @@ cdef class Polynomial(CommutativePolynomial): e -= 1 q = d**e - return (q*Q,q*R) + return (q * Q, q * R) @coerce_binop def gcd(self, other): @@ -5089,7 +5089,7 @@ cdef class Polynomial(CommutativePolynomial): try: doit = self._parent._base._gcd_univariate_polynomial except AttributeError: - raise NotImplementedError("%s does not provide a gcd implementation for univariate polynomials"%self._parent._base) + raise NotImplementedError("%s does not provide a gcd implementation for univariate polynomials" % self._parent._base) else: return doit(self, other) @@ -5462,7 +5462,7 @@ cdef class Polynomial(CommutativePolynomial): return R.fraction_field()[self._parent.variable_name()].quotient(self, names) - def sylvester_matrix(self, right, variable = None): + def sylvester_matrix(self, right, variable=None): """ Return the Sylvester matrix of ``self`` and ``right``. @@ -5588,10 +5588,10 @@ cdef class Polynomial(CommutativePolynomial): # sylvester_matrix() in multi_polynomial.pyx. if self._parent != right.parent(): - a, b = coercion_model.canonical_coercion(self,right) + a, b = coercion_model.canonical_coercion(self, right) variable = a.parent()(self.variables()[0]) - #We add the variable to cover the case that right is a multivariate - #polynomial + # We add the variable to cover the case that right is a multivariate + # polynomial return a.sylvester_matrix(b, variable) if variable: @@ -6446,13 +6446,18 @@ cdef class Polynomial(CommutativePolynomial): e = self.exponents() c = self.coefficients() - if len(e) == 0: return [] + if len(e) == 0: + return [] if len(e) == 1: - if e[0] == 0: return [] - else: return [(infinity.infinity, e[0])] + if e[0] == 0: + return [] + else: + return [(infinity.infinity, e[0])] - if e[0] == 0: slopes = [] - else: slopes = [(infinity.infinity, e[0])] + if e[0] == 0: + slopes = [] + else: + slopes = [(infinity.infinity, e[0])] points = [(e[0], c[0].valuation(p)), (e[1], c[1].valuation(p))] slopes.append((-(c[1].valuation(p)-c[0].valuation(p))/(e[1] - e[0]), e[1]-e[0])) @@ -6463,8 +6468,8 @@ cdef class Polynomial(CommutativePolynomial): slopes = slopes[:-1] points = points[:-1] s = -(v-points[-1][1])/(e[i]-points[-1][0]) - slopes.append((s,e[i]-points[-1][0])) - points.append((e[i],v)) + slopes.append((s, e[i] - points[-1][0])) + points.append((e[i], v)) return slopes @@ -6508,7 +6513,7 @@ cdef class Polynomial(CommutativePolynomial): if m != n or p[n] != q[n]: continue alpha = (q[n-1] - p[n-1])/(n*p[n]) - if alpha.is_integer(): # ZZ() might work for non-integers... + if alpha.is_integer(): # ZZ() might work for non-integers... alpha = ZZ(alpha) else: continue @@ -7178,7 +7183,7 @@ cdef class Polynomial(CommutativePolynomial): if Sf is not QQ or (d1 <= N and d2 <= N): algorithm = "resultant" else: - c = d1*sum(bool(p1[i]) for i in range(d1 + 1))*\ + c = d1*sum(bool(p1[i]) for i in range(d1 + 1)) * \ d2*sum(bool(p2[i]) for i in range(d2 + 1)) if c <= N**4: algorithm = "resultant" @@ -7591,8 +7596,7 @@ cdef class Polynomial(CommutativePolynomial): return self # return 0 n = self.degree() base_ring = self._parent.base_ring() - if (is_MPolynomialRing(base_ring) or - is_PowerSeriesRing(base_ring)): + if (is_MPolynomialRing(base_ring) or is_PowerSeriesRing(base_ring)): # It is often cheaper to compute discriminant of simple # multivariate polynomial and substitute the real # coefficients into that result (see #16014). @@ -7601,13 +7605,13 @@ cdef class Polynomial(CommutativePolynomial): k = d.degree() r = n % 4 - u = -1 # (-1)**(n*(n-1)/2) + u = -1 # (-1)**(n*(n-1)/2) if r == 0 or r == 1: u = 1 try: an = self.get_coeff_c(n)**(n - k - 2) except ZeroDivisionError: - assert(n-k-2 == -1) + assert (n-k-2 == -1) # Rather than dividing the resultant by the leading coefficient, # we alter the Sylvester matrix (see #11782). mat = self.sylvester_matrix(d) @@ -7656,14 +7660,14 @@ cdef class Polynomial(CommutativePolynomial): if degree is not None: d = degree if d != degree: - raise ValueError("degree argument must be a non-negative integer, got %s"%(degree)) + raise ValueError("degree argument must be a non-negative integer, got %s" % (degree)) if len(v) < degree+1: v.reverse() v = [self.base_ring().zero()]*(degree+1-len(v)) + v elif len(v) > degree+1: v = v[:degree+1] v.reverse() - else: # len(v) == degree + 1 + else: # len(v) == degree + 1 v.reverse() else: v.reverse() @@ -8418,9 +8422,9 @@ cdef class Polynomial(CommutativePolynomial): sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField)) output_fp = isinstance(L, (sage.rings.abc.RealField, - sage.rings.abc.ComplexField, - sage.rings.abc.RealDoubleField, - sage.rings.abc.ComplexDoubleField)) + sage.rings.abc.ComplexField, + sage.rings.abc.RealDoubleField, + sage.rings.abc.ComplexDoubleField)) input_complex = isinstance(K, (sage.rings.abc.ComplexField, sage.rings.abc.ComplexDoubleField)) output_complex = isinstance(L, (sage.rings.abc.ComplexField, sage.rings.abc.ComplexDoubleField)) input_gaussian = (isinstance(K, sage.rings.abc.NumberField_quadratic) @@ -8503,20 +8507,20 @@ cdef class Polynomial(CommutativePolynomial): from sage.symbolic.constants import I coeffs = self.list() D = coeffs[1]*coeffs[1] - 4*coeffs[0]*coeffs[2] - l = None + l0 = None if D > 0: - l = [((-coeffs[1]-sqrt(D))/2/coeffs[2], 1), - ((-coeffs[1]+sqrt(D))/2/coeffs[2], 1)] + l0 = [((-coeffs[1] - sqrt(D)) / 2 / coeffs[2], 1), + ((-coeffs[1] + sqrt(D)) / 2 / coeffs[2], 1)] elif D < 0: - l = [((-coeffs[1]-I*sqrt(-D))/2/coeffs[2], 1), - ((-coeffs[1]+I*sqrt(-D))/2/coeffs[2], 1)] + l0 = [((-coeffs[1] - I * sqrt(-D)) / 2 / coeffs[2], 1), + ((-coeffs[1] + I * sqrt(-D)) / 2 / coeffs[2], 1)] elif D == 0: - l = [(-coeffs[1]/2/coeffs[2], 2)] - if l: + l0 = [(-coeffs[1] / 2 / coeffs[2], 2)] + if l0: if multiplicities: - return l + return l0 else: - return [val for val,m in l] + return [val for val, m in l0] from sage.symbolic.ring import SR vname = 'do_not_use_this_name_in_a_polynomial_coefficient' var = SR(vname) @@ -8534,7 +8538,7 @@ cdef class Polynomial(CommutativePolynomial): # and complex root isolation and for p-adic factorization if (is_IntegerRing(K) or is_RationalField(K) or isinstance(K, sage.rings.abc.AlgebraicRealField)) and \ - isinstance(L, (sage.rings.abc.AlgebraicRealField, sage.rings.abc.RealIntervalField)): + isinstance(L, (sage.rings.abc.AlgebraicRealField, sage.rings.abc.RealIntervalField)): from sage.rings.polynomial.real_roots import real_roots @@ -8564,7 +8568,7 @@ cdef class Polynomial(CommutativePolynomial): if (is_IntegerRing(K) or is_RationalField(K) or isinstance(K, sage.rings.abc.AlgebraicField_common) or input_gaussian) and \ - isinstance(L, (sage.rings.abc.ComplexIntervalField, sage.rings.abc.AlgebraicField_common)): + isinstance(L, (sage.rings.abc.ComplexIntervalField, sage.rings.abc.AlgebraicField_common)): from sage.rings.polynomial.complex_roots import complex_roots @@ -8682,7 +8686,7 @@ cdef class Polynomial(CommutativePolynomial): pass else: if multiplicities: - seq.append((rt,fac[1])) + seq.append((rt, fac[1])) else: seq.append(rt) return seq @@ -9088,7 +9092,7 @@ cdef class Polynomial(CommutativePolynomial): coeffs = [] m = Q.degree() // 2 for i in reversed(range(m + 1)): - coeffs.insert(0, Q[2*i]) # Note: degree of Q may be less than 2*i + coeffs.insert(0, Q[2*i]) # Note: degree of Q may be less than 2*i Q = (Q % (x**2 + q)**i) // x return S(coeffs), cofactor, q @@ -9294,7 +9298,7 @@ cdef class Polynomial(CommutativePolynomial): if hasattr(self.base_ring(), '_xgcd_univariate_polynomial'): return self.base_ring()._xgcd_univariate_polynomial(self, other) else: - raise NotImplementedError("%s does not provide an xgcd implementation for univariate polynomials"%self.base_ring()) + raise NotImplementedError("%s does not provide an xgcd implementation for univariate polynomials" % self.base_ring()) def rational_reconstruction(self, m, n_deg=None, d_deg=None): r""" @@ -9459,9 +9463,9 @@ cdef class Polynomial(CommutativePolynomial): sF = Pf(self) mF = Pf(m) n, d = sF.rational_reconstruction(mF, n_deg, d_deg) - l = lcm([n.denominator(), d.denominator()]) - n *= l - d *= l + lc = lcm([n.denominator(), d.denominator()]) + n *= lc + d *= lc return P(n), P(d) # n and d are unique if m.degree() > (n.degree() + d.degree()) @@ -9472,9 +9476,9 @@ cdef class Polynomial(CommutativePolynomial): if n_deg < 0 or d_deg < 0: raise ValueError("the degree bounds " - "n_deg and d_deg should be positive") + "n_deg and d_deg should be positive") - #XGCD until degree the degree of t1 surpasses the degree of n + # XGCD until degree the degree of t1 surpasses the degree of n s0 = P(0) t0 = P(1) s1 = P(m) @@ -9583,15 +9587,15 @@ cdef class Polynomial(CommutativePolynomial): _p = self._parent.coerce(p) elif p is infinity.infinity: return -self.degree() - elif is_Ideal(p) and p.ring() is self._parent: # eventually need to handle fractional ideals in the fraction field - if self._parent.base_ring().is_field(): # common case + elif is_Ideal(p) and p.ring() is self._parent: # eventually need to handle fractional ideals in the fraction field + if self._parent.base_ring().is_field(): # common case _p = p.gen() else: raise NotImplementedError else: from sage.rings.fraction_field import is_FractionField if is_FractionField(p.parent()) and self._parent.has_coerce_map_from(p.parent().ring()): - _p = self._parent.coerce(p.parent().ring()(p)) # here we require that p be integral. + _p = self._parent.coerce(p.parent().ring()(p)) # here we require that p be integral. else: raise TypeError("The polynomial, p, must have the same parent as self.") @@ -10846,13 +10850,13 @@ cdef class Polynomial(CommutativePolynomial): elif n == 1 or self.is_zero() or self.is_one(): return self elif self.degree() % n: - raise ValueError("not a %s power"%Integer(n).ordinal_str()) - elif self.get_unsafe(0).is_zero(): # We know that self is not 0, so it must have degree >= 0 + raise ValueError("not a %s power" % Integer(n).ordinal_str()) + elif self.get_unsafe(0).is_zero(): # We know that self is not 0, so it must have degree >= 0 # p = x^k q # p^(1/n) = x^(k/n) q^(1/n) i = self.valuation() - if i%n: - raise ValueError("not a %s power"%Integer(n).ordinal_str()) + if i % n: + raise ValueError("not a %s power" % Integer(n).ordinal_str()) return (self >> i).nth_root(n) << (i // n) if self.get_unsafe(0).is_one(): @@ -10871,7 +10875,7 @@ cdef class Polynomial(CommutativePolynomial): if q**n == p: return S(q) else: - raise ValueError("not a %s power"%Integer(n).ordinal_str()) + raise ValueError("not a %s power" % Integer(n).ordinal_str()) def _nth_root_series(self, long n, long prec, start=None): r""" @@ -10964,12 +10968,12 @@ cdef class Polynomial(CommutativePolynomial): raise ValueError("n (={}) must be positive".format(m)) elif m.is_one() or self.is_zero() or self.is_one(): return self - elif self.get_unsafe(0).is_zero(): # we know that self is not zero, so the degree >= 0 + elif self.get_unsafe(0).is_zero(): # we know that self is not zero, so the degree >= 0 # p = x^i q # p^(1/m) = x^(i/m) q^(1/m) i = self.valuation() if i % m: - raise ValueError("not a %s power"%m.ordinal_str()) + raise ValueError("not a %s power" % m.ordinal_str()) return (self >> i)._nth_root_series(m, prec - i // m) << (i // m) else: c = R.characteristic() @@ -10981,7 +10985,7 @@ cdef class Polynomial(CommutativePolynomial): for i in range(self.degree()+1): if self.get_unsafe(i): if i % cc: - raise ValueError("not a %s power"%m.ordinal_str()) + raise ValueError("not a %s power" % m.ordinal_str()) ans[i//cc] = self.get_unsafe(i).nth_root(cc) p = self._parent(ans) m = m // cc @@ -11077,12 +11081,16 @@ cdef class Polynomial(CommutativePolynomial): if not self.base_ring().is_integral_domain(): raise NotImplementedError("divisibility test only implemented for polynomials over an integral domain") - if p.is_zero(): return True # everything divides 0 - if self.is_zero(): return False # 0 only divides 0 + if p.is_zero(): + return True # everything divides 0 + if self.is_zero(): + return False # 0 only divides 0 try: - if self.is_unit(): return True # units divide everything + if self.is_unit(): + return True # units divide everything except NotImplementedError: - if self.is_one(): return True # if is_unit is not implemented + if self.is_one(): + return True # if is_unit is not implemented if self.degree() > p.degree(): return False @@ -11134,10 +11142,9 @@ cdef class Polynomial(CommutativePolynomial): raise ValueError("either the dictionary or the specialization must be provided") else: from sage.rings.polynomial.flatten import SpecializationMorphism - phi = SpecializationMorphism(self._parent,D) + phi = SpecializationMorphism(self._parent, D) return phi(self) - def _log_series(self, long n): r""" Return the power series expansion of logarithm of this polynomial, @@ -11335,10 +11342,10 @@ cdef list do_schoolbook_product(list x, list y, Py_ssize_t deg): return y elif d1 == 0: c = x[0] - return [c*a for a in y[:deg]] # beware of noncommutative rings + return [c * a for a in y[:deg]] # beware of noncommutative rings elif d2 == 0: c = y[0] - return [a*c for a in x[:deg]] # beware of noncommutative rings + return [a * c for a in x[:deg]] # beware of noncommutative rings coeffs = [None]*deg for k in range(deg): start = 0 if k <= d2 else k-d2 # max(0, k-d2) @@ -11384,10 +11391,10 @@ cdef list do_karatsuba_different_size(list left, list right, Py_ssize_t K_thresh return [] if n == 1: c = left[0] - return [c*a for a in right] + return [c * a for a in right] if m == 1: c = right[0] - return [a*c for a in left] # beware of noncommutative rings + return [a * c for a in left] # beware of noncommutative rings if n <= K_threshold or m <= K_threshold: return do_schoolbook_product(left, right, -1) if n == m: @@ -11434,7 +11441,7 @@ cdef list do_karatsuba_different_size(list left, list right, Py_ssize_t K_thresh @cython.boundscheck(False) @cython.wraparound(False) @cython.overflowcheck(False) -cdef list do_karatsuba(list left, list right, Py_ssize_t K_threshold,Py_ssize_t start_l, Py_ssize_t start_r,Py_ssize_t num_elts): +cdef list do_karatsuba(list left, list right, Py_ssize_t K_threshold, Py_ssize_t start_l, Py_ssize_t start_r, Py_ssize_t num_elts): """ Core routine for Karatsuba multiplication. This function works for two polynomials of the same degree. @@ -11489,8 +11496,8 @@ cdef list do_karatsuba(list left, list right, Py_ssize_t K_threshold,Py_ssize_t d = right[start_r] c = right[start_r+1] return [b*d, a*d+b*c, a*c] - return do_schoolbook_product(left[start_l:start_l+num_elts], - right[start_r:start_r+num_elts], -1) + return do_schoolbook_product(left[start_l:start_l + num_elts], + right[start_r:start_r + num_elts], -1) if num_elts == 2: # beware of noncommutative rings b = left[start_l] @@ -11524,7 +11531,7 @@ cdef list do_karatsuba(list left, list right, Py_ssize_t K_threshold,Py_ssize_t bd[e+i] = bd[e+i] + tt1[i] bd.append(tt1[e-1]) for i from 0 <= i < lenac -e: - ac[i] = ac[i] + tt1[e+i] + ac[i] = ac[i] + tt1[e + i] return bd + ac @@ -11603,10 +11610,10 @@ cdef class Polynomial_generic_dense(Polynomial): check = 0 elif not isinstance(x, (list, tuple)): # We trust that the element constructors do not send x=0 -# if x: + # if x: x = [x] # constant polynomials -# else: -# x = [] # zero polynomial + # else: + # x = [] # zero polynomial if check: self._coeffs = [R(z, **kwds) for z in x] self._normalize() @@ -11639,9 +11646,9 @@ cdef class Polynomial_generic_dense(Polynomial): Univariate Polynomial Ring in x over Univariate Polynomial Ring in y over Rational Field """ if a: - return self._new_c([a],P) + return self._new_c([a], P) else: - return self._new_c([],P) + return self._new_c([], P) def __reduce__(self): """ @@ -11710,7 +11717,7 @@ cdef class Polynomial_generic_dense(Polynomial): for i in range(ell): v[i+d] = c * x[i] cdef Polynomial_generic_dense res = self._new_c(v, self._parent) - #if not v[len(v)-1]: + # if not v[len(v)-1]: # "normalize" checks this anyway... res._normalize() return res @@ -11853,7 +11860,7 @@ cdef class Polynomial_generic_dense(Polynomial): 2*y*x^3 + (y + 3)*x^2 + (-2*y + 1)*x + 1 """ cdef Polynomial_generic_dense res - cdef Py_ssize_t check=0, i, min + cdef Py_ssize_t check = 0, i, min x = (self)._coeffs y = (right)._coeffs if len(x) > len(y): @@ -11874,7 +11881,7 @@ cdef class Polynomial_generic_dense(Polynomial): cpdef _sub_(self, right): cdef Polynomial_generic_dense res - cdef Py_ssize_t check=0, i, min + cdef Py_ssize_t check = 0, i, min x = (self)._coeffs y = (right)._coeffs if len(x) > len(y): @@ -11900,7 +11907,7 @@ cdef class Polynomial_generic_dense(Polynomial): c = (self._coeffs[0])._parent.coerce(c) v = [c * a for a in self._coeffs] cdef Polynomial_generic_dense res = self._new_c(v, self._parent) - #if not v[len(v)-1]: + # if not v[len(v)-1]: # "normalize" checks this anyway... res._normalize() return res @@ -11912,7 +11919,7 @@ cdef class Polynomial_generic_dense(Polynomial): c = (self._coeffs[0])._parent.coerce(c) v = [a * c for a in self._coeffs] cdef Polynomial_generic_dense res = self._new_c(v, self._parent) - #if not v[len(v)-1]: + # if not v[len(v)-1]: # "normalize" checks this anyway... res._normalize() return res @@ -12121,7 +12128,7 @@ cdef class Polynomial_generic_dense(Polynomial): quo.append(q) quo.reverse() - return self._new_c(quo,self._parent), self._new_c(x,self._parent)._inplace_truncate(n-1) + return self._new_c(quo, self._parent), self._new_c(x, self._parent)._inplace_truncate(n-1) cpdef Polynomial truncate(self, long n): r""" @@ -12150,10 +12157,10 @@ cdef class Polynomial_generic_dense(Polynomial): sage: type(f) """ - l = len(self._coeffs) - if n > l: - n = l - while n > 0 and not self._coeffs[n-1]: + ln = len(self._coeffs) + if n > ln: + n = ln + while n > 0 and not self._coeffs[n - 1]: n -= 1 return self._new_c(self._coeffs[:n], self._parent) @@ -12164,6 +12171,7 @@ cdef class Polynomial_generic_dense(Polynomial): self._coeffs = self._coeffs[:n] return self + def make_generic_polynomial(parent, coeffs): return parent(coeffs) @@ -12205,7 +12213,7 @@ def universal_discriminant(n): pr1 = PolynomialRing(ZZ, n + 1, 'a') pr2 = PolynomialRing(pr1, 'x') p = pr2(list(pr1.gens())) - return (1 - (n&2))*p.resultant(p.derivative())//pr1.gen(n) + return (1 - (n & 2)) * p.resultant(p.derivative()) // pr1.gen(n) cpdef Polynomial generic_power_trunc(Polynomial p, Integer n, long prec): @@ -12301,7 +12309,7 @@ cpdef list _dict_to_list(dict x, zero): return [] n = max(x.keys()) cdef list v - if isinstance(n, tuple): # a mpoly dict + if isinstance(n, tuple): # a mpoly dict n = n[0] v = [zero] * (n+1) for i, z in x.iteritems(): From 9817b917c41f44feb02fc1971d3a4d91e62f64fe Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sat, 23 Sep 2023 09:45:52 +0200 Subject: [PATCH 011/463] homogeneize __reduce__ for uni- and multi-variate Laurent polynomials --- src/sage/rings/polynomial/laurent_polynomial.pyx | 2 +- src/sage/rings/polynomial/laurent_polynomial_ideal.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 917943f5619..6d3168f4995 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -379,7 +379,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: loads(dumps(elt)) == elt True """ - return LaurentPolynomial_univariate, (self._parent, self.__u, self.__n) + return LaurentPolynomial_univariate, (self.__u, self.__n) # eliminate first term in the tuple for the previous definition def _polynomial_(self, R): r""" diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index fbfa99fd8ac..c36c52957cd 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -198,7 +198,7 @@ def __contains__(self, f): if not f or f in self.gens(): return True f = self.ring()(f) - g = f.__reduce__()[1][1] + g = f.__reduce__()[1][0] return (g in self.polynomial_ideal()) # Operations on ideals @@ -501,7 +501,7 @@ def associated_primes(self): Multivariate Laurent Polynomial Ring in x, y, z over Rational Field) """ ap = self.polynomial_ideal(saturate=False).associated_primes() - ap2 = [self.ring().ideal(id.gens(), hint=id) for Iid in ap] + ap2 = [self.ring().ideal(id.gens(), hint=id) for id in ap] return tuple(id for id in ap2 if not id.is_one()) def minimal_associated_primes(self, saturate=False): From 5591d6cd8d41856327619fd68d894dc4933e155f Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sat, 23 Sep 2023 11:08:00 +0200 Subject: [PATCH 012/463] style --- src/sage/matrix/matrix2.pyx | 731 +++++++++--------- .../rings/polynomial/laurent_polynomial.pyx | 14 +- .../polynomial/laurent_polynomial_ring.py | 5 + 3 files changed, 386 insertions(+), 364 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 1e871d9e553..d438453318f 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -206,10 +206,10 @@ cdef class Matrix(Matrix1): from sage.matrix.constructor import matrix if self.is_sparse(): return matrix({ij: self[ij].subs(*args, **kwds) for ij in self.nonzero_positions()}, - nrows=self._nrows, ncols=self._ncols, sparse=True) + nrows=self._nrows, ncols=self._ncols, sparse=True) else: return matrix([a.subs(*args, **kwds) for a in self.list()], - nrows=self._nrows, ncols=self._ncols, sparse=False) + nrows=self._nrows, ncols=self._ncols, sparse=False) def solve_left(self, B, check=True): """ @@ -887,8 +887,8 @@ cdef class Matrix(Matrix1): # Elements of SR "remember" whether or not they are exact. # If every element in the system is exact, we can probably # still check the solution over the inexact ring SR. - check = (check and all( e.is_exact() - for e in self.list() + B.list() )) + check = (check and all(e.is_exact() + for e in self.list() + B.list())) else: check = (check and K.is_exact()) @@ -972,7 +972,7 @@ cdef class Matrix(Matrix1): raise NotFullRankError D = self.augment(B) D.echelonize() - return D.matrix_from_columns(range(self.ncols(),D.ncols())) + return D.matrix_from_columns(range(self.ncols(), D.ncols())) def pivot_rows(self): """ @@ -1072,8 +1072,8 @@ cdef class Matrix(Matrix1): for row from 0 <= row < self._nrows: tmp = [] for c in cols: -# if c<0 or c >= self._ncols: -# raise IndexError("matrix column index out of range") + # if c<0 or c >= self._ncols: + # raise IndexError("matrix column index out of range") tmp.append(self.get_unsafe(row, c)) pr = pr * sum(tmp) return pr @@ -1170,7 +1170,10 @@ cdef class Matrix(Matrix1): sage: A.elementwise_product(vector(ZZ, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Full MatrixSpace of 5 by 10 dense matrices over Integer Ring' and 'Ambient free module of rank 4 over the principal ideal domain Integer Ring' + TypeError: no common canonical parent for objects with parents: + 'Full MatrixSpace of 5 by 10 dense matrices over Integer Ring' + and 'Ambient free module of rank 4 over the principal ideal + domain Integer Ring' sage: A = matrix(2, 2, range(4)) sage: A.elementwise_product(polygen(parent(A))) @@ -1185,7 +1188,11 @@ cdef class Matrix(Matrix1): sage: A.elementwise_product(B) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Full MatrixSpace of 5 by 10 dense matrices over Integer Ring' and 'Full MatrixSpace of 10 by 5 dense matrices over Integer Ring' + TypeError: no common canonical parent + for objects with parents: 'Full MatrixSpace of + 5 by 10 dense matrices over Integer Ring' and + 'Full MatrixSpace of 10 by 5 dense matrices over + Integer Ring' Some pairs of rings do not have a common parent where multiplication makes sense. This will raise an error. :: @@ -1383,7 +1390,7 @@ cdef class Matrix(Matrix1): m = self._nrows n = self._ncols if not m <= n: - raise ValueError("must have m <= n, but m (=%s) and n (=%s)"%(m,n)) + raise ValueError("must have m <= n, but m (=%s) and n (=%s)" % (m, n)) for r from 1 <= r < m+1: lst = _choose(n, r) @@ -1504,8 +1511,8 @@ cdef class Matrix(Matrix1): return R.zero() pm = 0 - for cols in _choose(n,k): - for rows in _choose(m,k): + for cols in _choose(n, k): + for rows in _choose(m, k): pm = pm + self.matrix_from_rows_and_columns(rows, cols).permanent() return pm @@ -1814,14 +1821,14 @@ cdef class Matrix(Matrix1): ....: if v != [1, 16, 78, 128, 53]: ....: print("ERROR with algorithm={} use_complement=False".format(algorithm)) """ - cdef Py_ssize_t i,j + cdef Py_ssize_t i, j cdef unsigned int num_ones cdef int m = self._nrows cdef int n = self._ncols cdef int mn = min(m, n) cdef Matrix B zero = self.base_ring().zero() - one = self.base_ring().one() + one = self.base_ring().one() if algorithm is None: algorithm = "ButeraPernici" @@ -1835,7 +1842,7 @@ cdef class Matrix(Matrix1): num_ones = 1 for i in range(m): for j in range(n): - x = self.get_unsafe(i,j) + x = self.get_unsafe(i, j) if x != zero: if x != one: z2 = False @@ -1847,7 +1854,7 @@ cdef class Matrix(Matrix1): break if not z2 and (complement or algorithm == "Godsil"): - raise ValueError("coefficients must be zero or one, but we have '{}' in position ({},{}).".format(x,i,j)) + raise ValueError("coefficients must be zero or one, but we have '{}' in position ({},{}).".format(x, i, j)) if use_complement is None: use_complement = z2 and num_ones > 0.55 * m * n @@ -1861,7 +1868,7 @@ cdef class Matrix(Matrix1): complement = not complement elif algorithm == "Ryser": - b = [self.permanental_minor(k,algorithm="Ryser") + b = [self.permanental_minor(k, algorithm="Ryser") for k in range(mn + 1)] elif algorithm == "ButeraPernici": @@ -1950,9 +1957,9 @@ cdef class Matrix(Matrix1): all_rows = range(self.nrows()) all_cols = range(self.ncols()) m = [] - for rows in Combinations(all_rows,k): - for cols in Combinations(all_cols,k): - m.append(self.matrix_from_rows_and_columns(rows,cols).determinant()) + for rows in Combinations(all_rows, k): + for cols in Combinations(all_cols, k): + m.append(self.matrix_from_rows_and_columns(rows, cols).determinant()) return m def det(self, *args, **kwds): @@ -2110,13 +2117,13 @@ cdef class Matrix(Matrix1): if n == 0: d = R.one() elif n == 1: - d = self.get_unsafe(0,0) + d = self.get_unsafe(0, 0) elif n == 2: - d = self.get_unsafe(0,0)*self.get_unsafe(1,1) - self.get_unsafe(1,0)*self.get_unsafe(0,1) + d = self.get_unsafe(0, 0)*self.get_unsafe(1, 1) - self.get_unsafe(1, 0)*self.get_unsafe(0, 1) elif n == 3: - d = self.get_unsafe(0,0) * (self.get_unsafe(1,1)*self.get_unsafe(2,2) - self.get_unsafe(1,2)*self.get_unsafe(2,1)) \ - - self.get_unsafe(1,0) * (self.get_unsafe(0,1)*self.get_unsafe(2,2) - self.get_unsafe(0,2)*self.get_unsafe(2,1)) \ - + self.get_unsafe(2,0) * (self.get_unsafe(0,1)*self.get_unsafe(1,2) - self.get_unsafe(0,2)*self.get_unsafe(1,1)) + d = self.get_unsafe(0, 0) * (self.get_unsafe(1, 1)*self.get_unsafe(2, 2) - self.get_unsafe(1, 2)*self.get_unsafe(2, 1)) \ + - self.get_unsafe(1, 0) * (self.get_unsafe(0, 1)*self.get_unsafe(2, 2) - self.get_unsafe(0, 2)*self.get_unsafe(2, 1)) \ + + self.get_unsafe(2, 0) * (self.get_unsafe(0, 1)*self.get_unsafe(1, 2) - self.get_unsafe(0, 2)*self.get_unsafe(1, 1)) self.cache('det', d) return d @@ -2130,7 +2137,7 @@ cdef class Matrix(Matrix1): d = R(self.__pari__().matdet()) else: # Lift to ZZ and compute there. - d = R(self.apply_map(lambda x : x.lift_centered()).det()) + d = R(self.apply_map(lambda x: x.lift_centered()).det()) self.cache('det', d) return d @@ -2186,18 +2193,18 @@ cdef class Matrix(Matrix1): """ cdef Py_ssize_t n, i if level == 2: - return self.get_unsafe(0,0) * self.get_unsafe(1,1) - self.get_unsafe(0,1) * self.get_unsafe(1,0) + return self.get_unsafe(0, 0) * self.get_unsafe(1, 1) - self.get_unsafe(0, 1) * self.get_unsafe(1, 0) else: level -= 1 - d = self.get_unsafe(level,level) * self._det_by_minors(level) + d = self.get_unsafe(level, level) * self._det_by_minors(level) # on each iteration, row i will be missing in the first (level) rows # swapping is much faster than taking submatrices for i from level > i >= 0: self.swap_rows(level, i) if (level - i) % 2: - d -= self.get_unsafe(level,level) * self._det_by_minors(level) + d -= self.get_unsafe(level, level) * self._det_by_minors(level) else: - d += self.get_unsafe(level,level) * self._det_by_minors(level) + d += self.get_unsafe(level, level) * self._det_by_minors(level) # undo all our permutations to get us back to where we started for i from 0 <= i < level: self.swap_rows(level, i) @@ -2648,7 +2655,7 @@ cdef class Matrix(Matrix1): """ M = self.parent().change_ring(phi.codomain()) if self.is_sparse(): - values = {(i,j): phi(z) for (i,j),z in self.dict()} + values = {(i, j): phi(z) for (i, j), z in self.dict()} else: values = [phi(z) for z in self.list()] image = M(values) @@ -2757,7 +2764,7 @@ cdef class Matrix(Matrix1): return self.dense_matrix() if self.is_sparse(): - values = {(i,j): phi(v) for (i,j),v in self.dict().iteritems()} + values = {(i, j): phi(v) for (i, j), v in self.dict().iteritems()} if R is None: R = sage.structure.sequence.Sequence(values.values()).universe() else: @@ -2775,7 +2782,7 @@ cdef class Matrix(Matrix1): else: from sage.matrix.matrix_space import MatrixSpace M = MatrixSpace(R, self._nrows, - self._ncols, sparse=sparse) + self._ncols, sparse=sparse) image = M(values) if self._subdivisions is not None: image.subdivide(*self.subdivisions()) @@ -2886,7 +2893,7 @@ cdef class Matrix(Matrix1): # At least check that the minimal polynomial kills the matrix tester.assertTrue(self.minpoly().subs(x=self).is_zero()) - def charpoly(self, var = 'x', algorithm = None): + def charpoly(self, var='x', algorithm=None): r""" Returns the characteristic polynomial of self, as a polynomial over the base ring. @@ -3081,7 +3088,7 @@ cdef class Matrix(Matrix1): self.cache('charpoly', f) return f - def _charpoly_df(self, var = 'x'): + def _charpoly_df(self, var='x'): r""" Computes the characteristic polynomial of ``self`` without divisions. @@ -3169,10 +3176,10 @@ cdef class Matrix(Matrix1): # Extract parameters # - cdef Matrix M = self - n = M._ncols - R = M._base_ring - S = PolynomialRing(R, var) + cdef Matrix M = self + n = M._ncols + R = M._base_ring + S = PolynomialRing(R, var) # Corner cases # N.B. We already tested for M to be square, hence we do not need to @@ -3197,11 +3204,11 @@ cdef class Matrix(Matrix1): from sage.matrix.constructor import matrix F = [R.zero()] * n - cdef Matrix a = matrix(R, n-1, n) + cdef Matrix a = matrix(R, n - 1, n) A = [R.zero()] * n F[0] = - M.get_unsafe(0, 0) - for t in range(1,n): + for t in range(1, n): # Set a(1, t) to be M(<=t, t) # @@ -3372,7 +3379,7 @@ cdef class Matrix(Matrix1): [] """ n = min(self.nrows(), self.ncols()) - return [self[i,i] for i in range(n)] + return [self[i, i] for i in range(n)] def trace(self): """ @@ -3409,7 +3416,7 @@ cdef class Matrix(Matrix1): cdef object s s = R(0) for i from 0 <= i < self._nrows: - s = s + self.get_unsafe(i,i) + s = s + self.get_unsafe(i, i) return s def trace_of_product(self, Matrix other): @@ -3467,11 +3474,11 @@ cdef class Matrix(Matrix1): H = self.change_ring(K) H.hessenbergize() except TypeError as msg: - raise TypeError("%s\nHessenberg form only possible for matrices over a field"%msg) + raise TypeError("%s\nHessenberg form only possible for matrices over a field" % msg) else: H = self.__copy__() H.hessenbergize() - #end if + # end if self.cache('hessenberg_form', H) return H @@ -3515,7 +3522,7 @@ cdef class Matrix(Matrix1): cdef Py_ssize_t i, j, m, n, r n = self._nrows - tm = verbose("Computing Hessenberg Normal Form of %sx%s matrix"%(n,n)) + tm = verbose("Computing Hessenberg Normal Form of %sx%s matrix" % (n, n)) if not self.is_square(): raise TypeError("self must be square") @@ -3542,20 +3549,20 @@ cdef class Matrix(Matrix1): if i != -1: # Found a nonzero entry in column m-1 that is strictly below row m # Now set i to be the first nonzero position >= m in column m-1 - if not self.get_is_zero_unsafe(m,m-1): + if not self.get_is_zero_unsafe(m, m - 1): i = m - t = self.get_unsafe(i,m-1) + t = self.get_unsafe(i, m - 1) t_inv = None if i > m: - self.swap_rows_c(i,m) + self.swap_rows_c(i, m) # We must do the corresponding column swap to # maintain the characteristic polynomial (which is # an invariant of Hessenberg form) - self.swap_columns_c(i,m) + self.swap_columns_c(i, m) # Now the nonzero entry in position (m,m-1) is t. # Use t to clear the entries in column m-1 below m. for j from m+1 <= j < n: - x = self.get_unsafe(j, m-1) + x = self.get_unsafe(j, m - 1) if x != zero: if t_inv is None: t_inv = one / t @@ -3566,7 +3573,7 @@ cdef class Matrix(Matrix1): # column m, and we're only worried about column m-1 right now. # Add u*column_j to column_m. self.add_multiple_of_column_c(m, j, u, 0) - verbose("Finished Hessenberg Normal Form of %sx%s matrix"%(n,n),tm) + verbose("Finished Hessenberg Normal Form of %sx%s matrix" % (n, n), tm) def _charpoly_hessenberg(self, var): """ @@ -3617,9 +3624,9 @@ cdef class Matrix(Matrix1): n = self._nrows cdef Matrix c - c = H.new_matrix(nrows=n+1,ncols=n+1) # the 0 matrix + c = H.new_matrix(nrows=n + 1, ncols=n + 1) # the 0 matrix one = H._coerce_element(1) - c.set_unsafe(0,0,one) + c.set_unsafe(0, 0, one) for m from 1 <= m <= n: # Set the m-th row of c to (x - H[m-1,m-1])*c[m-1] = x*c[m-1] - H[m-1,m-1]*c[m-1] @@ -3627,20 +3634,21 @@ cdef class Matrix(Matrix1): # shifted to the right by one. We then add # -H[m-1,m-1]*c[m-1] to the resulting m-th row. for i from 1 <= i <= n: - c.set_unsafe(m, i, c.get_unsafe(m-1,i-1)) - c.add_multiple_of_row_c(m, m-1, -H.get_unsafe(m-1, m-1), 0) + c.set_unsafe(m, i, c.get_unsafe(m - 1, i - 1)) + c.add_multiple_of_row_c(m, m-1, -H.get_unsafe(m - 1, m - 1), 0) t = one for i from 1 <= i < m: - t = t * H.get_unsafe(m-i,m-i-1) + t = t * H.get_unsafe(m - i, m - i - 1) # Set the m-th row of c to c[m] - t*H[m-i-1,m-1]*c[m-i-1] - c.add_multiple_of_row_c(m, m-i-1, - t*H.get_unsafe(m-i-1,m-1), 0) + c.add_multiple_of_row_c(m, m - i - 1, -t * H.get_unsafe(m - i - 1, m - 1), 0) # The answer is now the n-th row of c. v = PyList_New(n+1) # this is really sort of v = []..." for i from 0 <= i <= n: # Finally, set v[i] = c[n,i] - o = c.get_unsafe(n,i) - Py_INCREF(o); PyList_SET_ITEM(v, i, o) + o = c.get_unsafe(n, i) + Py_INCREF(o) + PyList_SET_ITEM(v, i, o) R = self._base_ring[var] # polynomial ring over the base ring return R(v) @@ -3758,12 +3766,12 @@ cdef class Matrix(Matrix1): [0 0 1] """ from sage.matrix.matrix_space import MatrixSpace - tm = verbose("computing right kernel matrix over a number field for %sx%s matrix" % (self.nrows(), self.ncols()),level=1) + tm = verbose("computing right kernel matrix over a number field for %sx%s matrix" % (self.nrows(), self.ncols()), level=1) basis = self.__pari__().matker() # Coerce PARI representations into the number field R = self.base_ring() basis = [[R(x) for x in row] for row in basis] - verbose("done computing right kernel matrix over a number field for %sx%s matrix" % (self.nrows(), self.ncols()),level=1,t=tm) + verbose("done computing right kernel matrix over a number field for %sx%s matrix" % (self.nrows(), self.ncols()), level=1, t=tm) return 'pivot-pari-numberfield', MatrixSpace(R, len(basis), ncols=self._ncols)(basis) def _right_kernel_matrix_over_field(self, *args, **kwds): @@ -3817,7 +3825,7 @@ cdef class Matrix(Matrix1): [0 0 1] """ from sage.matrix.matrix_space import MatrixSpace - tm = verbose("computing right kernel matrix over an arbitrary field for %sx%s matrix" % (self.nrows(), self.ncols()),level=1) + tm = verbose("computing right kernel matrix over an arbitrary field for %sx%s matrix" % (self.nrows(), self.ncols()), level=1) E = self.echelon_form(*args, **kwds) pivots = E.pivots() pivots_set = set(pivots) @@ -3846,7 +3854,7 @@ cdef class Matrix(Matrix1): basis.append(v) M = MS(basis, coerce=False) tm = verbose("done computing right kernel matrix over an arbitrary field for %sx%s matrix" - % (self.nrows(), self.ncols()),level=1,t=tm) + % (self.nrows(), self.ncols()), level=1, t=tm) return 'pivot-generic', M def _right_kernel_matrix_over_domain(self): @@ -3910,7 +3918,7 @@ cdef class Matrix(Matrix1): cdef Py_ssize_t i, nrows = self._nrows for i in range(self._ncols): if i >= nrows or d[i, i] == 0: - basis.append( v.column(i) ) + basis.append(v.column(i)) verbose("done computing right kernel matrix over a domain for %sx%s matrix" % (self.nrows(), self.ncols()), level=1, t=tm) return 'computed-smith-form', self.new_matrix(nrows=len(basis), ncols=self._ncols, entries=basis) @@ -4501,7 +4509,7 @@ cdef class Matrix(Matrix1): if algorithm is None: algorithm = 'default' elif algorithm not in ['default', 'generic', 'flint', 'pari', 'padic', 'pluq']: - raise ValueError("matrix kernel algorithm '%s' not recognized" % algorithm ) + raise ValueError("matrix kernel algorithm '%s' not recognized" % algorithm) elif algorithm == 'padic' and not (is_IntegerRing(R) or is_RationalField(R)): raise ValueError("'padic' matrix kernel algorithm only available over the rationals and the integers, not over %s" % R) elif algorithm == 'flint' and not (is_IntegerRing(R) or is_RationalField(R)): @@ -4518,7 +4526,7 @@ cdef class Matrix(Matrix1): if basis is None: basis = 'default' elif basis not in ['default', 'computed', 'echelon', 'pivot', 'LLL']: - raise ValueError("matrix kernel basis format '%s' not recognized" % basis ) + raise ValueError("matrix kernel basis format '%s' not recognized" % basis) elif basis == 'pivot' and R not in _Fields: raise ValueError('pivot basis only available over a field, not over %s' % R) elif basis == 'LLL' and not is_IntegerRing(R): @@ -4552,7 +4560,8 @@ cdef class Matrix(Matrix1): # Third: generic first, if requested explicitly # then try specialized class methods, and finally # delegate to ad-hoc methods in greater generality - M = None; format = '' + M = None + format = '' if algorithm == 'generic': format, M = self._right_kernel_matrix_over_field() @@ -4582,7 +4591,7 @@ cdef class Matrix(Matrix1): # zero columns as well. (eg PARI?) This could be fixed at the source # with a careful study of the phenomenon. Start by commenting out # the following and running doctests in sage/matrix - if M.nrows()==0 and M.ncols()!=self.ncols(): + if M.nrows() == 0 and M.ncols() != self.ncols(): M = M.new_matrix(nrows=0, ncols=self.ncols()) # Convert basis to requested type and return the matrix @@ -5145,10 +5154,10 @@ cdef class Matrix(Matrix1): if K is not None: return K - tm = verbose("computing left kernel for %sx%s matrix" % (self.nrows(), self.ncols()),level=1) + tm = verbose("computing left kernel for %sx%s matrix" % (self.nrows(), self.ncols()), level=1) K = self.transpose().right_kernel(*args, **kwds) self.cache('left_kernel', K) - verbose("done computing left kernel for %sx%s matrix" % (self.nrows(), self.ncols()),level=1,t=tm) + verbose("done computing left kernel for %sx%s matrix" % (self.nrows(), self.ncols()), level=1, t=tm) return K kernel = left_kernel @@ -5520,15 +5529,15 @@ cdef class Matrix(Matrix1): False) ] """ if algorithm == 'kernel' or self.base_ring() not in _Fields: - return self._decomposition_using_kernels(is_diagonalizable = is_diagonalizable, dual=dual) + return self._decomposition_using_kernels(is_diagonalizable=is_diagonalizable, dual=dual) elif algorithm == 'spin': - X = self._decomposition_spin_generic(is_diagonalizable = is_diagonalizable) + X = self._decomposition_spin_generic(is_diagonalizable=is_diagonalizable) if dual: - Y = self.transpose()._decomposition_spin_generic(is_diagonalizable = is_diagonalizable) + Y = self.transpose()._decomposition_spin_generic(is_diagonalizable=is_diagonalizable) return X, Y return X else: - raise ValueError("no algorithm '%s'"%algorithm) + raise ValueError("no algorithm '%s'" % algorithm) def _decomposition_spin_generic(self, is_diagonalizable=False): r""" @@ -5558,13 +5567,13 @@ cdef class Matrix(Matrix1): if len(F) == 1: V = self.base_ring()**self.nrows() - return decomp_seq([(V,F[0][1]==1)]) + return decomp_seq([(V, F[0][1] == 1)]) V = self.base_ring()**self.nrows() v = V.random_element() num_iterates = max([0] + [f.degree() - g.degree() for g, _ in F if g.degree() > 1]) + 1 - S = [ ] + S = [] F.sort() for i in range(len(F)): @@ -5574,11 +5583,11 @@ cdef class Matrix(Matrix1): # Just use kernel -- much easier. B = self.__copy__() for k from 0 <= k < self.nrows(): - B[k,k] += g[0] + B[k, k] += g[0] if m > 1 and not is_diagonalizable: B = B**m W = B.kernel() - E.append((W, m==1)) + E.append((W, m == 1)) continue # General case, i.e., deg(g) > 1: @@ -5591,40 +5600,40 @@ cdef class Matrix(Matrix1): v = h.list() while len(S) < tries: - t = verbose('%s-spinning %s-th random vector'%(num_iterates, len(S)), level=2, caller_name='generic spin decomp') + t = verbose('%s-spinning %s-th random vector' % (num_iterates, len(S)), level=2, caller_name='generic spin decomp') S.append(self.iterates(V.random_element(), num_iterates)) verbose('done spinning', level=2, t=t, caller_name='generic spin decomp') for j in range(0 if W is None else W.nrows() // g.degree(), len(S)): # Compute one element of the kernel of g(A)**m. - t = verbose('compute element of kernel of g(A), for g of degree %s'%g.degree(),level=2, + t = verbose('compute element of kernel of g(A), for g of degree %s' % g.degree(), level=2, caller_name='generic spin decomp') w = S[j].linear_combination_of_rows(h.list()) - t = verbose('done computing element of kernel of g(A)', t=t,level=2, caller_name='generic spin decomp') + t = verbose('done computing element of kernel of g(A)', t=t, level=2, caller_name='generic spin decomp') # Get the rest of the kernel. - t = verbose('fill out rest of kernel',level=2, caller_name='generic spin decomp') + t = verbose('fill out rest of kernel', level=2, caller_name='generic spin decomp') if W is None: W = self.iterates(w, g.degree()) else: W = W.stack(self.iterates(w, g.degree())) - t = verbose('finished filling out more of kernel',level=2, t=t, caller_name='generic spin decomp') + t = verbose('finished filling out more of kernel', level=2, t=t, caller_name='generic spin decomp') if W.rank() == m * g.degree(): t = verbose('now computing row space', level=2, caller_name='generic spin decomp') W.echelonize() - E.append((W.row_space(), m==1)) - verbose('computed row space', level=2,t=t, caller_name='generic spin decomp') + E.append((W.row_space(), m == 1)) + verbose('computed row space', level=2, t=t, caller_name='generic spin decomp') break else: - verbose('we have not yet generated all the kernel (rank so far=%s, target rank=%s)'%( + verbose('we have not yet generated all the kernel (rank so far=%s, target rank=%s)' % ( W.rank(), m*g.degree()), level=2, caller_name='generic spin decomp') tries += 1 if tries > 1000*m: # avoid an insanely long infinite loop raise RuntimeError("likely bug in decomposition") # end if - #end while - #end for + # end while + # end for return E def _decomposition_using_kernels(self, is_diagonalizable=False, dual=False): @@ -5648,30 +5657,30 @@ cdef class Matrix(Matrix1): V = self.column_ambient_module() m = F[0][1] if dual: - return decomp_seq([(V, m==1)]), decomp_seq([(V, m==1)]) + return decomp_seq([(V, m == 1)]), decomp_seq([(V, m == 1)]) else: - return decomp_seq([(V, m==1)]) + return decomp_seq([(V, m == 1)]) F.sort() for g, m in f.factor(): - t = verbose('decomposition -- Computing g(self) for an irreducible factor g of degree %s'%g.degree(),level=2) + t = verbose('decomposition -- Computing g(self) for an irreducible factor g of degree %s' % g.degree(), level=2) if is_diagonalizable: B = g(self) else: B = g(self) - t2 = verbose('decomposition -- raising g(self) to the power %s'%m,level=2) + t2 = verbose('decomposition -- raising g(self) to the power %s' % m, level=2) B = B ** m - verbose('done powering',t2) + verbose('done powering', t2) t = verbose('decomposition -- done computing g(self)', level=2, t=t) - E.append((B.kernel(), m==1)) + E.append((B.kernel(), m == 1)) t = verbose('decomposition -- time to compute kernel', level=2, t=t) if dual: - Edual.append((B.transpose().kernel(), m==1)) + Edual.append((B.transpose().kernel(), m == 1)) verbose('decomposition -- time to compute dual kernel', level=2, t=t) if dual: return E, Edual return E - def decomposition_of_subspace(self, M, check_restrict = True, **kwds): + def decomposition_of_subspace(self, M, check_restrict=True, **kwds): """ Suppose the right action of self on M leaves M invariant. Return the decomposition of M as a list of pairs (W, is_irred) where @@ -5747,7 +5756,7 @@ cdef class Matrix(Matrix1): if not self.is_square(): raise ArithmeticError("self must be a square matrix") if M.base_ring() != self.base_ring(): - raise ArithmeticError("base rings must be the same, but self is over %s and module is over %s"%( + raise ArithmeticError("base rings must be the same, but self is over %s and module is over %s" % ( self.base_ring(), M.base_ring())) if M.degree() != self.ncols(): raise ArithmeticError("M must be a subspace of an %s-dimensional space" % self.ncols()) @@ -5755,16 +5764,18 @@ cdef class Matrix(Matrix1): time = verbose(t=0) # 1. Restrict - B = self.restrict(M, check = check_restrict) + B = self.restrict(M, check=check_restrict) time0 = verbose("decompose restriction -- ", time) # 2. Decompose restriction D = B.decomposition(**kwds) - sum_dim = sum([A.dimension() for A,_ in D]) + sum_dim = sum([A.dimension() for A, _ in D]) assert sum_dim == M.dimension(), \ "bug in decomposition; " + \ - "the sum of the dimensions (=%s) of the factors must equal the dimension (%s) of the acted on space:\nFactors found: %s\nSpace: %s"%(sum_dim, M.dimension(), D, M) + "the sum of the dimensions (=%s) of the factors must equal" + \ + "the dimension (%s) of the acted on space:\nFactors found:" + \ + "%s\nSpace: %s" % (sum_dim, M.dimension(), D, M) # 3. Lift decomposition to subspaces of ambient vector space. # Each basis vector for an element of D defines a linear @@ -5834,7 +5845,7 @@ cdef class Matrix(Matrix1): """ if not isinstance(V, sage.modules.free_module.FreeModule_generic): raise TypeError("V must be a free module") - #if V.base_ring() != self.base_ring(): + # if V.base_ring() != self.base_ring(): # raise ValueError("matrix and module must have the same base ring, but matrix is over %s and module is over %s"%(self.base_ring(), V.base_ring())) if V.degree() != self.nrows(): raise IndexError("degree of V (=%s) must equal number of rows of self (=%s)" % (V.degree(), self.nrows())) @@ -6016,7 +6027,8 @@ cdef class Matrix(Matrix1): sage: t.charpoly() # needs sage.libs.pari x^3 - 12*x^2 - 18*x """ - i = int(i); t=int(t) + i = int(i) + t = int(t) if self.nrows() != self.ncols(): raise ArithmeticError("self must be a square matrix") n = self.nrows() @@ -6421,7 +6433,7 @@ cdef class Matrix(Matrix1): if algebraic_multiplicity: return x else: - return Sequence([(e[0],e[1]) for e in x], cr=True, check=False) + return Sequence([(e[0], e[1]) for e in x], cr=True, check=False) # Possible improvements: # algorithm for dual_eigenvector in sage/modular/hecke/module.py @@ -6433,7 +6445,7 @@ cdef class Matrix(Matrix1): G = self.fcp() # factored characteristic polynomial V = [] - i = -1 # variable name index, increments for each eigenvalue + i = -1 # variable name index, increments for each eigenvalue for h, e in G: i = i + 1 if h.degree() == 1: @@ -6445,7 +6457,7 @@ cdef class Matrix(Matrix1): W = A.kernel() V.append((alpha, W.ambient_module().span_of_basis(W.basis()), e)) else: - F = h.root_field('{0}{1}'.format(var,i)) + F = h.root_field('{0}{1}'.format(var, i)) alpha = F.gen(0) A = self.change_ring(F) - alpha W = A.kernel() @@ -6469,7 +6481,7 @@ cdef class Matrix(Matrix1): if algebraic_multiplicity: return V else: - return Sequence([(e[0],e[1]) for e in V], cr=True, check=False) + return Sequence([(e[0], e[1]) for e in V], cr=True, check=False) left_eigenspaces = eigenspaces_left @@ -6673,7 +6685,7 @@ cdef class Matrix(Matrix1): if algebraic_multiplicity: return x else: - return Sequence([(e[0],e[1]) for e in x], cr=True, check=False) + return Sequence([(e[0], e[1]) for e in x], cr=True, check=False) V = self.transpose().eigenspaces_left(format=format, var=var, algebraic_multiplicity=True) @@ -6681,7 +6693,7 @@ cdef class Matrix(Matrix1): if algebraic_multiplicity: return V else: - return Sequence([(e[0],e[1]) for e in V], cr=True, check=False) + return Sequence([(e[0], e[1]) for e in V], cr=True, check=False) right_eigenspaces = eigenspaces_right @@ -6794,7 +6806,7 @@ cdef class Matrix(Matrix1): warn("Using generic algorithm for an inexact ring, which will probably give incorrect results due to numerical precision issues.") if not extend: - return Sequence(r for r,m in self.charpoly().roots() for _ in range(m)) + return Sequence(r for r, m in self.charpoly().roots() for _ in range(m)) # now we need to find a natural algebraic closure for the base ring K = self.base_ring() @@ -6814,7 +6826,7 @@ cdef class Matrix(Matrix1): if f.degree() == 1: res.extend([-f.constant_coefficient()]*e) else: - for r,ee in f.change_ring(A).roots(): + for r, ee in f.change_ring(A).roots(): res.extend([r]*(e*ee)) eigenvalues = Sequence(res) @@ -6925,7 +6937,7 @@ cdef class Matrix(Matrix1): V = [] from sage.categories.homset import hom eigenspaces = self.eigenspaces_left(format='galois', algebraic_multiplicity=True) - evec_list=[] + evec_list = [] n = self._nrows evec_eval_list = [] F = self.base_ring().fraction_field() @@ -6947,7 +6959,7 @@ cdef class Matrix(Matrix1): m = hom(eigval.parent(), e.parent(), e) space = (e.parent())**n evec_list = [(space)([m(i) for i in v]) for v in eigbasis] - evec_eval_list.append( (e, evec_list, eigmult)) + evec_eval_list.append((e, evec_list, eigmult)) return evec_eval_list @@ -7229,7 +7241,7 @@ cdef class Matrix(Matrix1): "failed to compute eigenvectors for eigenvalue %s, " "check eigenvectors_left() for partial results" % e[0]) P = matrix(rows) - return D,P + return D, P left_eigenmatrix = eigenmatrix_left @@ -7397,9 +7409,9 @@ cdef class Matrix(Matrix1): True """ - D,P = self.transpose().eigenmatrix_left(None if other is None - else other.transpose()) - return D,P.transpose() + D, P = self.transpose().eigenmatrix_left(None if other is None + else other.transpose()) + return D, P.transpose() right_eigenmatrix = eigenmatrix_right @@ -7615,7 +7627,7 @@ cdef class Matrix(Matrix1): d = self.dense_matrix().echelon_form(**kwds) for c from 0 <= c < self.ncols(): for r from 0 <= r < self.nrows(): - self.set_unsafe(r, c, d.get_unsafe(r,c)) + self.set_unsafe(r, c, d.get_unsafe(r, c)) self.clear_cache() self.cache('pivots', d.pivots()) self.cache('in_echelon_form', True) @@ -7623,11 +7635,11 @@ cdef class Matrix(Matrix1): try: a, d, p = self._echelon_form_PID() except TypeError as msg: - raise NotImplementedError("%s\nechelon form over %s not yet implemented"%(msg, self.base_ring())) + raise NotImplementedError("%s\nechelon form over %s not yet implemented" % (msg, self.base_ring())) for c from 0 <= c < self.ncols(): for r from 0 <= r < self.nrows(): - self.set_unsafe(r, c, d.get_unsafe(r,c)) + self.set_unsafe(r, c, d.get_unsafe(r, c)) self.clear_cache() self.cache('pivots', tuple(p)) self.cache('in_echelon_form', True) @@ -7827,7 +7839,7 @@ cdef class Matrix(Matrix1): kwds['algorithm'] = algorithm return self._echelonize_ring(**kwds) except ArithmeticError as msg: - raise NotImplementedError("%s\nEchelon form not implemented over '%s'."%(msg,basring)) + raise NotImplementedError("%s\nEchelon form not implemented over '%s'." % (msg, basring)) def echelon_form(self, algorithm="default", cutoff=0, **kwds): r""" @@ -7922,7 +7934,7 @@ cdef class Matrix(Matrix1): if algorithm == 'default': v = E.echelonize(cutoff=cutoff, **kwds) else: - v = E.echelonize(algorithm = algorithm, cutoff=cutoff, **kwds) + v = E.echelonize(algorithm=algorithm, cutoff=cutoff, **kwds) E.set_immutable() # so we can cache the echelon form. self.cache('echelon_form', E) if v is not None: @@ -8068,7 +8080,7 @@ cdef class Matrix(Matrix1): if self.fetch('in_echelon_form'): return self.fetch('pivots') - tm = verbose('generic in-place Gauss elimination on %s x %s matrix using %s algorithm'%(self._nrows, self._ncols, algorithm)) + tm = verbose('generic in-place Gauss elimination on %s x %s matrix using %s algorithm' % (self._nrows, self._ncols, algorithm)) self.check_mutability() cdef Matrix A @@ -8124,21 +8136,21 @@ cdef class Matrix(Matrix1): if algorithm == 'partial_pivoting': for r in range(start_row, nr): - abs_val = A.get_unsafe(r,c).abs() + abs_val = A.get_unsafe(r, c).abs() if abs_val > max_abs_val: max_abs_val = abs_val best_r = r elif algorithm == 'scaled_partial_pivoting': for r in range(start_row, nr): if scale_factors[r]: - abs_val = A.get_unsafe(r,c).abs() / scale_factors[r] + abs_val = A.get_unsafe(r, c).abs() / scale_factors[r] if abs_val > max_abs_val: max_abs_val = abs_val best_r = r - else: # algorithm == 'scaled_partial_pivoting_valuation': + else: # algorithm == 'scaled_partial_pivoting_valuation': for r in range(start_row, nr): if scale_factors[r] is not None: - abs_val = scale_factors[r] - A.get_unsafe(r,c).valuation() + abs_val = scale_factors[r] - A.get_unsafe(r, c).valuation() if max_abs_val is None or abs_val > max_abs_val: max_abs_val = abs_val best_r = r @@ -8481,7 +8493,7 @@ cdef class Matrix(Matrix1): permutations.append( (PermutationGroupElement([p(1 + i) for i in range(nrows)]), PermutationGroupElement([p(1 + nrows + i) - nrows for i in range(ncols)]) - )) + )) return permutations def permutation_normal_form(self, check=False): @@ -8588,14 +8600,14 @@ cdef class Matrix(Matrix1): # Sort each row with respect to S for the first matrix in X = MS X = copy(MS) SM = [sorted([(S[j], X[0][k][j]) for j in range(ncols)], reverse=True) - for k in range(l, nrows)] + for k in range(l, nrows)] SM = [[k[1] for k in s] for s in SM] # and pick the maximal row b = max(SM) # Find all rows equal to the maximal (potential new cases) m = [[j for j in range(nrows - l) if SM[j] == b]] - w = 0 # keeps track of how many entries we have removed from MS + w = 0 # keeps track of how many entries we have removed from MS # Let us find the maximal row in each of the entries in X = MS for i in range(1, len(X)): SN = [sorted([(S[j], X[i][k][j]) for j in range(ncols)], reverse=True) @@ -8731,7 +8743,7 @@ cdef class Matrix(Matrix1): truth, perm = N_B.is_isomorphic(M_B, certificate=True, edge_labels=True) from sage.groups.perm_gps.constructor import PermutationGroupElement if perm: - s = sorted(perm.items(), key=lambda x:x[0]) + s = sorted(perm.items(), key=lambda x: x[0]) row_perms = [value for k, value in s if k <= nrows] col_perms = [value - nrows for k, value in s if k > nrows] perm = (PermutationGroupElement(row_perms), PermutationGroupElement(col_perms)) @@ -8782,16 +8794,15 @@ cdef class Matrix(Matrix1): output = self.new_matrix(self._nrows, right._ncols) # The following used to be a little faster, but meanwhile # the previous line is faster. - #if self.is_sparse(): + # if self.is_sparse(): # output = self.matrix_space(self._nrows, right._ncols, sparse = True)(0) - #else: + # else: # output = self.matrix_space(self._nrows, right._ncols, sparse = False).zero_matrix().__copy__() - self_window = self.matrix_window() - right_window = right.matrix_window() + self_window = self.matrix_window() + right_window = right.matrix_window() output_window = output.matrix_window() - from . import strassen strassen.strassen_window_multiply(output_window, self_window, right_window, cutoff) return output @@ -8813,7 +8824,7 @@ cdef class Matrix(Matrix1): [ 0 0 0 0] [ 0 0 0 0] """ - tm = verbose('strassen echelon of %s x %s matrix'%(self._nrows, self._ncols)) + tm = verbose('strassen echelon of %s x %s matrix' % (self._nrows, self._ncols)) self.check_mutability() @@ -8836,8 +8847,8 @@ cdef class Matrix(Matrix1): verbose('done with strassen', tm) cpdef matrix_window(self, Py_ssize_t row=0, Py_ssize_t col=0, - Py_ssize_t nrows=-1, Py_ssize_t ncols=-1, - bint check=1): + Py_ssize_t nrows=-1, Py_ssize_t ncols=-1, + bint check=1): """ Return the requested matrix window. @@ -9091,7 +9102,7 @@ cdef class Matrix(Matrix1): """ if self._subdivisions is None: self._subdivisions = ([0, self._nrows], [0, self._ncols]) - key = "subdivision %s %s"%(i,j) + key = "subdivision %s %s" % (i, j) sd = self.fetch(key) if sd is None: sd = self[self._subdivisions[0][i]:self._subdivisions[0][i+1], @@ -9137,13 +9148,13 @@ cdef class Matrix(Matrix1): """ if self._subdivisions is None: if not i and not j: - return self[x,y] + return self[x, y] else: - raise IndexError("No such submatrix %s, %s"%(i,j)) + raise IndexError("No such submatrix %s, %s" % (i, j)) if x >= self._subdivisions[0][i+1]-self._subdivisions[0][i] or \ y >= self._subdivisions[1][j+1]-self._subdivisions[1][j]: - raise IndexError("Submatrix %s,%s has no entry %s,%s"%(i,j, x, y)) - return self[self._subdivisions[0][i] + x , self._subdivisions[1][j] + y] + raise IndexError("Submatrix %s,%s has no entry %s,%s" % (i, j, x, y)) + return self[self._subdivisions[0][i] + x, self._subdivisions[1][j] + y] def _subdivide_on_augment(self, left, right): r""" @@ -9454,7 +9465,7 @@ cdef class Matrix(Matrix1): for i from 0 <= i < self._nrows: for j from 0 <= j < self._ncols: self.set_unsafe(i, j, R._random_nonzero_element(*args, - **kwds)) + **kwds)) else: num = int(self._nrows * self._ncols * density) for i from 0 <= i < num: @@ -9494,7 +9505,7 @@ cdef class Matrix(Matrix1): """ return self.is_scalar(self.base_ring().one()) - def is_scalar(self, a = None): + def is_scalar(self, a=None): """ Return True if this matrix is a scalar matrix. @@ -9529,13 +9540,13 @@ cdef class Matrix(Matrix1): if a is None: if self._nrows == 0: return True - a = self.get_unsafe(0,0) + a = self.get_unsafe(0, 0) else: a = self.base_ring()(a) for i in range(self._nrows): for j in range(self._ncols): if i != j: - if not self.get_unsafe(i,j).is_zero(): + if not self.get_unsafe(i, j).is_zero(): return False else: if self.get_unsafe(i, i) != a: @@ -9572,7 +9583,7 @@ cdef class Matrix(Matrix1): for i in range(self._nrows): for j in range(self._ncols): if i != j: - if not self.get_unsafe(i,j).is_zero(): + if not self.get_unsafe(i, j).is_zero(): return False return True @@ -9682,7 +9693,7 @@ cdef class Matrix(Matrix1): P = self.transpose() * self # Orthogonal return P.is_scalar(1) - def is_bistochastic(self, normalized = True): + def is_bistochastic(self, normalized=True): r""" Returns ``True`` if this matrix is bistochastic. @@ -9845,12 +9856,12 @@ cdef class Matrix(Matrix1): cdef Matrix left = self*CT cdef Matrix right = CT*self - cdef Py_ssize_t i,j + cdef Py_ssize_t i, j normal = True # two products are Hermitian, need only check lower triangle for i from 0 <= i < self._nrows: for j from 0 <= j <= i: - if left.get_unsafe(i,j) != right.get_unsafe(i,j): + if left.get_unsafe(i, j) != right.get_unsafe(i, j): normal = False break if not normal: @@ -9967,11 +9978,11 @@ cdef class Matrix(Matrix1): ir = mc ic = mr b = 1.0 - elif max(mr,mc) > maxsize: + elif max(mr, mc) > maxsize: maxsize = float(maxsize) - ir = int(mc * maxsize/max(mr,mc)) - ic = int(mr * maxsize/max(mr,mc)) - b = max(mr,mc)/maxsize + ir = int(mc * maxsize / max(mr, mc)) + ic = int(mr * maxsize / max(mr, mc)) + b = max(mr, mc) / maxsize else: ir = mc ic = mr @@ -9988,7 +9999,7 @@ cdef class Matrix(Matrix1): for _x in range(bi): for _y in range(bi): if not self.get_unsafe((x*b + _x), (y*b + _y)).is_zero(): - v -= 1 #increase darkness + v -= 1 # increase darkness v = (v * fct + 0.5) pixel[y, x] = (v, v, v) return img @@ -10024,7 +10035,7 @@ cdef class Matrix(Matrix1): sage: a.density() 0 """ - cdef int x,y,k + cdef int x, y, k k = 0 nr = self.nrows() nc = self.ncols() @@ -10032,8 +10043,8 @@ cdef class Matrix(Matrix1): return 0 for x from 0 <= x < nr: for y from 0 <= y < nc: - if not self.get_unsafe(x,y).is_zero(): - k+=1 + if not self.get_unsafe(x, y).is_zero(): + k += 1 return QQ(k)/QQ(nr*nc) def inverse(self): @@ -10253,13 +10264,13 @@ cdef class Matrix(Matrix1): This is all left to the method `adjugate`. """ - n = self._ncols + n = self._ncols if self._nrows != n: raise ValueError("self must be a square matrix") A = self.charpoly().shift(-1)(self) - return A if n%2 else -A + return A if n % 2 else -A def QR(self, full=True): r""" @@ -10529,16 +10540,16 @@ cdef class Matrix(Matrix1): scale = sqrt(hip) q = (1/scale)*v Q.append(q) - R[row,i] = scale - for j in range(i+1, n): - R[row,j] = q.hermitian_inner_product(V[j]) - V[j] = V[j] - R[row,j]*q + R[row, i] = scale + for j in range(i + 1, n): + R[row, j] = q.hermitian_inner_product(V[j]) + V[j] = V[j] - R[row, j] * q row = row + 1 except TypeError: raise TypeError('QR decomposition unable to compute square roots in %s' % F) # complete to full orthonormal basis, or reduce to truncated R if full: - Qt = matrix(Q) # as rows here + Qt = matrix(Q) # as rows here if Qt.nrows() == 0: Qt = zero_matrix(F, 0, m) orthogonal = Qt.right_kernel().basis_matrix().transpose() @@ -10687,12 +10698,12 @@ cdef class Matrix(Matrix1): zero = F(0) Bstar = [] R = zero_matrix(F, n) - nnz = 0 # number non-zero rows in R, or number of nonzero vectors in Bstar + nnz = 0 # number non-zero rows in R, or number of nonzero vectors in Bstar for i in range(n): ortho = B[i] for j in range(nnz): - R[j,i] = Bstar[j].hermitian_inner_product(B[i])/Bstar[j].hermitian_inner_product(Bstar[j]) - ortho = ortho - R[j,i]*Bstar[j] + R[j, i] = Bstar[j].hermitian_inner_product(B[i]) / Bstar[j].hermitian_inner_product(Bstar[j]) + ortho = ortho - R[j, i] * Bstar[j] if ortho.hermitian_inner_product(ortho) != zero: Bstar.append(ortho) R[nnz, i] = 1 @@ -11028,7 +11039,8 @@ cdef class Matrix(Matrix1): R = self.base_ring() if isinstance(R, (sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField)): Q, R = self.transpose().QR() - m = R.nrows(); n = R.ncols() + m = R.nrows() + n = R.ncols() if m > n: Q = Q[0:m, 0:n] R = R[0:n, 0:n] @@ -11465,7 +11477,7 @@ cdef class Matrix(Matrix1): blocks = [] for eval, mult in evals: if mult == 1: - blocks.append((eval,1)) + blocks.append((eval, 1)) else: B = A - diagonal_matrix([eval]*n, sparse=sparse) C = B @@ -11494,7 +11506,7 @@ cdef class Matrix(Matrix1): # a Jordan chain for each, adding the chain (a sequence of # vectors) to the entry for the eigenvalue (which is a list). jordan_chains = {} - for eval,_ in evals: + for eval, _ in evals: jordan_chains[eval] = [] # Let B be the matrix `A - eval Id`. @@ -11532,9 +11544,9 @@ cdef class Matrix(Matrix1): # Now ``jordan_chains`` has all the columns of the transformation # matrix; we just need to put them in the right order. jordan_basis = [] - for eval,size in blocks: + for eval, size in blocks: # Find a block with the right size - for index,chain in enumerate(jordan_chains[eval]): + for index, chain in enumerate(jordan_chains[eval]): if len(chain) == size: jordan_basis += jordan_chains[eval].pop(index) break @@ -12592,7 +12604,7 @@ cdef class Matrix(Matrix1): R = self.base_ring() if not is_Vector(v): raise TypeError('first input should be a vector, not {0}'.format(v)) - if not (var is None or isinstance(var, str)): + if not (var is None or isinstance(var, str)): generator = False try: generator = var.is_gen() @@ -12911,7 +12923,7 @@ cdef class Matrix(Matrix1): True """ - cdef Matrix C # output matrix + cdef Matrix C # output matrix C = self.fetch('cholesky') if C is not None: return C @@ -12933,7 +12945,7 @@ cdef class Matrix(Matrix1): cdef Matrix L # block_ldlt() results cdef list d # block_ldlt() results try: - _,L,d = self._block_ldlt(True) + _, L, d = self._block_ldlt(True) except ValueError: # If the matrix was positive-definite, that would # have worked. @@ -12946,7 +12958,7 @@ cdef class Matrix(Matrix1): cdef bint extend = False for X in d: # The X are guaranteed to be one-by-one blocks. - x = X[0,0] + x = X[0, 0] if x <= zero: raise ValueError("matrix is not positive definite") @@ -12973,7 +12985,7 @@ cdef class Matrix(Matrix1): from sage.rings.qqbar import AA try: C = L.change_ring(AA) - except ValueError: # cannot coerce... + except ValueError: # cannot coerce... C = L.change_ring(F_ac) else: C = L.__copy__() @@ -12981,11 +12993,11 @@ cdef class Matrix(Matrix1): # Overwrite the (strict) upper-triangular part of "C", since a # priori it contains junk after _block_ldlt(). zero = C.base_ring().zero() - cdef Py_ssize_t i, j # loop indices + cdef Py_ssize_t i, j # loop indices for i in range(n): C.rescale_col_c(i, splits[i], 0) - for j in range(i+1,n): - C.set_unsafe(i,j,zero) + for j in range(i + 1, n): + C.set_unsafe(i, j, zero) C.set_immutable() self.cache('cholesky', C) return C @@ -13105,7 +13117,7 @@ cdef class Matrix(Matrix1): sage: actual == expected True """ - P,L,D = self.block_ldlt() + P, L, D = self.block_ldlt() # The default "echelonize" inverse() method works just fine for # triangular matrices. @@ -13558,24 +13570,24 @@ cdef class Matrix(Matrix1): # abs() necessary to convert zero to the # correct type for comparisons (Issue #12208) max_entry = abs(zero) - for i in range(k,m): - entry = abs(M.get_unsafe(i,k)) + for i in range(k, m): + entry = abs(M.get_unsafe(i, k)) if entry > max_entry: max_location = i max_entry = entry else: - for i in range(k,m): - if M.get_unsafe(i,k) != zero: + for i in range(k, m): + if M.get_unsafe(i, k) != zero: max_location = i break if max_location != -1: perm[k], perm[max_location] = perm[max_location], perm[k] M.swap_rows(k, max_location) for j in range(k+1, m): - scale = -M.get_unsafe(j,k)/M.get_unsafe(k,k) - M.set_unsafe(j,k, -scale) - for p in range(k+1,n): - M.set_unsafe(j,p, M.get_unsafe(j,p) + scale*M.get_unsafe(k,p)) + scale = -M.get_unsafe(j, k) / M.get_unsafe(k, k) + M.set_unsafe(j, k, -scale) + for p in range(k + 1, n): + M.set_unsafe(j, p, M.get_unsafe(j, p) + scale * M.get_unsafe(k, p)) perm = tuple(perm) M.set_immutable() compact = (perm, M) @@ -13594,11 +13606,11 @@ cdef class Matrix(Matrix1): perm = [perm[i]+1 for i in range(m)] P = sage.combinat.permutation.Permutation(perm).to_matrix() P = P.change_ring(F) - L = M.matrix_space(m,m).identity_matrix().__copy__() + L = M.matrix_space(m, m).identity_matrix().__copy__() for i in range(1, m): - for k in range(min(i,d)): - L[i,k] = M[i,k] - M[i,k] = zero + for k in range(min(i, d)): + L[i, k] = M[i, k] + M[i, k] = zero return P, L, M def _indefinite_factorization(self, algorithm, check=True): @@ -13840,16 +13852,16 @@ cdef class Matrix(Matrix1): t = L.get_unsafe(i, j) if conjugate: for k in range(j): - t -= L.get_unsafe(k,i)*L.get_unsafe(j,k).conjugate() + t -= L.get_unsafe(k, i) * L.get_unsafe(j, k).conjugate() else: for k in range(j): - t -= L.get_unsafe(k,i)*L.get_unsafe(j,k) + t -= L.get_unsafe(k, i) * L.get_unsafe(j, k) if i == j: if not t: - self.cache(cache_string, (False,i+1)) - return (False, i+1) + self.cache(cache_string, (False, i + 1)) + return (False, i + 1) d.append(t) - d_inv.append(one/t) + d_inv.append(one / t) L.set_unsafe(i, i, one) else: L.set_unsafe(j, i, t) @@ -14065,7 +14077,7 @@ cdef class Matrix(Matrix1): if result is not None: return result - cdef Py_ssize_t i, j, k # loop indices + cdef Py_ssize_t i, j, k # loop indices cdef Py_ssize_t r # another row/column index # We need to construct 1x1 and 2x2 matrices to stick in d. @@ -14089,7 +14101,7 @@ cdef class Matrix(Matrix1): # at the end of the function, not as its columns are computed. ring = self.base_ring().fraction_field() - cdef Matrix A # A copy of the input matrix + cdef Matrix A # A copy of the input matrix if self.base_ring() == ring: A = self.__copy__() else: @@ -14127,7 +14139,7 @@ cdef class Matrix(Matrix1): cdef list d = [] # And the parent of those diagonal blocks that are 1x1... - one_by_one_space = A.matrix_space(1,1) + one_by_one_space = A.matrix_space(1, 1) # The case n == 0 is *almost* handled by skipping the # forthcoming loop entirely. However, we must stick a trivial @@ -14143,7 +14155,7 @@ cdef class Matrix(Matrix1): # where we're storing the next iterate. So our indices are # always "k" greater than those of Higham or B&K. - A_kk = A.get_unsafe(k,k) + A_kk = A.get_unsafe(k, k) if k == (n-1): # Handle this trivial case manually, since otherwise the @@ -14151,7 +14163,7 @@ cdef class Matrix(Matrix1): # meaningless. The corresponding entry of "L" will be # fixed later (since it's an on-diagonal element, it gets # set to one eventually). - d.append( one_by_one_space(A_kk) ) + d.append(one_by_one_space(A_kk)) k += 1 continue @@ -14161,8 +14173,8 @@ cdef class Matrix(Matrix1): # It's a back door that lets us escape with only the standard non-block # non-pivoting LDL^T factorization. This allows us to implement e.g. # indefinite_factorization() in terms of this method. - d.append( one_by_one_space(A_kk) ) - _block_ldlt_pivot1x1(A,k) + d.append(one_by_one_space(A_kk)) + _block_ldlt_pivot1x1(A, k) k += 1 continue except ZeroDivisionError: @@ -14177,8 +14189,8 @@ cdef class Matrix(Matrix1): # Note: omega_1 is defined as a C double, but the abs() # below would make a complex number approximate anyway. omega_1 = 0 - for i in range(k+1,n): - a_ik_abs = A.get_unsafe(i,k).abs() + for i in range(k + 1, n): + a_ik_abs = A.get_unsafe(i, k).abs() if a_ik_abs > omega_1: omega_1 = a_ik_abs # We record the index "r" that corresponds to @@ -14198,7 +14210,7 @@ cdef class Matrix(Matrix1): # the 1x1 pivot "a" in the top-left position. The entry "a" # will be adjusted to "1" later on to ensure that "L" is # (block) unit-lower-triangular. - d.append( one_by_one_space(A_kk) ) + d.append(one_by_one_space(A_kk)) k += 1 continue @@ -14210,8 +14222,8 @@ cdef class Matrix(Matrix1): # otherwise. We are performing a 1x1 pivot, but the # rows/columns are already where we want them, so nothing # needs to be permuted. - d.append( one_by_one_space(A_kk) ) - _block_ldlt_pivot1x1(A,k) + d.append(one_by_one_space(A_kk)) + _block_ldlt_pivot1x1(A, k) k += 1 continue @@ -14225,27 +14237,30 @@ cdef class Matrix(Matrix1): # Note: omega_r is defined as a C double, but the abs() # below would make a complex number approximate anyway. omega_r = 0 - for j in range(k,r): - a_rj_abs = A.get_unsafe(r,j).abs() + for j in range(k, r): + a_rj_abs = A.get_unsafe(r, j).abs() if a_rj_abs > omega_r: omega_r = a_rj_abs if A_kk.abs()*omega_r >= alpha*(omega_1**2): # Step (2) in Higham or Step (4) in B&K. - d.append( one_by_one_space(A_kk) ) - _block_ldlt_pivot1x1(A,k) + d.append(one_by_one_space(A_kk)) + _block_ldlt_pivot1x1(A, k) k += 1 continue - A_rr = A.get_unsafe(r,r) + A_rr = A.get_unsafe(r, r) if A_rr.abs() > alpha*omega_r: # This is Step (3) in Higham or Step (5) in B&K. Still # a 1x1 pivot, but this time we need to swap # rows/columns k and r. - d.append( one_by_one_space(A_rr) ) - A.swap_columns_c(k,r); A.swap_rows_c(k,r) - p_k = p[k]; p[k] = p[r]; p[r] = p_k - _block_ldlt_pivot1x1(A,k) + d.append(one_by_one_space(A_rr)) + A.swap_columns_c(k, r) + A.swap_rows_c(k, r) + p_k = p[k] + p[k] = p[r] + p[r] = p_k + _block_ldlt_pivot1x1(A, k) k += 1 continue @@ -14253,16 +14268,19 @@ cdef class Matrix(Matrix1): # or Step (6) in B&K, where we perform a 2x2 pivot. See # pivot1x1() for an explanation of why it's OK to permute # the entries of "L" here as well. - A.swap_columns_c(k+1,r); A.swap_rows_c(k+1,r) - p_k = p[k+1]; p[k+1] = p[r]; p[r] = p_k + A.swap_columns_c(k + 1, r) + A.swap_rows_c(k + 1, r) + p_k = p[k + 1] + p[k + 1] = p[r] + p[r] = p_k # The top-left 2x2 submatrix (starting at position k,k) is # now our pivot. - E = A[k:k+2,k:k+2] + E = A[k: k + 2, k: k + 2] d.append(E) - C = A[k+2:n,k:k+2] - B = A[k+2:,k+2:] + C = A[k + 2: n, k: k + 2] + B = A[k + 2:, k+2:] # We don't actually need the inverse of E, what we really need # is C*E.inverse(), and that can be found by setting @@ -14279,10 +14297,10 @@ cdef class Matrix(Matrix1): # Compute the Schur complement that we'll work on during # the following iteration, and store it back in the lower- # right-hand corner of "A". - for i in range(n-k-2): - for j in range(i+1): - A.set_unsafe(k+2+i, k+2+j, schur_complement[i,j]) - A.set_unsafe(k+2+j, k+2+i, schur_complement[j,i]) + for i in range(n - k - 2): + for j in range(i + 1): + A.set_unsafe(k + 2 + i, k + 2 + j, schur_complement[i, j]) + A.set_unsafe(k + 2 + j, k + 2 + i, schur_complement[j, i]) # The on- and above-diagonal entries of "L" will be fixed # later, so we only need to worry about the lower-left entry @@ -14293,8 +14311,7 @@ cdef class Matrix(Matrix1): for j in range(2): # Store the new (k and (k+1)st) columns of "L" within # the lower-left-hand corner of "A". - A.set_unsafe(k+i+2, k+j, CE_inverse[i,j]) - + A.set_unsafe(k+i+2, k+j, CE_inverse[i, j]) k += 2 @@ -14303,7 +14320,7 @@ cdef class Matrix(Matrix1): # correctness. A.set_unsafe(i, i, one) - result = (p,A,d) + result = (p, A, d) self.cache(cache_string, result) return result @@ -14608,12 +14625,12 @@ cdef class Matrix(Matrix1): """ cdef Py_ssize_t n # size of the matrices - cdef Py_ssize_t i, j # loop indices - cdef Matrix P,L,D # output matrices + cdef Py_ssize_t i, j # loop indices + cdef Matrix P, L, D # output matrices - p,L,d = self._block_ldlt(classical) + p, L, d = self._block_ldlt(classical) MS = L.matrix_space() - P = MS.matrix(lambda i,j: p[j] == i) + P = MS.matrix(lambda i, j: p[j] == i) # Warning: when n == 0, this works, but returns a matrix # whose (nonexistent) entries are in ZZ rather than in @@ -14626,11 +14643,10 @@ cdef class Matrix(Matrix1): n = L._nrows zero = MS.base_ring().zero() for i in range(n): - for j in range(i+1,n): - L.set_unsafe(i,j,zero) - - return (P,L,D) + for j in range(i + 1, n): + L.set_unsafe(i, j, zero) + return (P, L, D) cdef bint _is_positive_definite_or_semidefinite(self, bint semi) except -1: """ @@ -14640,7 +14656,7 @@ cdef class Matrix(Matrix1): code. The boolean ``semi`` argument exists only to change "greater than zero" into "greater than or equal to zero." """ - from sage.rings.real_lazy import RLF,CLF + from sage.rings.real_lazy import RLF, CLF R = self.base_ring() @@ -14660,10 +14676,10 @@ cdef class Matrix(Matrix1): return False if self._nrows == 0: - return True # vacuously + return True # vacuously cdef list d - _,_,d = self._block_ldlt(False) + _, _, d = self._block_ldlt(False) # Check each 1x1 block for a nonpositive (negative) entry. If # we don't find any, the matrix is positive-(semi)definite. The @@ -14673,8 +14689,7 @@ cdef class Matrix(Matrix1): if semi: op = operator.ge - return all(d_i.nrows() == 1 and op(d_i[0,0], 0) for d_i in d) - + return all(d_i.nrows() == 1 and op(d_i[0, 0], 0) for d_i in d) def is_positive_semidefinite(self): r""" @@ -14986,7 +15001,7 @@ cdef class Matrix(Matrix1): result = self._is_positive_definite_or_semidefinite(False) if certificate: from sage.misc.superseded import deprecation - msg = "the 'certificate' argument is deprecated; if you " + msg = "the 'certificate' argument is deprecated; if you " msg += "need the corresponding factorization, you can " msg += "simply compute it yourself (the results are cached)" deprecation(31619, msg) @@ -14994,7 +15009,7 @@ cdef class Matrix(Matrix1): d = None if result: from sage.modules.free_module_element import vector - _,L,D = self.block_ldlt() + _, L, D = self.block_ldlt() d = vector(D.base_ring(), D.diagonal()) return (result, L, d) else: @@ -15075,7 +15090,7 @@ cdef class Matrix(Matrix1): m2 = hadamard_row_bound_mpfr(A) return min(m1, m2) - def find(self,f, indices=False): + def find(self, f, indices=False): r""" Find elements in this matrix satisfying the constraints in the function `f`. The function is evaluated on each element of @@ -15141,7 +15156,7 @@ cdef class Matrix(Matrix1): True """ from sage.matrix.matrix_space import MatrixSpace - cdef Py_ssize_t size,i,j + cdef Py_ssize_t size, i, j cdef object M if not indices: @@ -15150,20 +15165,20 @@ cdef class Matrix(Matrix1): M = PyList_New(0) for i from 0 <= i < size: - PyList_Append(M,f(PyList_GET_ITEM(L,i))) + PyList_Append(M, f(PyList_GET_ITEM(L, i))) from sage.rings.finite_rings.integer_mod_ring import IntegerModRing return MatrixSpace(IntegerModRing(2), - nrows=self._nrows,ncols=self._ncols).matrix(M) + nrows=self._nrows, ncols=self._ncols).matrix(M) else: # return matrix along with indices in a dictionary d = {} for i from 0 <= i < self._nrows: for j from 0 <= j < self._ncols: - if f(self.get_unsafe(i,j)): - d[(i,j)] = self.get_unsafe(i,j) + if f(self.get_unsafe(i, j)): + d[(i, j)] = self.get_unsafe(i, j) return d @@ -15654,7 +15669,7 @@ cdef class Matrix(Matrix1): """ d = self.smith_form(transformation=False) r = min(self.nrows(), self.ncols()) - return [d[i,i] for i in range(r)] + return [d[i, i] for i in range(r)] def smith_form(self, transformation=True, integral=None, exact=True): r""" @@ -15878,20 +15893,20 @@ cdef class Matrix(Matrix1): raise NotImplementedError("Smith form over non-exact rings not implemented at present") # first clear the first row and column - u,t,v = _smith_onestep(self) + u, t, v = _smith_onestep(self) # now recurse: t now has a nonzero entry at 0,0 and zero entries in the rest # of the 0th row and column, so we apply smith_form to the smaller submatrix - mm = t.submatrix(1,1) + mm = t.submatrix(1, 1) if transformation: dd, uu, vv = mm.smith_form(transformation=True) else: dd = mm.smith_form(transformation=False) mone = self.new_matrix(1, 1, [1]) - d = dd.new_matrix(1,1,[t[0,0]]).block_sum(dd) + d = dd.new_matrix(1, 1, [t[0, 0]]).block_sum(dd) if transformation: - u = uu.new_matrix(1,1,[1]).block_sum(uu) * u - v = v * vv.new_matrix(1,1,[1]).block_sum(vv) + u = uu.new_matrix(1, 1, [1]).block_sum(uu) * u + v = v * vv.new_matrix(1, 1, [1]).block_sum(vv) dp, up, vp = _smith_diag(d, transformation=transformation) if integral is False: dp = dp.change_ring(R) @@ -15972,36 +15987,37 @@ cdef class Matrix(Matrix1): pivot_cols = [] while j < n: k = i - while k < m and A.get_unsafe(k,j).is_zero(): # first nonzero entry + while k < m and A.get_unsafe(k, j).is_zero(): # first nonzero entry k += 1 if k < m: l = k + 1 while l < m: - while l < m and A.get_unsafe(l,j).is_zero(): # nonzero entry below + while l < m and A.get_unsafe(l, j).is_zero(): # nonzero entry below l += 1 - if l >= m: break + if l >= m: + break - a = A.get_unsafe(k,j) - b = A.get_unsafe(l,j) - d,p,q = a.xgcd(b) # p * a + q * b = d = gcd(a,b) + a = A.get_unsafe(k, j) + b = A.get_unsafe(l, j) + d, p, q = a.xgcd(b) # p * a + q * b = d = gcd(a,b) e = a // d f = b // d - for c in range(j,n): - Akc = A.get_unsafe(k,c) - Alc = A.get_unsafe(l,c) + for c in range(j, n): + Akc = A.get_unsafe(k, c) + Alc = A.get_unsafe(l, c) A.set_unsafe(k, c, p * Akc + q * Alc) A.set_unsafe(l, c, (-f) * Akc + e * Alc) if transformation: for c in range(m): - Ukc = U.get_unsafe(k,c) - Ulc = U.get_unsafe(l,c) + Ukc = U.get_unsafe(k, c) + Ulc = U.get_unsafe(l, c) U.set_unsafe(k, c, p * Ukc + q * Ulc) U.set_unsafe(l, c, (-f) * Ukc + e * Ulc) if i != k: - A.swap_rows_c(i,k) + A.swap_rows_c(i, k) if transformation: - U.swap_rows_c(i,k) + U.swap_rows_c(i, k) pivot_cols.append(j) i += 1 j += 1 @@ -16009,26 +16025,26 @@ cdef class Matrix(Matrix1): # reduce entries above pivots for i in range(len(pivot_cols)): j = pivot_cols[i] - pivot = A.get_unsafe(i,j) + pivot = A.get_unsafe(i, j) # possibly normalize the pivot if normalization: coeff = normalization(pivot) - for c in range(j,n): - A.set_unsafe(i, c, A.get_unsafe(i,c) * coeff) + for c in range(j, n): + A.set_unsafe(i, c, A.get_unsafe(i, c) * coeff) if transformation: for c in range(m): - U.set_unsafe(i, c, U.get_unsafe(i,c) * coeff) + U.set_unsafe(i, c, U.get_unsafe(i, c) * coeff) - pivot = A.get_unsafe(i,j) + pivot = A.get_unsafe(i, j) for k in range(i): - q = - (A.get_unsafe(k,j) // pivot) + q = - (A.get_unsafe(k, j) // pivot) if not q.is_zero(): - for c in range(j,n): - A.set_unsafe(k, c, A.get_unsafe(k,c) + q * A.get_unsafe(i,c)) + for c in range(j, n): + A.set_unsafe(k, c, A.get_unsafe(k, c) + q * A.get_unsafe(i, c)) if transformation: for c in range(m): - U.set_unsafe(k, c, U.get_unsafe(k,c) + q * U.get_unsafe(i,c)) + U.set_unsafe(k, c, U.get_unsafe(k, c) + q * U.get_unsafe(i, c)) if transformation: return U @@ -16173,25 +16189,25 @@ cdef class Matrix(Matrix1): return self.new_matrix(self.nrows(), self.nrows(), 1), self, [] else: return self.new_matrix(self.nrows(), self.nrows(), 1), self, [ - self.nonzero_positions_in_row(0)[0] ] + self.nonzero_positions_in_row(0)[0]] R = self.base_ring() # data type checks on R if not R.is_integral_domain(): raise TypeError("Generic echelon form only defined over " - "integral domains") + "integral domains") if not R.is_exact(): raise NotImplementedError("Echelon form over generic non-exact " - "rings not implemented at present") + "rings not implemented at present") left_mat, a = _generic_clear_column(self) assert left_mat * self == a - if a[0,0] != 0: + if a[0, 0] != 0: aa = a.submatrix(1, 1) s, t, pivs = aa._echelon_form_PID() - left_mat = s.new_matrix(1,1,[1]).block_sum(s) * left_mat + left_mat = s.new_matrix(1, 1, [1]).block_sum(s) * left_mat a = left_mat * self pivs = [0] + [x + 1 for x in pivs] @@ -16209,12 +16225,12 @@ cdef class Matrix(Matrix1): I = ideal_or_fractional(R, y) s = a[0][pivs[i]] t = I.small_residue(s) - v = R( (s-t) / y) + v = R((s-t) / y) left_mat.add_multiple_of_row(0, i, -v) a.add_multiple_of_row(0, i, -v) assert left_mat * self == a - except AttributeError: # on I.small_residue + except AttributeError: # on I.small_residue pass return left_mat, a, pivs @@ -16321,7 +16337,7 @@ cdef class Matrix(Matrix1): cdef list corners = [] # zero or one in corner of off-diagonal blocks if basis: from sage.matrix.constructor import identity_matrix - U = identity_matrix(R, n) # transformation matrix + U = identity_matrix(R, n) # transformation matrix # parity switch, True iff working on transpose # if False, mimic row operations only on U # if True, mimic column operations only on U @@ -16334,7 +16350,7 @@ cdef class Matrix(Matrix1): while zigging: # zigging means we are building a block nonzero = -1 for i in range(c+1, n): - if Z.get_unsafe(i,c): + if Z.get_unsafe(i, c): nonzero = i break zigging = (nonzero != -1) @@ -16378,7 +16394,7 @@ cdef class Matrix(Matrix1): # (inclusive), use it to clear entries to the right # but first record polynomial for block just built # this is the full monic polynomial, with correct coefficients - p = [-Z.get_unsafe(i,c) for i in range(s,c+1)] + p = [-Z.get_unsafe(i, c) for i in range(s, c + 1)] p.append(one) polys.append(p) @@ -16394,7 +16410,7 @@ cdef class Matrix(Matrix1): # Effectively: Z.add_multiple_of_row(i, j, scale) for k in range(c+1, n): # Z[i,k] = Z[i,k] + scale*Z[j,k] - Z.set_unsafe(i, k, Z.get_unsafe(i,k)+scale*Z.get_unsafe(j,k)) + Z.set_unsafe(i, k, Z.get_unsafe(i, k) + scale * Z.get_unsafe(j, k)) if basis: if trans: U.add_multiple_of_column(j, i, -scale) @@ -17161,7 +17177,7 @@ cdef class Matrix(Matrix1): companions.append(companion_matrix(poly, format=format)) return block_diagonal_matrix(companions, subdivide=subdivide) - def is_positive_operator_on(self,K1,K2=None): + def is_positive_operator_on(self, K1, K2=None): r""" Determine if this matrix is a positive operator on a cone. @@ -17595,7 +17611,7 @@ cdef class Matrix(Matrix1): """ return (-self).is_cross_positive_on(K) - def is_lyapunov_like_on(self,K): + def is_lyapunov_like_on(self, K): r""" Determine if this matrix is Lyapunov-like on a cone. @@ -17965,35 +17981,35 @@ def _smith_diag(d, transformation=True): else: left = right = None for i in range(n): - I = ideal_or_fractional(R, dp[i,i]) + I = ideal_or_fractional(R, dp[i, i]) if I == ideal_or_fractional(R, 1): - if dp[i,i] != 1: + if dp[i, i] != 1: if transformation: - left.add_multiple_of_row(i,i,R(R(1)/(dp[i,i])) - 1) - dp[i,i] = R(1) + left.add_multiple_of_row(i, i, R(R(1) / (dp[i, i])) - 1) + dp[i, i] = R(1) continue - for j in range(i+1,n): - if dp[j,j] not in I: - t = ideal_or_fractional(R, [dp[i,i], dp[j,j]]).gens_reduced() + for j in range(i + 1, n): + if dp[j, j] not in I: + t = ideal_or_fractional(R, [dp[i, i], dp[j, j]]).gens_reduced() if len(t) > 1: raise ArithmeticError t = t[0] # find lambda, mu such that lambda*d[i,i] + mu*d[j,j] = t - lamb = R(dp[i,i]/t).inverse_mod( ideal_or_fractional(R, dp[j,j]/t)) - mu = R((t - lamb*dp[i,i]) / dp[j,j]) + lamb = R(dp[i, i] / t).inverse_mod(ideal_or_fractional(R, dp[j, j] / t)) + mu = R((t - lamb * dp[i, i]) / dp[j, j]) newlmat = dp.new_matrix(dp.nrows(), dp.nrows(), 1) - newlmat[i,i] = lamb - newlmat[i,j] = 1 - newlmat[j,i] = R(-dp[j,j]*mu/t) - newlmat[j,j] = R(dp[i,i]/t) + newlmat[i, i] = lamb + newlmat[i, j] = 1 + newlmat[j, i] = R(-dp[j, j] * mu / t) + newlmat[j, j] = R(dp[i, i] / t) newrmat = dp.new_matrix(dp.ncols(), dp.ncols(), 1) - newrmat[i,i] = 1 - newrmat[i,j] = R(-dp[j,j]/t) - newrmat[j,i] = mu - newrmat[j,j] = R(lamb*dp[i,i] / t) + newrmat[i, i] = 1 + newrmat[i, j] = R(-dp[j, j] / t) + newrmat[j, i] = mu + newrmat[j, j] = R(lamb * dp[i, i] / t) if transformation: left = newlmat*left @@ -18039,13 +18055,13 @@ def _generic_clear_column(m): k = 0 while a[k, 0] == 0: k += 1 - if k == a.nrows(): # first column is zero + if k == a.nrows(): # first column is zero return left_mat, a # k is now first row such that a[k, 0] is nonzero - left_mat[0,0] = 0 - left_mat[k,k] = 0 - left_mat[0,k] = 1 - left_mat[k,0] = -1 + left_mat[0, 0] = 0 + left_mat[k, k] = 0 + left_mat[0, k] = 1 + left_mat[k, 0] = -1 a = left_mat*a if left_mat * m != a: raise ArithmeticError("Something went wrong") @@ -18059,15 +18075,15 @@ def _generic_clear_column(m): # [e,f] # is invertible over R - I = ideal_or_fractional(R, a[0, 0]) # need to make sure we change this when a[0,0] changes + I = ideal_or_fractional(R, a[0, 0]) # need to make sure we change this when a[0,0] changes for k in range(1, a.nrows()): - if a[k,0] not in I: + if a[k, 0] not in I: try: - v = ideal_or_fractional(R, a[0,0], a[k,0]).gens_reduced() + v = ideal_or_fractional(R, a[0, 0], a[k, 0]).gens_reduced() except Exception as msg: - raise ArithmeticError("%s\nCan't create ideal on %s and %s" % (msg, a[0,0], a[k,0])) + raise ArithmeticError("%s\nCan't create ideal on %s and %s" % (msg, a[0, 0], a[k, 0])) if len(v) > 1: - raise ArithmeticError("Ideal %s not principal" % ideal_or_fractional(R, a[0,0], a[k,0])) + raise ArithmeticError("Ideal %s not principal" % ideal_or_fractional(R, a[0, 0], a[k, 0])) B = v[0] # now we find c,d, using the fact that c * (a_{0,0}/B) - d * @@ -18076,40 +18092,40 @@ def _generic_clear_column(m): # need to handle carefully the case when a_{k,0}/B is a unit, i.e. a_{k,0} divides # a_{0,0}. - c = R(a[0,0] / B).inverse_mod(ideal_or_fractional(R, a[k,0] / B)) - d = R( (c*a[0,0] - B)/(a[k,0]) ) + c = R(a[0, 0] / B).inverse_mod(ideal_or_fractional(R, a[k, 0] / B)) + d = R((c*a[0, 0] - B)/(a[k, 0])) # sanity check - if c*a[0,0] - d*a[k,0] != B: + if c*a[0, 0] - d*a[k, 0] != B: raise ArithmeticError # now we find e,f such that e*d + c*f = 1 in the same way if c != 0: - e = d.inverse_mod( ideal_or_fractional(R, c) ) + e = d.inverse_mod(ideal_or_fractional(R, c)) f = R((1 - d*e)/c) else: - e = R(-a[k,0]/B) # here d is a unit and this is just 1/d + e = R(-a[k, 0] / B) # here d is a unit and this is just 1/d f = R(1) if e*d + c*f != 1: raise ArithmeticError newlmat = left_mat.parent()(1) - newlmat[0,0] = c - newlmat[0,k] = -d - newlmat[k,0] = e - newlmat[k,k] = f + newlmat[0, 0] = c + newlmat[0, k] = -d + newlmat[k, 0] = e + newlmat[k, k] = f if newlmat.det() != 1: raise ArithmeticError a = newlmat*a - I = ideal_or_fractional(R, a[0,0]) + I = ideal_or_fractional(R, a[0, 0]) left_mat = newlmat*left_mat if left_mat * m != a: raise ArithmeticError # now everything in column 0 is divisible by the pivot - for i in range(1,a.nrows()): - s = R( a[i, 0]/a[0, 0]) - a.add_multiple_of_row(i, 0, -s ) + for i in range(1, a.nrows()): + s = R(a[i, 0] / a[0, 0]) + a.add_multiple_of_row(i, 0, -s) left_mat.add_multiple_of_row(i, 0, -s) if left_mat * m != a: raise ArithmeticError @@ -18147,11 +18163,12 @@ def _smith_onestep(m): # preparation: if column 0 is zero, swap it with the first nonzero column j = 0 - while a.column(j) == 0: j += 1 + while a.column(j) == 0: + j += 1 if j > 0: - right_mat[0,0] = right_mat[j,j] = 0 - right_mat[0,j] = 1 - right_mat[j,0] = -1 + right_mat[0, 0] = right_mat[j, j] = 0 + right_mat[0, j] = 1 + right_mat[j, 0] = -1 a = a*right_mat if m * right_mat != a: raise ArithmeticError @@ -18162,15 +18179,15 @@ def _smith_onestep(m): # test if everything to the right of the pivot in row 0 is good as well isdone = True for jj in range(j+1, a.ncols()): - if a[0,jj] != 0: + if a[0, jj] != 0: isdone = False # if not we recurse -- algorithm must terminate if R is Noetherian. if not isdone: - s,t,u = _smith_onestep(a.transpose()) + s, t, u = _smith_onestep(a.transpose()) left_mat = u.transpose() * left_mat a = t.transpose() - right_mat = right_mat* s.transpose() + right_mat = right_mat * s.transpose() return left_mat, a, right_mat @@ -18445,7 +18462,7 @@ def _matrix_power_symbolic(A, n): # Jordan block Jk, its dimension nk, the eigenvalue m Jk = J.subdivision(k, k) nk = Jk.ncols() - mk = Jk[0,0] + mk = Jk[0, 0] # First row of block Mk; its entries are of the form # D^i(f) / i! with f = x^n and D = differentiation wrt x @@ -18492,28 +18509,28 @@ cdef inline bint _block_ldlt_pivot1x1(Matrix A, Py_ssize_t k) except 1: to return zero/one so that ``1`` can be used to indicate that a python exception occurred. """ - cdef Py_ssize_t i,j # dumy loop indices + cdef Py_ssize_t i, j # dumy loop indices cdef Py_ssize_t n = A._nrows - pivot = A.get_unsafe(k,k) + pivot = A.get_unsafe(k, k) # Compute the Schur complement that we'll work on during # the following iteration, and store it back in the lower- # right-hand corner of "A". - for i in range(n-k-1): - for j in range(i+1): - A.set_unsafe(k+1+i, - k+1+j, - ( A.get_unsafe(k+1+i,k+1+j) - - A.get_unsafe(k+1+i,k)*A.get_unsafe(k,k+1+j)/pivot )) - A.set_unsafe(k+1+j, - k+1+i, - A.get_unsafe(k+1+i,k+1+j).conjugate()) + for i in range(n - k - 1): + for j in range(i + 1): + A.set_unsafe(k + 1 + i, + k + 1 + j, + (A.get_unsafe(k + 1 + i, k + 1 + j) - + A.get_unsafe(k + 1 + i, k) * A.get_unsafe(k, k + 1 + j) / pivot)) + A.set_unsafe(k + 1 + j, + k + 1 + i, + A.get_unsafe(k + 1 + i, k + 1 + j).conjugate()) for i in range(n-k-1): # Store the new (kth) column of "L" within the lower- # left-hand corner of "A". - A.set_unsafe(k+i+1, + A.set_unsafe(k + i + 1, k, - A.get_unsafe(k+i+1,k)/ pivot) + A.get_unsafe(k + i + 1, k) / pivot) return 0 diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 6d3168f4995..aba931ad022 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -359,7 +359,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): elif (not isinstance(f, Polynomial)) or (parent is not f.parent()): if isinstance(f, dict): v = min(f) if f else 0 - f = {i-v: c for i,c in f.items()} + f = {i-v: c for i, c in f.items()} n += v f = parent._R(f) @@ -653,19 +653,19 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): elif e == 0: var = "" elif e > 0: - var = "|{}^{{{}}}".format(X,e) + var = "|{}^{{{}}}".format(X, e) if e >= 0: - s += "{}{}".format(x,var) - else: # negative e + s += "{}{}".format(x, var) + else: # negative e if e == -1: s += "\\frac{{{}}}{{{}}}".format(x, X) else: - s += "\\frac{{{}}}{{{}^{{{}}}}}".format(x, X,-e) + s += "\\frac{{{}}}{{{}^{{{}}}}}".format(x, X, -e) first = False s = s.replace(" + -", " - ") - s = s.replace(" 1|"," ") + s = s.replace(" 1|", " ") s = s.replace(" -1|", " -") - s = s.replace("|","") + s = s.replace("|", "") return s[1:] diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index 38f9f7a8ebb..4cf0880880e 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -77,6 +77,8 @@ def is_LaurentPolynomialRing(R): _cache = {} + + def LaurentPolynomialRing(base_ring, *args, **kwds): r""" Return the globally unique univariate or multivariate Laurent polynomial @@ -252,6 +254,7 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): _cache[R] = P return P + def _split_dict_(D, indices, group_by=None): r""" Split the dictionary ``D`` by ``indices`` and ``group_by``. @@ -334,6 +337,7 @@ def extract(T, indices): else: return result + def _split_laurent_polynomial_dict_(P, M, d): r""" Helper function for splitting a multivariate Laurent polynomial @@ -395,6 +399,7 @@ def value(d, R): pass return sum(P({k: 1}) * value(v, P) for k, v in D.items()).dict() + def from_fraction_field(L, x): r""" Helper function to construct a Laurent polynomial from an element of its From 040d9ec01d60e15d99b4726a2fbdd71cb7f2e127 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sat, 23 Sep 2023 22:00:00 +0200 Subject: [PATCH 013/463] change __reduce__ again to avoid further errors --- src/sage/rings/polynomial/laurent_polynomial.pyx | 2 +- src/sage/rings/polynomial/laurent_polynomial_ideal.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index aba931ad022..9a042d526d8 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -379,7 +379,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: loads(dumps(elt)) == elt True """ - return LaurentPolynomial_univariate, (self.__u, self.__n) # eliminate first term in the tuple for the previous definition + return LaurentPolynomial_univariate, (self._parent, self.__u, self.__n) def _polynomial_(self, R): r""" diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index c36c52957cd..b193569d3fa 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -198,7 +198,10 @@ def __contains__(self, f): if not f or f in self.gens(): return True f = self.ring()(f) - g = f.__reduce__()[1][0] + if self.ring().ngens() > 1: + g = f.__reduce__()[1][0] + else: + g = f.__reduce__()[1][1] return (g in self.polynomial_ideal()) # Operations on ideals From 4e9a8bd3727e33cf113b62b0ca61628947ee3f99 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 30 Jul 2023 12:36:05 -0700 Subject: [PATCH 014/463] LatticePolytope: Use experimental method PermutationGroupElement._transpose_left --- src/sage/geometry/lattice_polytope.py | 35 +++++++++---------- .../groups/perm_gps/permgroup_element.pyx | 10 ++++++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 26c7d9a3819..a3d17d6cd51 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -3215,7 +3215,7 @@ def index_of_max(iterable): for j in range(n_v): m = index_of_max(PM[0, i] for i in range(j, n_v)) if m > 0: - permutations[0][1] = S_v((j + 1, m + j + 1), check=False) * permutations[0][1] + permutations[0][1] = permutations[0][1]._transpose_left(j + 1, m + j + 1) first_row = list(PM[0]) # Arrange other rows one by one and compare with first row @@ -3224,7 +3224,7 @@ def index_of_max(iterable): permutations[n_s] = [S_f.one(), S_v.one()] m = index_of_max(PM[k, permutations[n_s][1](j+1) - 1] for j in range(n_v)) if m > 0: - permutations[n_s][1] = S_v((1, m + 1), check=False) * permutations[n_s][1] + permutations[n_s][1] = permutations[n_s][1]._transpose_left(1, m + 1) d = (PM[k, permutations[n_s][1](1) - 1] - permutations[0][1](first_row)[0]) if d < 0: @@ -3235,8 +3235,7 @@ def index_of_max(iterable): for i in range(1, n_v): m = index_of_max(PM[k, permutations[n_s][1](j+1) - 1] for j in range(i,n_v)) if m > 0: - permutations[n_s][1] = S_v((i + 1, m + i + 1), check=False) \ - * permutations[n_s][1] + permutations[n_s][1] = permutations[n_s][1]._transpose_left(i + 1, m + i + 1) if d == 0: d = (PM[k, permutations[n_s][1](i+1) - 1] -permutations[0][1](first_row)[i]) @@ -3246,7 +3245,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] = S_f((1, k + 1), check=False) * permutations[n_s][0] + permutations[n_s][0] = permutations[n_s][0]._transpose_left(1, k + 1) if d == 0: # This row is the same, so we have a symmetry! n_s += 1 @@ -3286,7 +3285,7 @@ def index_of_max(iterable): # number of local permutations associated with current global n_p = 0 ccf = cf - permutations_bar = {0: copy(permutations[k])} + permutations_bar = {0: list(permutations[k])} # We look for the line with the maximal entry in the first # subsymmetry block, i.e. we are allowed to swap elements # between 0 and S(0) @@ -3295,14 +3294,14 @@ def index_of_max(iterable): v0 = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] vj = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](j+1) - 1] if v0 < vj: - permutations_bar[n_p][1] = S_v((1, j + 1), check=False) * permutations_bar[n_p][1] + permutations_bar[n_p][1] = permutations_bar[n_p][1]._transpose_left(1, j + 1) if ccf == 0: l_r[0] = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] if s != l: - permutations_bar[n_p][0] = S_f((l + 1, s + 1), check=False) * permutations_bar[n_p][0] + permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) n_p += 1 ccf = 1 - permutations_bar[n_p] = copy(permutations[k]) + permutations_bar[n_p] = list(permutations[k]) else: d1 = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] d = d1 - l_r[0] @@ -3312,20 +3311,20 @@ def index_of_max(iterable): elif d==0: # Maximal values agree, so possible symmetry if s != l: - permutations_bar[n_p][0] = S_f((l + 1, s + 1), check=False) * permutations_bar[n_p][0] + permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) n_p += 1 - permutations_bar[n_p] = copy(permutations[k]) + permutations_bar[n_p] = list(permutations[k]) else: # We found a greater maximal value for first entry. # It becomes our new reference: l_r[0] = d1 if s != l: - permutations_bar[n_p][0] = S_f((l + 1, s + 1), check=False) * permutations_bar[n_p][0] + permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) # Forget previous work done cf = 0 - permutations_bar = {0:copy(permutations_bar[n_p])} + permutations_bar = {0: list(permutations_bar[n_p])} n_p = 1 - permutations_bar[n_p] = copy(permutations[k]) + permutations_bar[n_p] = list(permutations[k]) n_s = k + 1 # Check if the permutations found just now work # with other elements @@ -3345,7 +3344,7 @@ def index_of_max(iterable): vc = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1] vj = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(j+1) - 1] if (vc < vj): - permutations_bar[s][1] = S_v((c + 1, j + 1), check=False) * permutations_bar[s][1] + permutations_bar[s][1] = permutations_bar[s][1]._transpose_left(c + 1, j + 1) if ccf == 0: # Set reference and carry on to next permutation l_r[c] = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1] @@ -3356,7 +3355,7 @@ def index_of_max(iterable): if d < 0: n_p -= 1 if s < n_p: - permutations_bar[s] = copy(permutations_bar[n_p]) + permutations_bar[s] = list(permutations_bar[n_p]) elif d > 0: # The current case leads to a smaller matrix, # hence this case becomes our new reference @@ -3366,10 +3365,10 @@ def index_of_max(iterable): n_s = k + 1 # Update permutations if (n_s - 1) > k: - permutations[k] = copy(permutations[n_s - 1]) + permutations[k] = list(permutations[n_s - 1]) n_s -= 1 for s in range(n_p): - permutations[n_s] = copy(permutations_bar[s]) + permutations[n_s] = list(permutations_bar[s]) n_s += 1 cf = n_s permutations = {k: permutations[k] for k in permutations if k < n_s} diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index 2522b5c346d..2b36616b27e 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -1298,6 +1298,16 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): return coercion_model.bin_op(left, right, operator.mul) + def _transpose_left(self, j, k): + if j == k: + return self + cdef PermutationGroupElement prod = self._new_c() + cdef int i + for i from 0 <= i < self.n: + prod.perm[i] = self.perm[i] + prod.perm[j - 1], prod.perm[k - 1] = self.perm[k - 1], self.perm[j - 1] + return prod + cpdef _mul_(left, _right): r""" EXAMPLES:: From 684f35968d4c1691c7aaff87e1ac5403ac9cafb2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 2 Aug 2023 20:24:47 -0700 Subject: [PATCH 015/463] sage.geometry.palp_normal_form: Cythonized _palp_PM_max method --- src/sage/geometry/lattice_polytope.py | 200 +------------------ src/sage/geometry/palp_normal_form.pyx | 262 +++++++++++++++++++++++++ 2 files changed, 264 insertions(+), 198 deletions(-) create mode 100644 src/sage/geometry/palp_normal_form.pyx diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index a3d17d6cd51..1ae8504a306 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -3199,204 +3199,8 @@ def _palp_PM_max(self, check=False): sage: all(results) # long time True """ - PM = self.vertex_facet_pairing_matrix() - n_v = PM.ncols() - n_f = PM.nrows() - S_v = SymmetricGroup(n_v) - S_f = SymmetricGroup(n_f) - - # and find all the ways of making the first row of PM_max - def index_of_max(iterable): - # returns the index of max of any iterable - return max(enumerate(iterable), key=lambda x: x[1])[0] - - n_s = 1 - permutations = {0: [S_f.one(), S_v.one()]} - for j in range(n_v): - m = index_of_max(PM[0, i] for i in range(j, n_v)) - if m > 0: - permutations[0][1] = permutations[0][1]._transpose_left(j + 1, m + j + 1) - first_row = list(PM[0]) - - # Arrange other rows one by one and compare with first row - for k in range(1, n_f): - # Error for k == 1 already! - permutations[n_s] = [S_f.one(), S_v.one()] - m = index_of_max(PM[k, permutations[n_s][1](j+1) - 1] for j in range(n_v)) - if m > 0: - permutations[n_s][1] = permutations[n_s][1]._transpose_left(1, m + 1) - d = (PM[k, permutations[n_s][1](1) - 1] - - permutations[0][1](first_row)[0]) - if d < 0: - # The largest elt of this row is smaller than largest elt - # in 1st row, so nothing to do - continue - # otherwise: - for i in range(1, n_v): - m = index_of_max(PM[k, permutations[n_s][1](j+1) - 1] for j in range(i,n_v)) - if m > 0: - permutations[n_s][1] = permutations[n_s][1]._transpose_left(i + 1, m + i + 1) - if d == 0: - d = (PM[k, permutations[n_s][1](i+1) - 1] - -permutations[0][1](first_row)[i]) - if d < 0: - break - if d < 0: - # This row is smaller than 1st row, so nothing to do - del permutations[n_s] - continue - permutations[n_s][0] = permutations[n_s][0]._transpose_left(1, k + 1) - if d == 0: - # This row is the same, so we have a symmetry! - n_s += 1 - else: - # This row is larger, so it becomes the first row and - # the symmetries reset. - first_row = list(PM[k]) - permutations = {0: permutations[n_s]} - n_s = 1 - permutations = {k: permutations[k] for k in permutations if k < n_s} - - b = tuple(PM[permutations[0][0](1) - 1, permutations[0][1](j+1) - 1] for j in range(n_v)) - # Work out the restrictions the current permutations - # place on other permutations as a automorphisms - # of the first row - # The array is such that: - # S = [i, 1, ..., 1 (ith), j, i+1, ..., i+1 (jth), k ... ] - # describes the "symmetry blocks" - S = list(range(1, n_v + 1)) - for i in range(1, n_v): - if b[i-1] == b[i]: - S[i] = S[i-1] - S[S[i]-1] += 1 - else: - S[i] = i + 1 - - # We determine the other rows of PM_max in turn by use of perms and - # aut on previous rows. - for l in range(1, n_f - 1): - n_s = len(permutations) - n_s_bar = n_s - cf = 0 - l_r = [0]*n_v - # Search for possible local permutations based off previous - # global permutations. - for k in range(n_s_bar - 1, -1, -1): - # number of local permutations associated with current global - n_p = 0 - ccf = cf - permutations_bar = {0: list(permutations[k])} - # We look for the line with the maximal entry in the first - # subsymmetry block, i.e. we are allowed to swap elements - # between 0 and S(0) - for s in range(l, n_f): - for j in range(1, S[0]): - v0 = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] - vj = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](j+1) - 1] - if v0 < vj: - permutations_bar[n_p][1] = permutations_bar[n_p][1]._transpose_left(1, j + 1) - if ccf == 0: - l_r[0] = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] - if s != l: - permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) - n_p += 1 - ccf = 1 - permutations_bar[n_p] = list(permutations[k]) - else: - d1 = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] - d = d1 - l_r[0] - if d < 0: - # We move to the next line - continue - elif d==0: - # Maximal values agree, so possible symmetry - if s != l: - permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) - n_p += 1 - permutations_bar[n_p] = list(permutations[k]) - else: - # We found a greater maximal value for first entry. - # It becomes our new reference: - l_r[0] = d1 - if s != l: - permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) - # Forget previous work done - cf = 0 - permutations_bar = {0: list(permutations_bar[n_p])} - n_p = 1 - permutations_bar[n_p] = list(permutations[k]) - n_s = k + 1 - # Check if the permutations found just now work - # with other elements - for c in range(1, n_v): - h = S[c] - ccf = cf - # Now let us find out where the end of the - # next symmetry block is: - if h < c + 1: - h = S[h - 1] - s = n_p - # Check through this block for each possible permutation - while s > 0: - s -= 1 - # Find the largest value in this symmetry block - for j in range(c + 1, h): - vc = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1] - vj = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(j+1) - 1] - if (vc < vj): - permutations_bar[s][1] = permutations_bar[s][1]._transpose_left(c + 1, j + 1) - if ccf == 0: - # Set reference and carry on to next permutation - l_r[c] = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1] - ccf = 1 - else: - d1 = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1] - d = d1 - l_r[c] - if d < 0: - n_p -= 1 - if s < n_p: - permutations_bar[s] = list(permutations_bar[n_p]) - elif d > 0: - # The current case leads to a smaller matrix, - # hence this case becomes our new reference - l_r[c] = d1 - cf = 0 - n_p = s + 1 - n_s = k + 1 - # Update permutations - if (n_s - 1) > k: - permutations[k] = list(permutations[n_s - 1]) - n_s -= 1 - for s in range(n_p): - permutations[n_s] = list(permutations_bar[s]) - n_s += 1 - cf = n_s - permutations = {k: permutations[k] for k in permutations if k < n_s} - # If the automorphisms are not already completely restricted, - # update them - if S != list(range(1, n_v + 1)): - # Take the old automorphisms and update by - # the restrictions the last worked out - # row imposes. - c = 0 - M = tuple(PM[permutations[0][0](l+1) - 1, permutations[0][1](j+1) - 1] for j in range(n_v)) - while c < n_v: - s = S[c] + 1 - S[c] = c + 1 - c += 1 - while c < (s - 1): - if M[c] == M[c - 1]: - S[c] = S[c - 1] - S[S[c] - 1] += 1 - else: - S[c] = c + 1 - c += 1 - # Now we have the perms, we construct PM_max using one of them - PM_max = PM.with_permuted_rows_and_columns(*permutations[0]) - if check: - return (PM_max, permutations) - else: - return PM_max + from .palp_normal_form import _palp_PM_max + return _palp_PM_max(self, check) def npoints(self): r""" diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx new file mode 100644 index 00000000000..77fffa8b761 --- /dev/null +++ b/src/sage/geometry/palp_normal_form.pyx @@ -0,0 +1,262 @@ +from sage.groups.perm_gps.permgroup_named import SymmetricGroup + + +def _palp_PM_max(self, check=False): + r""" + Compute the permutation normal form of the vertex facet pairing + matrix . + + The permutation normal form of a matrix is defined as the lexicographic + maximum under all permutations of its rows and columns. For more + more detail, see also + :meth:`~sage.matrix.matrix2.Matrix.permutation_normal_form`. + + Instead of using the generic method for computing the permutation + normal form, this method uses the PALP algorithm to compute + the permutation normal form and its automorphisms concurrently. + + INPUT: + + - ``check`` -- Boolean (default: ``False``), whether to return + the permutations leaving the maximal vertex-facet pairing + matrix invariant. + + OUTPUT: + + A matrix or a tuple of a matrix and a dict whose values are the + permutation group elements corresponding to the permutations + that permute :meth:`vertices` such that the vertex-facet pairing + matrix is maximal. + + EXAMPLES:: + + sage: o = lattice_polytope.cross_polytope(2) + sage: PM = o.vertex_facet_pairing_matrix() + sage: PM_max = PM.permutation_normal_form() # optional - sage.graphs + sage: PM_max == o._palp_PM_max() # optional - sage.graphs + True + sage: P2 = ReflexivePolytope(2, 0) + sage: PM_max, permutations = P2._palp_PM_max(check=True) + sage: PM_max + [3 0 0] + [0 3 0] + [0 0 3] + sage: list(permutations.values()) + [[(1,2,3), (1,2,3)], + [(1,3,2), (1,3,2)], + [(1,3), (1,3)], + [(1,2), (1,2)], + [(), ()], + [(2,3), (2,3)]] + sage: PM_max.automorphisms_of_rows_and_columns() + [((), ()), + ((1,2,3), (1,2,3)), + ((1,3,2), (1,3,2)), + ((2,3), (2,3)), + ((1,2), (1,2)), + ((1,3), (1,3))] + sage: PMs = ( i._palp_PM_max(check=True) + ....: for i in ReflexivePolytopes(2) ) + sage: results = ( len(i) == len(j.automorphisms_of_rows_and_columns()) + ....: for j, i in PMs ) + sage: all(results) # long time + True + """ + PM = self.vertex_facet_pairing_matrix() + n_v = PM.ncols() + n_f = PM.nrows() + S_v = SymmetricGroup(n_v) + S_f = SymmetricGroup(n_f) + + # and find all the ways of making the first row of PM_max + def index_of_max(iterable): + # returns the index of max of any iterable + return max(enumerate(iterable), key=lambda x: x[1])[0] + + n_s = 1 + permutations = {0: [S_f.one(), S_v.one()]} + for j in range(n_v): + m = index_of_max(PM[0, i] for i in range(j, n_v)) + if m > 0: + permutations[0][1] = permutations[0][1]._transpose_left(j + 1, m + j + 1) + first_row = list(PM[0]) + + # Arrange other rows one by one and compare with first row + for k in range(1, n_f): + # Error for k == 1 already! + permutations[n_s] = [S_f.one(), S_v.one()] + m = index_of_max(PM[k, permutations[n_s][1](j+1) - 1] for j in range(n_v)) + if m > 0: + permutations[n_s][1] = permutations[n_s][1]._transpose_left(1, m + 1) + d = (PM[k, permutations[n_s][1](1) - 1] + - permutations[0][1](first_row)[0]) + if d < 0: + # The largest elt of this row is smaller than largest elt + # in 1st row, so nothing to do + continue + # otherwise: + for i in range(1, n_v): + m = index_of_max(PM[k, permutations[n_s][1](j+1) - 1] for j in range(i,n_v)) + if m > 0: + permutations[n_s][1] = permutations[n_s][1]._transpose_left(i + 1, m + i + 1) + if d == 0: + d = (PM[k, permutations[n_s][1](i+1) - 1] + -permutations[0][1](first_row)[i]) + if d < 0: + break + if d < 0: + # This row is smaller than 1st row, so nothing to do + del permutations[n_s] + continue + permutations[n_s][0] = permutations[n_s][0]._transpose_left(1, k + 1) + if d == 0: + # This row is the same, so we have a symmetry! + n_s += 1 + else: + # This row is larger, so it becomes the first row and + # the symmetries reset. + first_row = list(PM[k]) + permutations = {0: permutations[n_s]} + n_s = 1 + permutations = {k: permutations[k] for k in permutations if k < n_s} + + b = tuple(PM[permutations[0][0](1) - 1, permutations[0][1](j+1) - 1] for j in range(n_v)) + # Work out the restrictions the current permutations + # place on other permutations as a automorphisms + # of the first row + # The array is such that: + # S = [i, 1, ..., 1 (ith), j, i+1, ..., i+1 (jth), k ... ] + # describes the "symmetry blocks" + S = list(range(1, n_v + 1)) + for i in range(1, n_v): + if b[i-1] == b[i]: + S[i] = S[i-1] + S[S[i]-1] += 1 + else: + S[i] = i + 1 + + # We determine the other rows of PM_max in turn by use of perms and + # aut on previous rows. + for l in range(1, n_f - 1): + n_s = len(permutations) + n_s_bar = n_s + cf = 0 + l_r = [0]*n_v + # Search for possible local permutations based off previous + # global permutations. + for k in range(n_s_bar - 1, -1, -1): + # number of local permutations associated with current global + n_p = 0 + ccf = cf + permutations_bar = {0: list(permutations[k])} + # We look for the line with the maximal entry in the first + # subsymmetry block, i.e. we are allowed to swap elements + # between 0 and S(0) + for s in range(l, n_f): + for j in range(1, S[0]): + v0 = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] + vj = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](j+1) - 1] + if v0 < vj: + permutations_bar[n_p][1] = permutations_bar[n_p][1]._transpose_left(1, j + 1) + if ccf == 0: + l_r[0] = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] + if s != l: + permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) + n_p += 1 + ccf = 1 + permutations_bar[n_p] = list(permutations[k]) + else: + d1 = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] + d = d1 - l_r[0] + if d < 0: + # We move to the next line + continue + elif d==0: + # Maximal values agree, so possible symmetry + if s != l: + permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) + n_p += 1 + permutations_bar[n_p] = list(permutations[k]) + else: + # We found a greater maximal value for first entry. + # It becomes our new reference: + l_r[0] = d1 + if s != l: + permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) + # Forget previous work done + cf = 0 + permutations_bar = {0: list(permutations_bar[n_p])} + n_p = 1 + permutations_bar[n_p] = list(permutations[k]) + n_s = k + 1 + # Check if the permutations found just now work + # with other elements + for c in range(1, n_v): + h = S[c] + ccf = cf + # Now let us find out where the end of the + # next symmetry block is: + if h < c + 1: + h = S[h - 1] + s = n_p + # Check through this block for each possible permutation + while s > 0: + s -= 1 + # Find the largest value in this symmetry block + for j in range(c + 1, h): + vc = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1] + vj = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(j+1) - 1] + if (vc < vj): + permutations_bar[s][1] = permutations_bar[s][1]._transpose_left(c + 1, j + 1) + if ccf == 0: + # Set reference and carry on to next permutation + l_r[c] = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1] + ccf = 1 + else: + d1 = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1] + d = d1 - l_r[c] + if d < 0: + n_p -= 1 + if s < n_p: + permutations_bar[s] = list(permutations_bar[n_p]) + elif d > 0: + # The current case leads to a smaller matrix, + # hence this case becomes our new reference + l_r[c] = d1 + cf = 0 + n_p = s + 1 + n_s = k + 1 + # Update permutations + if (n_s - 1) > k: + permutations[k] = list(permutations[n_s - 1]) + n_s -= 1 + for s in range(n_p): + permutations[n_s] = list(permutations_bar[s]) + n_s += 1 + cf = n_s + permutations = {k: permutations[k] for k in permutations if k < n_s} + # If the automorphisms are not already completely restricted, + # update them + if S != list(range(1, n_v + 1)): + # Take the old automorphisms and update by + # the restrictions the last worked out + # row imposes. + c = 0 + M = tuple(PM[permutations[0][0](l+1) - 1, permutations[0][1](j+1) - 1] for j in range(n_v)) + while c < n_v: + s = S[c] + 1 + S[c] = c + 1 + c += 1 + while c < (s - 1): + if M[c] == M[c - 1]: + S[c] = S[c - 1] + S[S[c] - 1] += 1 + else: + S[c] = c + 1 + c += 1 + # Now we have the perms, we construct PM_max using one of them + PM_max = PM.with_permuted_rows_and_columns(*permutations[0]) + if check: + return (PM_max, permutations) + else: + return PM_max From 26c8607cc4d47bc180537fc45401cd38d6e91e2c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 2 Aug 2023 21:06:45 -0700 Subject: [PATCH 016/463] src/sage/geometry/palp_normal_form.pyx: More cythonization --- src/sage/geometry/palp_normal_form.pyx | 78 ++++++++++++++++---------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index 77fffa8b761..ec1a1550e36 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -1,4 +1,6 @@ +from sage.groups.perm_gps.permgroup_element cimport PermutationGroupElement from sage.groups.perm_gps.permgroup_named import SymmetricGroup +from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense def _palp_PM_max(self, check=False): @@ -62,9 +64,9 @@ def _palp_PM_max(self, check=False): sage: all(results) # long time True """ - PM = self.vertex_facet_pairing_matrix() - n_v = PM.ncols() - n_f = PM.nrows() + cdef Matrix_integer_dense PM = self.vertex_facet_pairing_matrix() + cdef int n_v = PM.ncols() + cdef int n_f = PM.nrows() S_v = SymmetricGroup(n_v) S_f = SymmetricGroup(n_f) @@ -73,12 +75,14 @@ def _palp_PM_max(self, check=False): # returns the index of max of any iterable return max(enumerate(iterable), key=lambda x: x[1])[0] - n_s = 1 - permutations = {0: [S_f.one(), S_v.one()]} + cdef int n_s = 1 + cdef dict permutations = {0: [S_f.one(), S_v.one()]} + cdef int j, k, m, d + for j in range(n_v): m = index_of_max(PM[0, i] for i in range(j, n_v)) if m > 0: - permutations[0][1] = permutations[0][1]._transpose_left(j + 1, m + j + 1) + permutations[0][1] = ( permutations[0][1])._transpose_left(j + 1, m + j + 1) first_row = list(PM[0]) # Arrange other rows one by one and compare with first row @@ -87,28 +91,27 @@ def _palp_PM_max(self, check=False): permutations[n_s] = [S_f.one(), S_v.one()] m = index_of_max(PM[k, permutations[n_s][1](j+1) - 1] for j in range(n_v)) if m > 0: - permutations[n_s][1] = permutations[n_s][1]._transpose_left(1, m + 1) - d = (PM[k, permutations[n_s][1](1) - 1] - - permutations[0][1](first_row)[0]) + permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(1, m + 1) + d = PM[k, ( permutations[n_s][1])(1) - 1] - ( permutations[0][1])(first_row)[0] if d < 0: # The largest elt of this row is smaller than largest elt # in 1st row, so nothing to do continue # otherwise: for i in range(1, n_v): - m = index_of_max(PM[k, permutations[n_s][1](j+1) - 1] for j in range(i,n_v)) + m = index_of_max(PM[k, ( permutations[n_s][1](j+1)) - 1] for j in range(i,n_v)) if m > 0: - permutations[n_s][1] = permutations[n_s][1]._transpose_left(i + 1, m + i + 1) + permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(i + 1, m + i + 1) if d == 0: - d = (PM[k, permutations[n_s][1](i+1) - 1] - -permutations[0][1](first_row)[i]) + d = (PM[k, ( permutations[n_s][1])(i+1) - 1] + - ( permutations[0][1])(first_row)[i]) if d < 0: break if d < 0: # This row is smaller than 1st row, so nothing to do del permutations[n_s] continue - permutations[n_s][0] = permutations[n_s][0]._transpose_left(1, k + 1) + permutations[n_s][0] = ( permutations[n_s][0])._transpose_left(1, k + 1) if d == 0: # This row is the same, so we have a symmetry! n_s += 1 @@ -120,14 +123,15 @@ def _palp_PM_max(self, check=False): n_s = 1 permutations = {k: permutations[k] for k in permutations if k < n_s} - b = tuple(PM[permutations[0][0](1) - 1, permutations[0][1](j+1) - 1] for j in range(n_v)) + cdef tuple b = tuple(PM[( permutations[0][0])(1) - 1, + ( permutations[0][1])(j+1) - 1] for j in range(n_v)) # Work out the restrictions the current permutations # place on other permutations as a automorphisms # of the first row # The array is such that: # S = [i, 1, ..., 1 (ith), j, i+1, ..., i+1 (jth), k ... ] # describes the "symmetry blocks" - S = list(range(1, n_v + 1)) + cdef list S = list(range(1, n_v + 1)) for i in range(1, n_v): if b[i-1] == b[i]: S[i] = S[i-1] @@ -135,6 +139,9 @@ def _palp_PM_max(self, check=False): else: S[i] = i + 1 + cdef int l, np, cf, ccf, n_s_bar, d1, v0, vc, vj + cdef list l_r + # We determine the other rows of PM_max in turn by use of perms and # aut on previous rows. for l in range(1, n_f - 1): @@ -154,19 +161,23 @@ def _palp_PM_max(self, check=False): # between 0 and S(0) for s in range(l, n_f): for j in range(1, S[0]): - v0 = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] - vj = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](j+1) - 1] + v0 = PM[( permutations_bar[n_p][0])(s+1) - 1, + ( permutations_bar[n_p][1])(1) - 1] + vj = PM[( permutations_bar[n_p][0])(s+1) - 1, + ( permutations_bar[n_p][1])(j+1) - 1] if v0 < vj: - permutations_bar[n_p][1] = permutations_bar[n_p][1]._transpose_left(1, j + 1) + permutations_bar[n_p][1] = ( permutations_bar[n_p][1])._transpose_left(1, j + 1) if ccf == 0: - l_r[0] = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] + l_r[0] = PM[( permutations_bar[n_p][0])(s+1) - 1, + ( permutations_bar[n_p][1])(1) - 1] if s != l: - permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) + permutations_bar[n_p][0] = ( permutations_bar[n_p][0])._transpose_left(l + 1, s + 1) n_p += 1 ccf = 1 permutations_bar[n_p] = list(permutations[k]) else: - d1 = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1] + d1 = PM[( permutations_bar[n_p][0])(s+1) - 1, + ( permutations_bar[n_p][1])(1) - 1] d = d1 - l_r[0] if d < 0: # We move to the next line @@ -174,7 +185,7 @@ def _palp_PM_max(self, check=False): elif d==0: # Maximal values agree, so possible symmetry if s != l: - permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) + permutations_bar[n_p][0] = ( permutations_bar[n_p][0])._transpose_left(l + 1, s + 1) n_p += 1 permutations_bar[n_p] = list(permutations[k]) else: @@ -182,7 +193,7 @@ def _palp_PM_max(self, check=False): # It becomes our new reference: l_r[0] = d1 if s != l: - permutations_bar[n_p][0] = permutations_bar[n_p][0]._transpose_left(l + 1, s + 1) + permutations_bar[n_p][0] = ( permutations_bar[n_p][0])._transpose_left(l + 1, s + 1) # Forget previous work done cf = 0 permutations_bar = {0: list(permutations_bar[n_p])} @@ -204,16 +215,20 @@ def _palp_PM_max(self, check=False): s -= 1 # Find the largest value in this symmetry block for j in range(c + 1, h): - vc = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1] - vj = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(j+1) - 1] - if (vc < vj): - permutations_bar[s][1] = permutations_bar[s][1]._transpose_left(c + 1, j + 1) + vc = PM[( permutations_bar[s][0])(l+1) - 1, + ( permutations_bar[s][1])(c+1) - 1] + vj = PM[( permutations_bar[s][0])(l+1) - 1, + ( permutations_bar[s][1])(j+1) - 1] + if vc < vj: + permutations_bar[s][1] = ( permutations_bar[s][1])._transpose_left(c + 1, j + 1) if ccf == 0: # Set reference and carry on to next permutation - l_r[c] = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1] + l_r[c] = PM[( permutations_bar[s][0])(l+1) - 1, + ( permutations_bar[s][1])(c+1) - 1] ccf = 1 else: - d1 = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1] + d1 = PM[( permutations_bar[s][0])(l+1) - 1, + ( permutations_bar[s][1])(c+1) - 1] d = d1 - l_r[c] if d < 0: n_p -= 1 @@ -242,7 +257,8 @@ def _palp_PM_max(self, check=False): # the restrictions the last worked out # row imposes. c = 0 - M = tuple(PM[permutations[0][0](l+1) - 1, permutations[0][1](j+1) - 1] for j in range(n_v)) + M = tuple(PM[( permutations[0][0])(l+1) - 1, + ( permutations[0][1])(j+1) - 1] for j in range(n_v)) while c < n_v: s = S[c] + 1 S[c] = c + 1 From e5d593549b16152bb6e439f3e71d426ba4f69b1c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 3 Aug 2023 12:56:17 -0700 Subject: [PATCH 017/463] src/sage/geometry/palp_normal_form.pyx: Cython loop to replace index_of_max --- src/sage/geometry/palp_normal_form.pyx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index ec1a1550e36..27b847535d5 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -78,6 +78,7 @@ def _palp_PM_max(self, check=False): cdef int n_s = 1 cdef dict permutations = {0: [S_f.one(), S_v.one()]} cdef int j, k, m, d + cdef int element, max_element for j in range(n_v): m = index_of_max(PM[0, i] for i in range(j, n_v)) @@ -89,7 +90,7 @@ def _palp_PM_max(self, check=False): for k in range(1, n_f): # Error for k == 1 already! permutations[n_s] = [S_f.one(), S_v.one()] - m = index_of_max(PM[k, permutations[n_s][1](j+1) - 1] for j in range(n_v)) + m = index_of_max(PM[k, ( permutations[n_s][1])(j+1) - 1] for j in range(n_v)) if m > 0: permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(1, m + 1) d = PM[k, ( permutations[n_s][1])(1) - 1] - ( permutations[0][1])(first_row)[0] @@ -99,9 +100,15 @@ def _palp_PM_max(self, check=False): continue # otherwise: for i in range(1, n_v): - m = index_of_max(PM[k, ( permutations[n_s][1](j+1)) - 1] for j in range(i,n_v)) - if m > 0: - permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(i + 1, m + i + 1) + max_element = PM[k, ( permutations[n_s][1](i + 1)) - 1] + m = i + 1 + for j in range(i + 1, n_v): + element = PM[k, ( permutations[n_s][1](j+1)) - 1] + if element > max_element: + max_element = element + m = j + if m > i + 1: + permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(i + 1, m) if d == 0: d = (PM[k, ( permutations[n_s][1])(i+1) - 1] - ( permutations[0][1])(first_row)[i]) From 1425cb13d28b94dbe5e7c912f76eddf556392bd7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 3 Aug 2023 14:12:10 -0700 Subject: [PATCH 018/463] src/sage/geometry/palp_normal_form.pyx: Cython loop to replace index_of_max (fixup) --- src/sage/geometry/palp_normal_form.pyx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index 27b847535d5..dbb37844f1e 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -100,15 +100,15 @@ def _palp_PM_max(self, check=False): continue # otherwise: for i in range(1, n_v): - max_element = PM[k, ( permutations[n_s][1](i + 1)) - 1] - m = i + 1 + max_element = PM[k, ( permutations[n_s][1])(i + 1) - 1] + m = i for j in range(i + 1, n_v): - element = PM[k, ( permutations[n_s][1](j+1)) - 1] + element = PM[k, ( permutations[n_s][1])(j + 1) - 1] if element > max_element: max_element = element m = j - if m > i + 1: - permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(i + 1, m) + if m > i: + permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(i + 1, m + 1) if d == 0: d = (PM[k, ( permutations[n_s][1])(i+1) - 1] - ( permutations[0][1])(first_row)[i]) From 5fba248fa287813384f4c7482595b43e8d1a41fb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 3 Aug 2023 16:01:31 -0700 Subject: [PATCH 019/463] src/sage/geometry/palp_normal_form.pyx: Do not keep first_row as a list --- src/sage/geometry/palp_normal_form.pyx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index dbb37844f1e..e97f12c6dc5 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -84,7 +84,8 @@ def _palp_PM_max(self, check=False): m = index_of_max(PM[0, i] for i in range(j, n_v)) if m > 0: permutations[0][1] = ( permutations[0][1])._transpose_left(j + 1, m + j + 1) - first_row = list(PM[0]) + + cdef first_row_index = 0 # Arrange other rows one by one and compare with first row for k in range(1, n_f): @@ -93,7 +94,8 @@ def _palp_PM_max(self, check=False): m = index_of_max(PM[k, ( permutations[n_s][1])(j+1) - 1] for j in range(n_v)) if m > 0: permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(1, m + 1) - d = PM[k, ( permutations[n_s][1])(1) - 1] - ( permutations[0][1])(first_row)[0] + d = (PM[k, ( permutations[n_s][1])(1) - 1] + - PM[first_row_index, ( permutations[0][1])(1) - 1]) if d < 0: # The largest elt of this row is smaller than largest elt # in 1st row, so nothing to do @@ -111,7 +113,7 @@ def _palp_PM_max(self, check=False): permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(i + 1, m + 1) if d == 0: d = (PM[k, ( permutations[n_s][1])(i+1) - 1] - - ( permutations[0][1])(first_row)[i]) + - PM[first_row_index, ( permutations[0][1])(i + 1) - 1]) if d < 0: break if d < 0: @@ -125,7 +127,7 @@ def _palp_PM_max(self, check=False): else: # This row is larger, so it becomes the first row and # the symmetries reset. - first_row = list(PM[k]) + first_row_index = k permutations = {0: permutations[n_s]} n_s = 1 permutations = {k: permutations[k] for k in permutations if k < n_s} From 524c37c767ff501c3bd3485c729be4180489cb02 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 3 Aug 2023 17:38:02 -0700 Subject: [PATCH 020/463] src/sage/geometry/palp_normal_form.pyx: Replace another use of index_of_max --- src/sage/geometry/palp_normal_form.pyx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index e97f12c6dc5..e772cb9455c 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -91,7 +91,13 @@ def _palp_PM_max(self, check=False): for k in range(1, n_f): # Error for k == 1 already! permutations[n_s] = [S_f.one(), S_v.one()] - m = index_of_max(PM[k, ( permutations[n_s][1])(j+1) - 1] for j in range(n_v)) + max_element = PM[k, ( permutations[n_s][1])(1) - 1] + m = 0 + for j in range(1, n_v): + element = PM[k, ( permutations[n_s][1])(j + 1) - 1] + if element > max_element: + max_element = element + m = j if m > 0: permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(1, m + 1) d = (PM[k, ( permutations[n_s][1])(1) - 1] From 011f6989bb74a75968fede4880d46f9f78d25f14 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 3 Aug 2023 17:38:42 -0700 Subject: [PATCH 021/463] src/sage/groups/perm_gps/permgroup_element.pxd: Add cpdef --- src/sage/groups/perm_gps/permgroup_element.pxd | 1 + src/sage/groups/perm_gps/permgroup_element.pyx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/groups/perm_gps/permgroup_element.pxd b/src/sage/groups/perm_gps/permgroup_element.pxd index 0a584745f96..b013451d5a0 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pxd +++ b/src/sage/groups/perm_gps/permgroup_element.pxd @@ -18,6 +18,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): cpdef _set_permutation_group_element(self, PermutationGroupElement p, bint convert) cpdef _mul_(self, other) + cpdef PermutationGroupElement _transpose_left(self, int j, int k) cpdef PermutationGroupElement _generate_new(self, list new_list) cpdef PermutationGroupElement _generate_new_GAP(self, old) cpdef _gap_list(self) diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index 2b36616b27e..d64c01efce8 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -1298,7 +1298,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): return coercion_model.bin_op(left, right, operator.mul) - def _transpose_left(self, j, k): + cpdef PermutationGroupElement _transpose_left(self, int j, int k): if j == k: return self cdef PermutationGroupElement prod = self._new_c() From b15c25fb8c2fe59435e8c1be277320d5e697f6ad Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 3 Aug 2023 23:03:24 -0700 Subject: [PATCH 022/463] src/sage/geometry/palp_normal_form.pyx: Faster access to elements of PM --- src/sage/geometry/palp_normal_form.pyx | 58 +++++++++++++------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index e772cb9455c..54dd7239391 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -91,35 +91,35 @@ def _palp_PM_max(self, check=False): for k in range(1, n_f): # Error for k == 1 already! permutations[n_s] = [S_f.one(), S_v.one()] - max_element = PM[k, ( permutations[n_s][1])(1) - 1] + max_element = PM.get_unsafe_int(k, ( permutations[n_s][1])(1) - 1) m = 0 for j in range(1, n_v): - element = PM[k, ( permutations[n_s][1])(j + 1) - 1] + element = PM.get_unsafe_int(k, ( permutations[n_s][1])(j + 1) - 1) if element > max_element: max_element = element m = j if m > 0: permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(1, m + 1) - d = (PM[k, ( permutations[n_s][1])(1) - 1] - - PM[first_row_index, ( permutations[0][1])(1) - 1]) + d = (PM.get_unsafe_int(k, ( permutations[n_s][1])(1) - 1) + - PM.get_unsafe_int(first_row_index, ( permutations[0][1])(1) - 1)) if d < 0: # The largest elt of this row is smaller than largest elt # in 1st row, so nothing to do continue # otherwise: for i in range(1, n_v): - max_element = PM[k, ( permutations[n_s][1])(i + 1) - 1] + max_element = PM.get_unsafe_int(k, ( permutations[n_s][1])(i + 1) - 1) m = i for j in range(i + 1, n_v): - element = PM[k, ( permutations[n_s][1])(j + 1) - 1] + element = PM.get_unsafe_int(k, ( permutations[n_s][1])(j + 1) - 1) if element > max_element: max_element = element m = j if m > i: permutations[n_s][1] = ( permutations[n_s][1])._transpose_left(i + 1, m + 1) if d == 0: - d = (PM[k, ( permutations[n_s][1])(i+1) - 1] - - PM[first_row_index, ( permutations[0][1])(i + 1) - 1]) + d = (PM.get_unsafe_int(k, ( permutations[n_s][1])(i+1) - 1) + - PM.get_unsafe_int(first_row_index, ( permutations[0][1])(i + 1) - 1)) if d < 0: break if d < 0: @@ -138,8 +138,9 @@ def _palp_PM_max(self, check=False): n_s = 1 permutations = {k: permutations[k] for k in permutations if k < n_s} - cdef tuple b = tuple(PM[( permutations[0][0])(1) - 1, - ( permutations[0][1])(j+1) - 1] for j in range(n_v)) + cdef tuple b = tuple(PM.get_unsafe_int(( permutations[0][0])(1) - 1, + ( permutations[0][1])(j+1) - 1) + for j in range(n_v)) # Work out the restrictions the current permutations # place on other permutations as a automorphisms # of the first row @@ -176,23 +177,23 @@ def _palp_PM_max(self, check=False): # between 0 and S(0) for s in range(l, n_f): for j in range(1, S[0]): - v0 = PM[( permutations_bar[n_p][0])(s+1) - 1, - ( permutations_bar[n_p][1])(1) - 1] - vj = PM[( permutations_bar[n_p][0])(s+1) - 1, - ( permutations_bar[n_p][1])(j+1) - 1] + v0 = PM.get_unsafe_int(( permutations_bar[n_p][0])(s+1) - 1, + ( permutations_bar[n_p][1])(1) - 1) + vj = PM.get_unsafe_int(( permutations_bar[n_p][0])(s+1) - 1, + ( permutations_bar[n_p][1])(j+1) - 1) if v0 < vj: permutations_bar[n_p][1] = ( permutations_bar[n_p][1])._transpose_left(1, j + 1) if ccf == 0: - l_r[0] = PM[( permutations_bar[n_p][0])(s+1) - 1, - ( permutations_bar[n_p][1])(1) - 1] + l_r[0] = PM.get_unsafe_int(( permutations_bar[n_p][0])(s+1) - 1, + ( permutations_bar[n_p][1])(1) - 1) if s != l: permutations_bar[n_p][0] = ( permutations_bar[n_p][0])._transpose_left(l + 1, s + 1) n_p += 1 ccf = 1 permutations_bar[n_p] = list(permutations[k]) else: - d1 = PM[( permutations_bar[n_p][0])(s+1) - 1, - ( permutations_bar[n_p][1])(1) - 1] + d1 = PM.get_unsafe_int(( permutations_bar[n_p][0])(s+1) - 1, + ( permutations_bar[n_p][1])(1) - 1) d = d1 - l_r[0] if d < 0: # We move to the next line @@ -230,20 +231,20 @@ def _palp_PM_max(self, check=False): s -= 1 # Find the largest value in this symmetry block for j in range(c + 1, h): - vc = PM[( permutations_bar[s][0])(l+1) - 1, - ( permutations_bar[s][1])(c+1) - 1] - vj = PM[( permutations_bar[s][0])(l+1) - 1, - ( permutations_bar[s][1])(j+1) - 1] + vc = PM.get_unsafe_int(( permutations_bar[s][0])(l+1) - 1, + ( permutations_bar[s][1])(c+1) - 1) + vj = PM.get_unsafe_int(( permutations_bar[s][0])(l+1) - 1, + ( permutations_bar[s][1])(j+1) - 1) if vc < vj: permutations_bar[s][1] = ( permutations_bar[s][1])._transpose_left(c + 1, j + 1) if ccf == 0: # Set reference and carry on to next permutation - l_r[c] = PM[( permutations_bar[s][0])(l+1) - 1, - ( permutations_bar[s][1])(c+1) - 1] + l_r[c] = PM.get_unsafe_int(( permutations_bar[s][0])(l+1) - 1, + ( permutations_bar[s][1])(c+1) - 1) ccf = 1 else: - d1 = PM[( permutations_bar[s][0])(l+1) - 1, - ( permutations_bar[s][1])(c+1) - 1] + d1 = PM.get_unsafe_int(( permutations_bar[s][0])(l+1) - 1, + ( permutations_bar[s][1])(c+1) - 1) d = d1 - l_r[c] if d < 0: n_p -= 1 @@ -272,8 +273,9 @@ def _palp_PM_max(self, check=False): # the restrictions the last worked out # row imposes. c = 0 - M = tuple(PM[( permutations[0][0])(l+1) - 1, - ( permutations[0][1])(j+1) - 1] for j in range(n_v)) + M = tuple(PM.get_unsafe_int(( permutations[0][0])(l+1) - 1, + ( permutations[0][1])(j+1) - 1) + for j in range(n_v)) while c < n_v: s = S[c] + 1 S[c] = c + 1 From 9ba1cd85ab58873dae431aa98f284c1c124f9754 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 4 Aug 2023 21:22:07 -0700 Subject: [PATCH 023/463] sage.geometry.palp_normal_form: Add _palp_canonical_order, factored out from .lattice_polytope --- src/sage/geometry/lattice_polytope.py | 38 ++++---------- src/sage/geometry/palp_normal_form.pyx | 70 +++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 29 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 1ae8504a306..cd14c9d0ca6 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -3155,8 +3155,8 @@ def _palp_PM_max(self, check=False): INPUT: - ``check`` -- Boolean (default: ``False``), whether to return - the permutations leaving the maximal vertex-facet pairing - matrix invariant. + the permutations leaving the maximal vertex-facet pairing + matrix invariant. OUTPUT: @@ -3200,7 +3200,7 @@ def _palp_PM_max(self, check=False): True """ from .palp_normal_form import _palp_PM_max - return _palp_PM_max(self, check) + return _palp_PM_max(self.vertex_facet_pairing_matrix(), check) def npoints(self): r""" @@ -4978,12 +4978,13 @@ def _palp_canonical_order(V, PM_max, permutations): - ``PM_max`` -- the maximal vertex-facet pairing matrix - - ``permutation`` -- the permutations of the vertices yielding + - ``permutations`` -- the permutations of the vertices yielding ``PM_max``. OUTPUT: - The PALP normal form as a :class:`point collection `. + The PALP normal form as a :class:`point collection ` + and a permutation. TESTS:: @@ -4998,32 +4999,15 @@ def _palp_canonical_order(V, PM_max, permutations): M(-1, 0) in 2-d lattice M, (1,3,2,4)) """ - n_v = PM_max.ncols() - S_v = SymmetricGroup(n_v) - p_c = S_v.one() - M_max = [max(row[j] for row in PM_max.rows()) for j in range(n_v)] - S_max = sum(PM_max) - for i in range(n_v): - k = i - for j in range(i + 1, n_v): - if M_max[j] < M_max[k] or \ - (M_max[j] == M_max[k] and S_max[j] < S_max[k]): - k = j - if not k == i: - M_max[i], M_max[k] = M_max[k], M_max[i] - S_max[i], S_max[k] = S_max[k], S_max[i] - p_c = S_v((1 + i, 1 + k), check=False) * p_c - # Create array of possible NFs. - permutations = [p_c * l[1] for l in permutations.values()] + from .palp_normal_form import _palp_canonical_order + Vmatrix = V.column_matrix() - Vs = [(Vmatrix.with_permuted_columns(sig).hermite_form(), sig) - for sig in permutations] - Vmin = min(Vs, key=lambda x:x[0]) Vmodule = V.module() - vertices = [Vmodule(_) for _ in Vmin[0].columns()] + vertices, permutation = _palp_canonical_order(Vmatrix, PM_max, permutations) + vertices = [Vmodule(v) for v in vertices] for v in vertices: v.set_immutable() - return (PointCollection(vertices, Vmodule), Vmin[1]) + return PointCollection(vertices, Vmodule), permutation def _palp_convert_permutation(permutation): diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index 54dd7239391..e5efacb6d27 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -1,9 +1,11 @@ from sage.groups.perm_gps.permgroup_element cimport PermutationGroupElement from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense +from sage.matrix.special import column_matrix +from sage.structure.element import Matrix -def _palp_PM_max(self, check=False): +def _palp_PM_max(Matrix_integer_dense PM, check=False): r""" Compute the permutation normal form of the vertex facet pairing matrix . @@ -64,7 +66,6 @@ def _palp_PM_max(self, check=False): sage: all(results) # long time True """ - cdef Matrix_integer_dense PM = self.vertex_facet_pairing_matrix() cdef int n_v = PM.ncols() cdef int n_f = PM.nrows() S_v = SymmetricGroup(n_v) @@ -293,3 +294,68 @@ def _palp_PM_max(self, check=False): return (PM_max, permutations) else: return PM_max + + +def _palp_canonical_order(vertices, PM_max, permutations): + r""" + Compute the PALP normal form of vertices of a lattice polytope + using auxiliary data computed elsewhere. + + This is a helper function for + :meth:`~sage.geometry.lattice_polytope.LatticePolytopeClass.normal_form` + and should not be called directly. + + Given an iterable of vertices, the maximal vertex-facet pairing matrix + and the permutations realizing this matrix, apply the last part of the + PALP algorithm and return the normal form. + + INPUT: + + - ``vertices`` -- iterable of iterables. The vertices. + + - ``PM_max`` -- the maximal vertex-facet pairing matrix + + - ``permutation`` -- the permutations of the vertices yielding ``PM_max``. + + OUTPUT: + + The PALP normal form as an iterable of integer vectors. + + TESTS:: + + sage: L = lattice_polytope.cross_polytope(2) + sage: V = L.vertices() + sage: PM_max, permutations = L._palp_PM_max(check=True) # optional - sage.groups + sage: from sage.geometry.lattice_polytope import _palp_canonical_order + sage: _palp_canonical_order(V, PM_max, permutations) # optional - sage.groups + (M( 1, 0), + M( 0, 1), + M( 0, -1), + M(-1, 0) + in 2-d lattice M, (1,3,2,4)) + """ + n_v = PM_max.ncols() + S_v = SymmetricGroup(n_v) + p_c = S_v.one() + M_max = [max(row[j] for row in PM_max.rows()) for j in range(n_v)] + S_max = sum(PM_max) + for i in range(n_v): + k = i + for j in range(i + 1, n_v): + if M_max[j] < M_max[k] or \ + (M_max[j] == M_max[k] and S_max[j] < S_max[k]): + k = j + if not k == i: + M_max[i], M_max[k] = M_max[k], M_max[i] + S_max[i], S_max[k] = S_max[k], S_max[i] + p_c = S_v((1 + i, 1 + k), check=False) * p_c + # Create array of possible NFs. + permutations = [p_c * l[1] for l in permutations.values()] + if isinstance(vertices, Matrix): + Vmatrix = vertices + else: + Vmatrix = column_matrix(vertices) + Vs = [(Vmatrix.with_permuted_columns(sig).hermite_form(), sig) + for sig in permutations] + Vmin = min(Vs, key=lambda x: x[0]) + return Vmin[0].columns(), Vmin[1] From a47701b6374e9c894bee01f008267e7af213e3f4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 4 Aug 2023 21:43:44 -0700 Subject: [PATCH 024/463] Polyhedron_ZZ.normal_form: New --- src/sage/geometry/lattice_polytope.py | 2 +- src/sage/geometry/polyhedron/base_ZZ.py | 38 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index cd14c9d0ca6..fd1bc168bb1 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -5024,7 +5024,7 @@ def _palp_convert_permutation(permutation): OUTPUT: - A :class:`permutation group element `. + A :class:`permutation group element `. EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/base_ZZ.py b/src/sage/geometry/polyhedron/base_ZZ.py index 561ed76d70c..f40b88b284b 100644 --- a/src/sage/geometry/polyhedron/base_ZZ.py +++ b/src/sage/geometry/polyhedron/base_ZZ.py @@ -834,3 +834,41 @@ def is_known_summand(poly): decompositions.append((X, Y)) summands += [X, Y] return tuple(decompositions) + + def normal_form(self, algorithm="palp_native", permutation=False): + r""" + EXAMPLES: + + We compute the normal form of the "diamond":: + + sage: d = Polyhedron([(1,0), (0,1), (-1,0), (0,-1)]) + sage: d.vertices() + (A vertex at (-1, 0), + A vertex at (0, -1), + A vertex at (0, 1), + A vertex at (1, 0)) + sage: d.normal_form() + [(1, 0), (0, 1), (0, -1), (-1, 0)] + + It is not possible to compute normal forms for polytopes which do not + span the space:: + + sage: p = Polyhedron([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)]) + sage: p.normal_form() + Traceback (most recent call last): + ... + ValueError: normal form is not defined for A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices + """ + from sage.geometry.palp_normal_form import _palp_PM_max, _palp_canonical_order + + if self.dim() < self.ambient_dim(): + raise ValueError("normal form is not defined for %s" % self) + + PM = self.slack_matrix().transpose() + PM_max, permutations = _palp_PM_max(PM, check=True) + out = _palp_canonical_order(self.vertices(), PM_max, permutations) + + if permutation: + return out + else: + return out[0] From 3411205c29962fac2b1ec7a126157a28bd368cb9 Mon Sep 17 00:00:00 2001 From: Luze Xu Date: Tue, 22 Aug 2023 17:50:32 -0700 Subject: [PATCH 025/463] fix bug --- src/sage/geometry/palp_normal_form.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index e5efacb6d27..1dae6e70e1e 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -82,7 +82,7 @@ def _palp_PM_max(Matrix_integer_dense PM, check=False): cdef int element, max_element for j in range(n_v): - m = index_of_max(PM[0, i] for i in range(j, n_v)) + m = index_of_max(PM.get_unsafe_int(0, ( permutations[0][1])(i + 1) - 1) for i in range(j, n_v)) if m > 0: permutations[0][1] = ( permutations[0][1])._transpose_left(j + 1, m + j + 1) From 88ebcf72d3aec71219d55be1687734dd1442066d Mon Sep 17 00:00:00 2001 From: Luze Xu Date: Tue, 22 Aug 2023 18:13:09 -0700 Subject: [PATCH 026/463] add the example --- src/sage/geometry/lattice_polytope.py | 7 +++++++ src/sage/geometry/palp_normal_form.pyx | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index fd1bc168bb1..0138f50a2b3 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -3198,6 +3198,13 @@ def _palp_PM_max(self, check=False): ....: for j, i in PMs ) sage: all(results) # long time True + sage: P = Polyhedron([(-4,-6),(-4,-5),(0,0),(1,0),(5,6)]) + sage: P.lattice_polytope()._palp_PM_max() + [9 5 4 0 0] + [6 0 6 5 0] + [1 5 0 0 4] + [0 6 0 1 6] + [0 0 3 5 3] """ from .palp_normal_form import _palp_PM_max return _palp_PM_max(self.vertex_facet_pairing_matrix(), check) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index 1dae6e70e1e..d2ffb05c8e1 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -65,6 +65,18 @@ def _palp_PM_max(Matrix_integer_dense PM, check=False): ....: for j, i in PMs ) sage: all(results) # long time True + sage: from sage.geometry.palp_normal_form import _palp_PM_max, _palp_canonical_order + sage: P = Polyhedron([(-4,-6),(-4,-5),(0,0),(1,0),(5,6)]) + sage: PM = P.slack_matrix().transpose() + sage: _palp_PM_max(PM) + [9 5 4 0 0] + [6 0 6 5 0] + [1 5 0 0 4] + [0 6 0 1 6] + [0 0 3 5 3] + sage: PM_max, permutations = _palp_PM_max(PM, check=True) + sage: _palp_canonical_order(P.vertices(), PM_max, permutations) + ([(1, 0), (0, 0), (2, 4), (1, 5), (-1, 1)], (1,2,3)) """ cdef int n_v = PM.ncols() cdef int n_f = PM.nrows() From 996191cc1c0d3677169cb8bd4d68bd3f7b380767 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 12:33:48 -0700 Subject: [PATCH 027/463] Put new tests in TESTS sections --- src/sage/geometry/lattice_polytope.py | 9 +++++++-- src/sage/geometry/palp_normal_form.pyx | 5 +++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 0138f50a2b3..fc33c78a15f 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -3198,8 +3198,13 @@ def _palp_PM_max(self, check=False): ....: for j, i in PMs ) sage: all(results) # long time True - sage: P = Polyhedron([(-4,-6),(-4,-5),(0,0),(1,0),(5,6)]) - sage: P.lattice_polytope()._palp_PM_max() + + TESTS: + + Check that a bug introduced in :issue:`35997` is fixed:: + + sage: P = LatticePolytope([(-4,-6),(-4,-5),(0,0),(1,0),(5,6)]) + sage: P._palp_PM_max() [9 5 4 0 0] [6 0 6 5 0] [1 5 0 0 4] diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index d2ffb05c8e1..a08a9166831 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -65,6 +65,11 @@ def _palp_PM_max(Matrix_integer_dense PM, check=False): ....: for j, i in PMs ) sage: all(results) # long time True + + TESTS: + + Check that a bug introduced in :issue:`35997` is fixed:: + sage: from sage.geometry.palp_normal_form import _palp_PM_max, _palp_canonical_order sage: P = Polyhedron([(-4,-6),(-4,-5),(0,0),(1,0),(5,6)]) sage: PM = P.slack_matrix().transpose() From d6e433f4eb676110199dd2ffc5639925f35667cc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 12:58:30 -0700 Subject: [PATCH 028/463] src/sage/geometry/lattice_polytope.py: Update copyright --- src/sage/geometry/lattice_polytope.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index fc33c78a15f..5d4b0a45a41 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -93,8 +93,27 @@ """ # **************************************************************************** -# Copyright (C) 2007-2013 Andrey Novoseltsev -# Copyright (C) 2007-2013 William Stein +# Copyright (C) 2007-2017 Andrey Novoseltsev +# 2007-2013 William Stein +# 2009 Mike Hansen +# 2009-2020 John H. Palmieri +# 2010-2014 Volker Braun +# 2012 Samuel Gonshaw +# 2013 Jan Keitel +# 2014 André Apitzsch +# 2014 Wilfried Luebbe +# 2015-2022 Frédéric Chapoton +# 2015 Ursula Whitcher +# 2016 Jori Mäntysalo +# 2017 Travis Scrimshaw +# 2018 Christian Stump +# 2018 Vincent Klein +# 2019 Vincent Delecroix +# 2019 Jonathan Kliem +# 2020 Samuel Lelièvre +# 2021-2023 Matthias Koeppe +# 2022 David Coudert +# 2023 Luze Xu # # 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 From e241607216a5a0e4f5f7b2d10995ae3ca31acaed Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 12:58:49 -0700 Subject: [PATCH 029/463] src/sage/geometry/palp_normal_form.pyx: Add copyright --- src/sage/geometry/palp_normal_form.pyx | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index a08a9166831..6eca2a56b9b 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -1,3 +1,24 @@ +r""" +PALP normal form of vertices of a lattice polytope +""" +# **************************************************************************** +# Copyright (C) 2013 Jan Keitel +# 2014 Volker Braun +# 2018 Christian Stump +# 2019 Vincent Delecroix +# 2019 Jonathan Kliem +# 2021 Michael Orlitzky +# 2018-2022 Frédéric Chapoton +# 2023 Luze Xu +# 2023 Matthias Koeppe +# +# 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 sage.groups.perm_gps.permgroup_element cimport PermutationGroupElement from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense @@ -7,8 +28,7 @@ from sage.structure.element import Matrix def _palp_PM_max(Matrix_integer_dense PM, check=False): r""" - Compute the permutation normal form of the vertex facet pairing - matrix . + Compute the permutation normal form of the vertex facet pairing matrix. The permutation normal form of a matrix is defined as the lexicographic maximum under all permutations of its rows and columns. For more From 6f8769be8e3c3c499d9ef42e20b896c7eaf34435 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 12 Aug 2023 13:18:33 -0700 Subject: [PATCH 030/463] src/sage/geometry/palp_normal_form.pyx: One more use of _transpose_left --- src/sage/geometry/palp_normal_form.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index 6eca2a56b9b..92bbd9a362d 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -385,7 +385,7 @@ def _palp_canonical_order(vertices, PM_max, permutations): if not k == i: M_max[i], M_max[k] = M_max[k], M_max[i] S_max[i], S_max[k] = S_max[k], S_max[i] - p_c = S_v((1 + i, 1 + k), check=False) * p_c + p_c = p_c._transpose_left(1 + i, 1 + k) # Create array of possible NFs. permutations = [p_c * l[1] for l in permutations.values()] if isinstance(vertices, Matrix): From 48348b5a490069825df3fdc9f9c649ab902ff26d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 13:41:34 -0700 Subject: [PATCH 031/463] src/sage/geometry/palp_normal_form.pyx: Update # needs --- src/sage/geometry/palp_normal_form.pyx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index 92bbd9a362d..212e7736023 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.groups r""" PALP normal form of vertices of a lattice polytope """ @@ -56,8 +57,8 @@ def _palp_PM_max(Matrix_integer_dense PM, check=False): sage: o = lattice_polytope.cross_polytope(2) sage: PM = o.vertex_facet_pairing_matrix() - sage: PM_max = PM.permutation_normal_form() # optional - sage.graphs - sage: PM_max == o._palp_PM_max() # optional - sage.graphs + sage: PM_max = PM.permutation_normal_form() + sage: PM_max == o._palp_PM_max() True sage: P2 = ReflexivePolytope(2, 0) sage: PM_max, permutations = P2._palp_PM_max(check=True) @@ -362,9 +363,9 @@ def _palp_canonical_order(vertices, PM_max, permutations): sage: L = lattice_polytope.cross_polytope(2) sage: V = L.vertices() - sage: PM_max, permutations = L._palp_PM_max(check=True) # optional - sage.groups + sage: PM_max, permutations = L._palp_PM_max(check=True) sage: from sage.geometry.lattice_polytope import _palp_canonical_order - sage: _palp_canonical_order(V, PM_max, permutations) # optional - sage.groups + sage: _palp_canonical_order(V, PM_max, permutations) (M( 1, 0), M( 0, 1), M( 0, -1), From 63abe415a738385c65400fa4d9783298a8035ce0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 15:51:43 -0700 Subject: [PATCH 032/463] PermutationGroupElement._transpose_left: Generalize --- .../groups/perm_gps/permgroup_element.pxd | 2 +- .../groups/perm_gps/permgroup_element.pyx | 25 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/sage/groups/perm_gps/permgroup_element.pxd b/src/sage/groups/perm_gps/permgroup_element.pxd index b013451d5a0..21b509f06d1 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pxd +++ b/src/sage/groups/perm_gps/permgroup_element.pxd @@ -18,7 +18,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): cpdef _set_permutation_group_element(self, PermutationGroupElement p, bint convert) cpdef _mul_(self, other) - cpdef PermutationGroupElement _transpose_left(self, int j, int k) + cpdef PermutationGroupElement _transpose_left(self, j, k) cpdef PermutationGroupElement _generate_new(self, list new_list) cpdef PermutationGroupElement _generate_new_GAP(self, old) cpdef _gap_list(self) diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index d64c01efce8..f25db93010f 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -1298,13 +1298,36 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): return coercion_model.bin_op(left, right, operator.mul) - cpdef PermutationGroupElement _transpose_left(self, int j, int k): + cpdef PermutationGroupElement _transpose_left(self, j, k): + r""" + Return the product of the transposition `(j, k)` with ``self``. + + EXAMPLES:: + + sage: S = SymmetricGroup(5) + sage: s = S([5, 2, 4, 3, 1]) + sage: s._transpose_left(2, 3) + (1,5)(2,4,3) + sage: S((2, 3)) * s + (1,5)(2,4,3) + + sage: S = SymmetricGroup(["a", "b", "c", "d", "e"]) + sage: s = S(["e", "b", "d", "c", "a"]) + sage: s._transpose_left("b", "c") + ('a','e')('b','d','c') + sage: S(("b", "c")) * s + ('a','e')('b','d','c') + """ if j == k: return self cdef PermutationGroupElement prod = self._new_c() cdef int i for i from 0 <= i < self.n: prod.perm[i] = self.perm[i] + if not self._parent._has_natural_domain(): + convert_dict = self._parent._domain_to_gap + j = convert_dict[j] + k = convert_dict[k] prod.perm[j - 1], prod.perm[k - 1] = self.perm[k - 1], self.perm[j - 1] return prod From 38da660c064a64ef1aa09b7c085d1a46ac105f81 Mon Sep 17 00:00:00 2001 From: Luze Xu Date: Wed, 23 Aug 2023 14:08:38 -0700 Subject: [PATCH 033/463] remove index_of_max --- src/sage/geometry/palp_normal_form.pyx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index 212e7736023..fad9f968c06 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -109,18 +109,19 @@ def _palp_PM_max(Matrix_integer_dense PM, check=False): S_v = SymmetricGroup(n_v) S_f = SymmetricGroup(n_f) - # and find all the ways of making the first row of PM_max - def index_of_max(iterable): - # returns the index of max of any iterable - return max(enumerate(iterable), key=lambda x: x[1])[0] - cdef int n_s = 1 cdef dict permutations = {0: [S_f.one(), S_v.one()]} cdef int j, k, m, d cdef int element, max_element for j in range(n_v): - m = index_of_max(PM.get_unsafe_int(0, ( permutations[0][1])(i + 1) - 1) for i in range(j, n_v)) + max_element = PM.get_unsafe_int(0, ( permutations[0][1])(j + 1) - 1) + m = 0 + for i in range(j + 1, n_v): + element = PM.get_unsafe_int(0, ( permutations[0][1])(i + 1) - 1) + if element > max_element: + max_element = element + m = i - j if m > 0: permutations[0][1] = ( permutations[0][1])._transpose_left(j + 1, m + j + 1) From e5025aea8fc425abdd2570e3c9195a79a6d79414 Mon Sep 17 00:00:00 2001 From: Luze Xu Date: Tue, 5 Sep 2023 10:38:59 -0700 Subject: [PATCH 034/463] crash example --- src/sage/geometry/lattice_polytope.py | 63 +++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 5d4b0a45a41..4e30dbd242f 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -3032,6 +3032,69 @@ def normal_form(self, algorithm="palp", permutation=False): M( 0, -1), M(-1, 0) in 2-d lattice M + + Note that the default algorithm may crash for higher dimensions:: + + sage: P = LatticePolytope([[-3, -3, -6, -6, -1], [3, 3, 6, 6, 1], [-3, -3, -6, -6, 1], + ....: [-3, -3, -3, -6, 0], [-3, -3, -3, 0, 0], [-3, -3, 0, 0, 0], + ....: [-3, 0, -6, -6, 0], [-3, 0, -3, -6, 0], [-3, 0, -3, 0, 0], + ....: [-3, 0, 0, 0, -1], [3, 3, 6, 6, -1], [-3, 0, 0, 0, 1], + ....: [0, -3, -6, -6, 0], [0, -3, -3, -6, 0], [0, -3, -3, 0, 0], + ....: [0, -3, 0, 0, -1], [3, 3, 3, 6, 0], [0, -3, 0, 0, 1], + ....: [0, 0, -6, -6, 0], [0, 0, -3, -6, -1], [3, 3, 3, 0, 0], + ....: [0, 0, -3, -6, 1], [0, 0, -3, 0, -1], [3, 3, 0, 0, 0], + ....: [0, 0, -3, 0, 1], [0, 0, 3, 0, -1], [3, 0, 6, 6, 0], + ....: [0, 0, 3, 0, 1], [0, 0, 3, 6, -1], [3, 0, 3, 6, 0], + ....: [0, 0, 3, 6, 1], [0, 0, 6, 6, 0], [0, 3, 0, 0, -1], + ....: [3, 0, 3, 0, 0], [0, 3, 0, 0, 1], [0, 3, 3, 0, 0], + ....: [0, 3, 3, 6, 0], [0, 3, 6, 6, 0], [3, 0,0, 0, -1], [3, 0, 0, 0, 1]]) + sage: P.normal_form(algorithm="palp") + Traceback (most recent call last): + ... + Output: + b'*** stack smashing detected ***: terminated\nAborted\n' + sage: P.normal_form(algorithm="palp_native") + M( 6, 0, 0, 0, 0), + M( -6, 0, 0, 0, 0), + M( 0, 1, 0, 0, 0), + M( 0, 0, 3, 0, 0), + M( 0, 1, 0, 3, 0), + M( 0, 0, 0, 0, 3), + M( -6, 1, 6, 3, -6), + M( -6, 0, 6, 0, -3), + M(-12, 1, 6, 3, -3), + M( -6, 1, 0, 3, 0), + M( -6, 0, 3, 3, 0), + M( 6, 0, -6, -3, 6), + M(-12, 1, 6, 3, -6), + M(-12, 0, 9, 3, -6), + M( 0, 0, 0, -3, 0), + M(-12, 1, 6, 6, -6), + M(-12, 0, 6, 3, -3), + M( 0, 1, -3, 0, 0), + M( 0, 0, -3, -3, 3), + M( 0, 1, 0, 3, -3), + M( 0, -1, 0, -3, 3), + M( 0, 0, 3, 3, -3), + M( 0, -1, 3, 0, 0), + M( 12, 0, -6, -3, 3), + M( 12, -1, -6, -6, 6), + M( 0, 0, 0, 3, 0), + M( 12, 0, -9, -3, 6), + M( 12, -1, -6, -3, 6), + M( -6, 0, 6, 3, -6), + M( 6, 0, -3, -3, 0), + M( 6, -1, 0, -3, 0), + M(-12, 1, 9, 6, -6), + M( 6, 0, -6, 0, 3), + M( 6, -1, -6, -3, 6), + M( 0, 0, 0, 0, -3), + M( 0, -1, 0, -3, 0), + M( 0, 0, -3, 0, 0), + M( 0, -1, 0, 0, 0), + M( 12, -1, -9, -6, 6), + M( 12, -1, -6, -3, 3) + in 5-d lattice M """ if self.dim() < self.lattice_dim(): raise ValueError("normal form is not defined for %s" % self) From 4e06ea90547c481546092b680ed83d250498df3d Mon Sep 17 00:00:00 2001 From: Luze Xu Date: Tue, 5 Sep 2023 17:18:59 -0700 Subject: [PATCH 035/463] speed tests for palp_native --- src/sage/geometry/lattice_polytope.py | 96 ++++++++++++++++++++++++- src/sage/geometry/polyhedron/base_ZZ.py | 10 +++ 2 files changed, 103 insertions(+), 3 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 4e30dbd242f..4f7e21c4df2 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -2950,10 +2950,11 @@ def normal_form(self, algorithm="palp", permutation=False): - ``algorithm`` -- (default: "palp") The algorithm which is used to compute the normal form. Options are: - * "palp" -- Run external PALP code, usually the fastest option. + * "palp" -- Run external PALP code, usually the fastest option, + but may fail in higher dimensions. * "palp_native" -- The original PALP algorithm implemented - in sage. Currently considerably slower than PALP. + in sage. Currently competitive with PALP in many cases. * "palp_modified" -- A modified version of the PALP algorithm which determines the maximal vertex-facet @@ -3033,7 +3034,49 @@ def normal_form(self, algorithm="palp", permutation=False): M(-1, 0) in 2-d lattice M - Note that the default algorithm may crash for higher dimensions:: + The following examples demonstrate the speed improvement of ``"palp_native"``. + In low dimensions, ``"palp_native"`` is the fastest. + As the dimension increases, ``"palp"`` is relatively faster than ``"palp_native"``. + ``"palp_native"`` is usually much faster than ``"palp_modified"``. + But in some cases when the polytope has high symmetry, however, ``"palp_native"`` is slower:: + + sage: o = lattice_polytope.cross_polytope(2) + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") # not tested + 625 loops, best of 3: 3.07 ms per loop + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") # not tested + 625 loops, best of 3: 0.445 ms per loop + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") # not tested + 625 loops, best of 3: 5.01 ms per loop + + sage: o = lattice_polytope.cross_polytope(3) + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") # not tested + 625 loops, best of 3: 3.22 ms per loop + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") # not tested + 625 loops, best of 3: 2.73 ms per loop + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") # not tested + 625 loops, best of 3: 20.7 ms per loop + + sage: o = lattice_polytope.cross_polytope(4) + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") # not tested + 625 loops, best of 3: 4.84 ms per loop + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") # not tested + 625 loops, best of 3: 55.6 ms per loop + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") # not tested + 625 loops, best of 3: 129 ms per loop + + sage: o = lattice_polytope.cross_polytope(5) + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") # not tested + 10 loops, best of 3: 0.0364 s per loop + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") # not tested + 10 loops, best of 3: 1.68 s per loop + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") # not tested + 10 loops, best of 3: 0.858 s per loop + + Note that the default algorithm ``"palp"`` may crash for higher dimensions because of + the overflow errors as mentioned in :issue:`13525#comment:9`. + Then use ``"palp_native"`` instead, which is usually faster than ``"palp_modified"``. + Below is an example where ``"palp"`` fails, and + ``"palp_native"`` is much faster than ``"palp_modified"``:: sage: P = LatticePolytope([[-3, -3, -6, -6, -1], [3, 3, 6, 6, 1], [-3, -3, -6, -6, 1], ....: [-3, -3, -3, -6, 0], [-3, -3, -3, 0, 0], [-3, -3, 0, 0, 0], @@ -3051,6 +3094,7 @@ def normal_form(self, algorithm="palp", permutation=False): sage: P.normal_form(algorithm="palp") Traceback (most recent call last): ... + RuntimeError: Error executing ... for a polytope sequence! Output: b'*** stack smashing detected ***: terminated\nAborted\n' sage: P.normal_form(algorithm="palp_native") @@ -3095,6 +3139,52 @@ def normal_form(self, algorithm="palp", permutation=False): M( 12, -1, -9, -6, 6), M( 12, -1, -6, -3, 3) in 5-d lattice M + sage: P.normal_form(algorithm="palp_modified") + M( 6, 0, 0, 0, 0), + M( -6, 0, 0, 0, 0), + M( 0, 1, 0, 0, 0), + M( 0, 0, 3, 0, 0), + M( 0, 1, 0, 3, 0), + M( 0, 0, 0, 0, 3), + M( -6, 1, 6, 3, -6), + M( -6, 0, 6, 0, -3), + M(-12, 1, 6, 3, -3), + M( -6, 1, 0, 3, 0), + M( -6, 0, 3, 3, 0), + M( 6, 0, -6, -3, 6), + M(-12, 1, 6, 3, -6), + M(-12, 0, 9, 3, -6), + M( 0, 0, 0, -3, 0), + M(-12, 1, 6, 6, -6), + M(-12, 0, 6, 3, -3), + M( 0, 1, -3, 0, 0), + M( 0, 0, -3, -3, 3), + M( 0, 1, 0, 3, -3), + M( 0, -1, 0, -3, 3), + M( 0, 0, 3, 3, -3), + M( 0, -1, 3, 0, 0), + M( 12, 0, -6, -3, 3), + M( 12, -1, -6, -6, 6), + M( 0, 0, 0, 3, 0), + M( 12, 0, -9, -3, 6), + M( 12, -1, -6, -3, 6), + M( -6, 0, 6, 3, -6), + M( 6, 0, -3, -3, 0), + M( 6, -1, 0, -3, 0), + M(-12, 1, 9, 6, -6), + M( 6, 0, -6, 0, 3), + M( 6, -1, -6, -3, 6), + M( 0, 0, 0, 0, -3), + M( 0, -1, 0, -3, 0), + M( 0, 0, -3, 0, 0), + M( 0, -1, 0, 0, 0), + M( 12, -1, -9, -6, 6), + M( 12, -1, -6, -3, 3) + in 5-d lattice M + sage: %timeit P.normal_form.clear_cache(); P.normal_form("palp_native") # not tested + 10 loops, best of 3: 0.137 s per loop + sage: %timeit P.normal_form.clear_cache(); P.normal_form("palp_modified") # not tested + 10 loops, best of 3: 22.2 s per loop """ if self.dim() < self.lattice_dim(): raise ValueError("normal form is not defined for %s" % self) diff --git a/src/sage/geometry/polyhedron/base_ZZ.py b/src/sage/geometry/polyhedron/base_ZZ.py index f40b88b284b..9ce438105f5 100644 --- a/src/sage/geometry/polyhedron/base_ZZ.py +++ b/src/sage/geometry/polyhedron/base_ZZ.py @@ -837,6 +837,10 @@ def is_known_summand(poly): def normal_form(self, algorithm="palp_native", permutation=False): r""" + Return the normal form of vertices of ``self`` if ``self`` is a lattice polytope, + i.e. all vertices have integer coordinates. For more more detail, + see also :meth:`~sage.geometry.lattice_polytope.LatticePolytopeClass.normal_form`. + EXAMPLES: We compute the normal form of the "diamond":: @@ -849,6 +853,12 @@ def normal_form(self, algorithm="palp_native", permutation=False): A vertex at (1, 0)) sage: d.normal_form() [(1, 0), (0, 1), (0, -1), (-1, 0)] + sage: d.lattice_polytope().normal_form("palp_native") + M( 1, 0), + M( 0, 1), + M( 0, -1), + M(-1, 0) + in 2-d lattice M It is not possible to compute normal forms for polytopes which do not span the space:: From 137c8482020819346985d15a8227d10ae53c27fd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 7 Sep 2023 11:06:32 -0700 Subject: [PATCH 036/463] Polyhedron_ZZ.normal_form: Reject unbounded polyhedra --- src/sage/geometry/polyhedron/base_ZZ.py | 26 ++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/sage/geometry/polyhedron/base_ZZ.py b/src/sage/geometry/polyhedron/base_ZZ.py index 9ce438105f5..0a41dc9371a 100644 --- a/src/sage/geometry/polyhedron/base_ZZ.py +++ b/src/sage/geometry/polyhedron/base_ZZ.py @@ -837,9 +837,10 @@ def is_known_summand(poly): def normal_form(self, algorithm="palp_native", permutation=False): r""" - Return the normal form of vertices of ``self`` if ``self`` is a lattice polytope, - i.e. all vertices have integer coordinates. For more more detail, - see also :meth:`~sage.geometry.lattice_polytope.LatticePolytopeClass.normal_form`. + Return the normal form of vertices of the lattice polytope ``self``. + + For more more detail, + see :meth:`~sage.geometry.lattice_polytope.LatticePolytopeClass.normal_form`. EXAMPLES: @@ -867,12 +868,27 @@ def normal_form(self, algorithm="palp_native", permutation=False): sage: p.normal_form() Traceback (most recent call last): ... - ValueError: normal form is not defined for A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices + ValueError: normal form is not defined for lower-dimensional polyhedra, got + A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices + + The normal form is also not defined for unbounded polyhedra:: + + sage: p = Polyhedron(vertices=[[1, 1]], rays=[[1, 0], [0, 1]], base_ring=ZZ) + sage: p.normal_form() + Traceback (most recent call last): + ... + ValueError: normal form is not defined for unbounded polyhedra, got + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex and 2 rays + + See :issue:`15280` for proposed extensions to these cases. """ from sage.geometry.palp_normal_form import _palp_PM_max, _palp_canonical_order if self.dim() < self.ambient_dim(): - raise ValueError("normal form is not defined for %s" % self) + raise ValueError("normal form is not defined for lower-dimensional polyhedra, got %s" % self) + + if not self.is_compact(): + raise ValueError("normal form is not defined for unbounded polyhedra, got %s" % self) PM = self.slack_matrix().transpose() PM_max, permutations = _palp_PM_max(PM, check=True) From 26c89cfb17a3d2e1bef63a3c99e8ef74d3f28ee8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 7 Sep 2023 11:28:57 -0700 Subject: [PATCH 037/463] Docstring/doctest cosmetics --- src/sage/geometry/lattice_polytope.py | 52 +++++++++++++------------- src/sage/geometry/palp_normal_form.pyx | 12 +++--- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 4f7e21c4df2..a6c53e03f2d 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -2519,7 +2519,7 @@ def index(self): M(-1, 0) in 2-d lattice M - But they are in the same `GL(Z^n)` orbit and have the same + But they are in the same `GL(\ZZ^n)` orbit and have the same normal form:: sage: d.normal_form() # needs palp @@ -2937,26 +2937,26 @@ def normal_form(self, algorithm="palp", permutation=False): Return the normal form of vertices of ``self``. Two full-dimensional lattice polytopes are in the same - ``GL(\ZZ)``-orbit if and only if their normal forms are the + `GL(\ZZ^n)`-orbit if and only if their normal forms are the same. Normal form is not defined and thus cannot be used for polytopes whose dimension is smaller than the dimension of the ambient space. The original algorithm was presented in [KS1998]_ and implemented in PALP. A modified version of the PALP algorithm is discussed in - [GK2013]_ and available here as "palp_modified". + [GK2013]_ and available here as ``"palp_modified"``. INPUT: - - ``algorithm`` -- (default: "palp") The algorithm which is used + - ``algorithm`` -- (default: ``"palp"``) The algorithm which is used to compute the normal form. Options are: - * "palp" -- Run external PALP code, usually the fastest option, + * ``"palp"`` -- Run external PALP code, usually the fastest option, but may fail in higher dimensions. - * "palp_native" -- The original PALP algorithm implemented + * ``"palp_native"`` -- The original PALP algorithm implemented in sage. Currently competitive with PALP in many cases. - * "palp_modified" -- A modified version of the PALP + * ``"palp_modified"`` -- A modified version of the PALP algorithm which determines the maximal vertex-facet pairing matrix first and then computes its automorphisms, while the PALP algorithm does both things @@ -3040,42 +3040,40 @@ def normal_form(self, algorithm="palp", permutation=False): ``"palp_native"`` is usually much faster than ``"palp_modified"``. But in some cases when the polytope has high symmetry, however, ``"palp_native"`` is slower:: + sage: # not tested sage: o = lattice_polytope.cross_polytope(2) - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") 625 loops, best of 3: 3.07 ms per loop - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") 625 loops, best of 3: 0.445 ms per loop - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") 625 loops, best of 3: 5.01 ms per loop - sage: o = lattice_polytope.cross_polytope(3) - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") 625 loops, best of 3: 3.22 ms per loop - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") 625 loops, best of 3: 2.73 ms per loop - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") 625 loops, best of 3: 20.7 ms per loop - sage: o = lattice_polytope.cross_polytope(4) - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") 625 loops, best of 3: 4.84 ms per loop - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") 625 loops, best of 3: 55.6 ms per loop - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") 625 loops, best of 3: 129 ms per loop - sage: o = lattice_polytope.cross_polytope(5) - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp") 10 loops, best of 3: 0.0364 s per loop - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_native") 10 loops, best of 3: 1.68 s per loop - sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") # not tested + sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") 10 loops, best of 3: 0.858 s per loop Note that the default algorithm ``"palp"`` may crash for higher dimensions because of the overflow errors as mentioned in :issue:`13525#comment:9`. Then use ``"palp_native"`` instead, which is usually faster than ``"palp_modified"``. - Below is an example where ``"palp"`` fails, and + Below is an example where ``"palp"`` fails and ``"palp_native"`` is much faster than ``"palp_modified"``:: sage: P = LatticePolytope([[-3, -3, -6, -6, -1], [3, 3, 6, 6, 1], [-3, -3, -6, -6, 1], @@ -3091,7 +3089,7 @@ def normal_form(self, algorithm="palp", permutation=False): ....: [0, 0, 3, 6, 1], [0, 0, 6, 6, 0], [0, 3, 0, 0, -1], ....: [3, 0, 3, 0, 0], [0, 3, 0, 0, 1], [0, 3, 3, 0, 0], ....: [0, 3, 3, 6, 0], [0, 3, 6, 6, 0], [3, 0,0, 0, -1], [3, 0, 0, 0, 1]]) - sage: P.normal_form(algorithm="palp") + sage: P.normal_form(algorithm="palp") # not tested Traceback (most recent call last): ... RuntimeError: Error executing ... for a polytope sequence! @@ -3139,7 +3137,7 @@ def normal_form(self, algorithm="palp", permutation=False): M( 12, -1, -9, -6, 6), M( 12, -1, -6, -3, 3) in 5-d lattice M - sage: P.normal_form(algorithm="palp_modified") + sage: P.normal_form(algorithm="palp_modified") # long time (22s) M( 6, 0, 0, 0, 0), M( -6, 0, 0, 0, 0), M( 0, 1, 0, 0, 0), @@ -3181,9 +3179,9 @@ def normal_form(self, algorithm="palp", permutation=False): M( 12, -1, -9, -6, 6), M( 12, -1, -6, -3, 3) in 5-d lattice M - sage: %timeit P.normal_form.clear_cache(); P.normal_form("palp_native") # not tested + sage: %timeit P.normal_form.clear_cache(); P.normal_form("palp_native") # not tested 10 loops, best of 3: 0.137 s per loop - sage: %timeit P.normal_form.clear_cache(); P.normal_form("palp_modified") # not tested + sage: %timeit P.normal_form.clear_cache(); P.normal_form("palp_modified") # not tested 10 loops, best of 3: 22.2 s per loop """ if self.dim() < self.lattice_dim(): diff --git a/src/sage/geometry/palp_normal_form.pyx b/src/sage/geometry/palp_normal_form.pyx index fad9f968c06..fa756fe65b0 100644 --- a/src/sage/geometry/palp_normal_form.pyx +++ b/src/sage/geometry/palp_normal_form.pyx @@ -43,8 +43,8 @@ def _palp_PM_max(Matrix_integer_dense PM, check=False): INPUT: - ``check`` -- Boolean (default: ``False``), whether to return - the permutations leaving the maximal vertex-facet pairing - matrix invariant. + the permutations leaving the maximal vertex-facet pairing + matrix invariant. OUTPUT: @@ -80,10 +80,10 @@ def _palp_PM_max(Matrix_integer_dense PM, check=False): ((2,3), (2,3)), ((1,2), (1,2)), ((1,3), (1,3))] - sage: PMs = ( i._palp_PM_max(check=True) - ....: for i in ReflexivePolytopes(2) ) - sage: results = ( len(i) == len(j.automorphisms_of_rows_and_columns()) - ....: for j, i in PMs ) + sage: PMs = (i._palp_PM_max(check=True) + ....: for i in ReflexivePolytopes(2)) + sage: results = (len(i) == len(j.automorphisms_of_rows_and_columns()) + ....: for j, i in PMs) sage: all(results) # long time True From 7759c528fd989fcd1004ba5f9acf613e8fde77d0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 7 Sep 2023 11:40:45 -0700 Subject: [PATCH 038/463] Polyhedron_ZZ.normal_form: Add doc --- src/sage/geometry/polyhedron/base_ZZ.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/geometry/polyhedron/base_ZZ.py b/src/sage/geometry/polyhedron/base_ZZ.py index 0a41dc9371a..06b93aea513 100644 --- a/src/sage/geometry/polyhedron/base_ZZ.py +++ b/src/sage/geometry/polyhedron/base_ZZ.py @@ -839,6 +839,13 @@ def normal_form(self, algorithm="palp_native", permutation=False): r""" Return the normal form of vertices of the lattice polytope ``self``. + INPUT: + + - ``algorithm`` -- must be ``"palp_native"``, the default. + + - ``permutation`` -- boolean (default: ``False``); if ``True``, the permutation + applied to vertices to obtain the normal form is returned as well. + For more more detail, see :meth:`~sage.geometry.lattice_polytope.LatticePolytopeClass.normal_form`. @@ -884,6 +891,9 @@ def normal_form(self, algorithm="palp_native", permutation=False): """ from sage.geometry.palp_normal_form import _palp_PM_max, _palp_canonical_order + if algorithm != "palp_native": + raise ValueError("algorithm must be 'palp_native'") + if self.dim() < self.ambient_dim(): raise ValueError("normal form is not defined for lower-dimensional polyhedra, got %s" % self) From ea4d8571ca257417e612429c61540175b7fe15f3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 7 Sep 2023 11:41:37 -0700 Subject: [PATCH 039/463] LatticePolytope.normal_form: Change the default to algorithm='palp_native' --- src/sage/geometry/lattice_polytope.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index a6c53e03f2d..f7306d5b3ff 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -2932,7 +2932,7 @@ def nfacets(self): return len(self.facet_normals()) if self.dim() > 0 else 0 @cached_method - def normal_form(self, algorithm="palp", permutation=False): + def normal_form(self, algorithm="palp_native", permutation=False): r""" Return the normal form of vertices of ``self``. @@ -2947,11 +2947,12 @@ def normal_form(self, algorithm="palp", permutation=False): INPUT: - - ``algorithm`` -- (default: ``"palp"``) The algorithm which is used + - ``algorithm`` -- (default: ``"palp_native"``) The algorithm which is used to compute the normal form. Options are: - * ``"palp"`` -- Run external PALP code, usually the fastest option, - but may fail in higher dimensions. + * ``"palp"`` -- Run external PALP code, usually the fastest option + when it works; but reproducible crashes have been observed in dimension + 5 and higher. * ``"palp_native"`` -- The original PALP algorithm implemented in sage. Currently competitive with PALP in many cases. @@ -2962,7 +2963,7 @@ def normal_form(self, algorithm="palp", permutation=False): automorphisms, while the PALP algorithm does both things concurrently. - - ``permutation`` -- (default: ``False``) If ``True`` the permutation + - ``permutation`` -- boolean (default: ``False``); if ``True``, the permutation applied to vertices to obtain the normal form is returned as well. Note that the different algorithms may return different results that nevertheless lead to the same normal form. @@ -2983,7 +2984,7 @@ def normal_form(self, algorithm="palp", permutation=False): M(-1, 0), M( 0, -1) in 2-d lattice M - sage: d.normal_form() # needs palp + sage: d.normal_form() M( 1, 0), M( 0, 1), M( 0, -1), @@ -3034,11 +3035,11 @@ def normal_form(self, algorithm="palp", permutation=False): M(-1, 0) in 2-d lattice M - The following examples demonstrate the speed improvement of ``"palp_native"``. - In low dimensions, ``"palp_native"`` is the fastest. + The following examples demonstrate the speed of the available algorithms. + In low dimensions, the default algorithm, ``"palp_native"``, is the fastest. As the dimension increases, ``"palp"`` is relatively faster than ``"palp_native"``. ``"palp_native"`` is usually much faster than ``"palp_modified"``. - But in some cases when the polytope has high symmetry, however, ``"palp_native"`` is slower:: + In some cases when the polytope has high symmetry, however, ``"palp_native"`` is slower:: sage: # not tested sage: o = lattice_polytope.cross_polytope(2) @@ -3070,7 +3071,7 @@ def normal_form(self, algorithm="palp", permutation=False): sage: %timeit o.normal_form.clear_cache(); o.normal_form("palp_modified") 10 loops, best of 3: 0.858 s per loop - Note that the default algorithm ``"palp"`` may crash for higher dimensions because of + Note that the algorithm ``"palp"`` may crash for higher dimensions because of the overflow errors as mentioned in :issue:`13525#comment:9`. Then use ``"palp_native"`` instead, which is usually faster than ``"palp_modified"``. Below is an example where ``"palp"`` fails and @@ -3195,8 +3196,7 @@ def normal_form(self, algorithm="palp", permutation=False): elif algorithm == "palp_modified": result = self._palp_modified_normal_form(permutation=permutation) else: - raise ValueError('Algorithm must be palp, ' + - 'palp_native, or palp_modified.') + raise ValueError("algorithm must be 'palp', 'palp_native', or 'palp_modified'") if permutation: vertices, perm = result else: @@ -3219,7 +3219,7 @@ def _palp_modified_normal_form(self, permutation=False): INPUT: - - ``permutation`` -- a Boolean, whether to return the permutation of + - ``permutation`` -- boolean (default: ``False``); whether to return the permutation of the order of the vertices that was applied to obtain this matrix. OUTPUT: From 05f82288e41141de58454f3f68474fa8ab8f99eb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 7 Sep 2023 11:45:14 -0700 Subject: [PATCH 040/463] Add # needs sage.groups --- src/sage/geometry/lattice_polytope.py | 6 +++--- src/sage/geometry/polyhedron/base_ZZ.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index f7306d5b3ff..c7dffd27341 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -2984,7 +2984,7 @@ def normal_form(self, algorithm="palp_native", permutation=False): M(-1, 0), M( 0, -1) in 2-d lattice M - sage: d.normal_form() + sage: d.normal_form() # needs sage.groups M( 1, 0), M( 0, 1), M( 0, -1), @@ -3096,7 +3096,7 @@ def normal_form(self, algorithm="palp_native", permutation=False): RuntimeError: Error executing ... for a polytope sequence! Output: b'*** stack smashing detected ***: terminated\nAborted\n' - sage: P.normal_form(algorithm="palp_native") + sage: P.normal_form(algorithm="palp_native") # needs sage.groups M( 6, 0, 0, 0, 0), M( -6, 0, 0, 0, 0), M( 0, 1, 0, 0, 0), @@ -3138,7 +3138,7 @@ def normal_form(self, algorithm="palp_native", permutation=False): M( 12, -1, -9, -6, 6), M( 12, -1, -6, -3, 3) in 5-d lattice M - sage: P.normal_form(algorithm="palp_modified") # long time (22s) + sage: P.normal_form(algorithm="palp_modified") # long time (22s) # needs sage.groups M( 6, 0, 0, 0, 0), M( -6, 0, 0, 0, 0), M( 0, 1, 0, 0, 0), diff --git a/src/sage/geometry/polyhedron/base_ZZ.py b/src/sage/geometry/polyhedron/base_ZZ.py index 06b93aea513..cd5dbaa1958 100644 --- a/src/sage/geometry/polyhedron/base_ZZ.py +++ b/src/sage/geometry/polyhedron/base_ZZ.py @@ -859,9 +859,9 @@ def normal_form(self, algorithm="palp_native", permutation=False): A vertex at (0, -1), A vertex at (0, 1), A vertex at (1, 0)) - sage: d.normal_form() + sage: d.normal_form() # needs sage.groups [(1, 0), (0, 1), (0, -1), (-1, 0)] - sage: d.lattice_polytope().normal_form("palp_native") + sage: d.lattice_polytope().normal_form("palp_native") # needs sage.groups M( 1, 0), M( 0, 1), M( 0, -1), From 14a0fe4710f34070bea4b7f6b38babc2c72b21e4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 7 Sep 2023 11:54:55 -0700 Subject: [PATCH 041/463] src/sage/geometry/polyhedron/base_ZZ.py: Update copyright --- src/sage/geometry/polyhedron/base_ZZ.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/base_ZZ.py b/src/sage/geometry/polyhedron/base_ZZ.py index cd5dbaa1958..2f280a4d74d 100644 --- a/src/sage/geometry/polyhedron/base_ZZ.py +++ b/src/sage/geometry/polyhedron/base_ZZ.py @@ -3,7 +3,14 @@ """ # **************************************************************************** -# Copyright (C) 2011 Volker Braun +# Copyright (C) 2011-2013 Volker Braun +# 2015 Nathann Cohen +# 2015 Vincent Delecroix +# 2017-2018 Frédéric Chapoton +# 2019 Sophia Elia +# 2019-2020 Jonathan Kliem +# 2023 Luze Xu +# 2023 Matthias Koeppe # # 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 From 13dbc7e56c0f538ed936fd4fe7c83be9413cacb7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 7 Sep 2023 11:58:28 -0700 Subject: [PATCH 042/463] src/sage/geometry/lattice_polytope.py: Update # needs --- src/sage/geometry/lattice_polytope.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index c7dffd27341..5874d2d7e9a 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -2522,13 +2522,13 @@ def index(self): But they are in the same `GL(\ZZ^n)` orbit and have the same normal form:: - sage: d.normal_form() # needs palp + sage: d.normal_form() # needs sage.groups M( 1, 0), M( 0, 1), M( 0, -1), M(-1, 0) in 2-d lattice M - sage: lattice_polytope.ReflexivePolytope(2,3).normal_form() + sage: lattice_polytope.ReflexivePolytope(2,3).normal_form() # needs sage.groups M( 1, 0), M( 0, 1), M( 0, -1), From fdcfe1c7eb12fa1c2a79eaabed65ee83cdceb491 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Mon, 25 Sep 2023 09:17:46 +0200 Subject: [PATCH 043/463] merge --- src/sage/matrix/matrix2.pyx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 060f6620f87..3e5115ec5dd 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -8078,11 +8078,7 @@ cdef class Matrix(Matrix1): if self.fetch('in_echelon_form'): return self.fetch('pivots') -<<<<<<< HEAD - tm = verbose('generic in-place Gauss elimination on %s x %s matrix using %s algorithm' % (self._nrows, self._ncols, algorithm)) -======= _ = verbose('generic in-place Gauss elimination on %s x %s matrix using %s algorithm' % (self._nrows, self._ncols, algorithm)) ->>>>>>> develop self.check_mutability() cdef Matrix A From 04f314a01427dbbfa87c76a77884dc79046cb1e0 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Mon, 25 Sep 2023 09:20:37 +0200 Subject: [PATCH 044/463] merge --- src/sage/matrix/matrix2.pyx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 060f6620f87..3e5115ec5dd 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -8078,11 +8078,7 @@ cdef class Matrix(Matrix1): if self.fetch('in_echelon_form'): return self.fetch('pivots') -<<<<<<< HEAD - tm = verbose('generic in-place Gauss elimination on %s x %s matrix using %s algorithm' % (self._nrows, self._ncols, algorithm)) -======= _ = verbose('generic in-place Gauss elimination on %s x %s matrix using %s algorithm' % (self._nrows, self._ncols, algorithm)) ->>>>>>> develop self.check_mutability() cdef Matrix A From dc8ff266955d97890a3b97c9d290b6a84d3ba037 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Tue, 5 Sep 2023 11:16:47 +0200 Subject: [PATCH 045/463] establish interface for instantiated classical modular polynomials --- .../en/reference/arithmetic_curves/index.rst | 1 + src/sage/schemes/elliptic_curves/all.py | 2 + src/sage/schemes/elliptic_curves/mod_poly.py | 140 ++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 src/sage/schemes/elliptic_curves/mod_poly.py diff --git a/src/doc/en/reference/arithmetic_curves/index.rst b/src/doc/en/reference/arithmetic_curves/index.rst index 6ab10dcf1c0..93c72854e05 100644 --- a/src/doc/en/reference/arithmetic_curves/index.rst +++ b/src/doc/en/reference/arithmetic_curves/index.rst @@ -25,6 +25,7 @@ Maps between them sage/schemes/elliptic_curves/hom_scalar sage/schemes/elliptic_curves/hom_frobenius sage/schemes/elliptic_curves/isogeny_small_degree + sage/schemes/elliptic_curves/mod_poly Elliptic curves over number fields diff --git a/src/sage/schemes/elliptic_curves/all.py b/src/sage/schemes/elliptic_curves/all.py index fd2fb992360..c58602ffc6a 100644 --- a/src/sage/schemes/elliptic_curves/all.py +++ b/src/sage/schemes/elliptic_curves/all.py @@ -40,4 +40,6 @@ from .ell_curve_isogeny import EllipticCurveIsogeny, isogeny_codomain_from_kernel +from .mod_poly import classical_modular_polynomial + from .heegner import heegner_points, heegner_point diff --git a/src/sage/schemes/elliptic_curves/mod_poly.py b/src/sage/schemes/elliptic_curves/mod_poly.py new file mode 100644 index 00000000000..d20b69c58e5 --- /dev/null +++ b/src/sage/schemes/elliptic_curves/mod_poly.py @@ -0,0 +1,140 @@ +r""" +Modular polynomials for elliptic curves + +For a positive integer `\ell`, the classical modular polynomial +`\Phi_\ell\in\ZZ[X,Y]` is characterized by the property that its +zero set is exactly the set of pairs of `j`-invariants connected +by a cyclic `\ell`-isogeny. + +AUTHORS: + +- Lorenz Panny (2023) +""" + +from sage.misc.cachefunc import cached_function +from sage.structure.parent import Parent +from sage.structure.element import parent, FieldElement + +from sage.rings.integer_ring import ZZ +from sage.rings.polynomial.polynomial_ring import polygen, polygens + +from sage.libs.pari import pari +from cypari2.handle_error import PariError + +from sage.databases.db_modular_polynomials import ClassicalModularPolynomialDatabase +_db = ClassicalModularPolynomialDatabase() + +_cache = dict() + +def classical_modular_polynomial(l, j=None): + r""" + Return the classical modular polynomial `\Phi_\ell`, either as a + "generic" bivariate polynomial over `\ZZ`, or as an "instantiated" + modular polynomial where one variable has been replaced by the + given `j`-invariant. + + Generic polynomials are cached up to a certain size of `\ell`, + which significantly accelerates subsequent invocations with the + same `\ell`. The default bound is `\ell \leq 150`, which can be + adjusted by setting ``classical_modular_polynomial.cache_bound`` + to a different value. Beware that modular polynomials are very + large and the amount of memory consumed by the cache will grow + rapidly when the bound is set to a large value. + + INPUT: + + - ``l`` -- positive integer. + + - ``j`` -- either ``None`` or a ring element. + + - If ``None`` is given, the original modular polynomial + is returned as an element of `\ZZ[X,Y]`. + + - If a ring element `j \in R` is given, the evaluation + `\Phi_\ell(j,Y)` is returned as an element of the + univariate polynomial ring `R[Y]`. + + ALGORITHMS: + + - The Kohel database + :class:`~sage.databases.db_modular_polynomials.ClassicalModularPolynomialDatabase` + + - :pari:`polmodular` + + EXAMPLES:: + + sage: classical_modular_polynomial(2) + -X^2*Y^2 + X^3 + 1488*X^2*Y + 1488*X*Y^2 + Y^3 - 162000*X^2 + 40773375*X*Y - 162000*Y^2 + 8748000000*X + 8748000000*Y - 157464000000000 + sage: j = Mod(1728, 419) + sage: classical_modular_polynomial(3, j) + Y^4 + 230*Y^3 + 84*Y^2 + 118*Y + 329 + + TESTS:: + + sage: q = random_prime(50)^randrange(1,4) + sage: j = GF(q).random_element() + sage: l = random_prime(50) + sage: Y = polygen(parent(j), 'Y') + sage: classical_modular_polynomial(l,j) == classical_modular_polynomial(l)(j,Y) + True + """ + l = ZZ(l) + + if j is None: + # We are supposed to return the generic modular polynomial. First + # check if it is already in the cache, then check the database, + # finally compute it using PARI. + try: + return _cache[l] + except KeyError: + pass + + try: + Phi = ZZ['X,Y'](_db[l]) + except ValueError: + try: + pari_Phi = pari.polmodular(l) + except PariError: + raise NotImplementedError('modular polynomial is not in database and computing it on the fly is not yet implemented') + d = {(i,j): c for i,f in enumerate(pari_Phi) for j,c in enumerate(f)} + Phi = ZZ['X,Y'](d) + + if l <= classical_modular_polynomial.cache_bound: + _cache[l] = Phi + + return Phi + + R,Y = parent(j)['Y'].objgen() + + # If the generic polynomial is in the cache or the database, evaluating + # it directly should always be faster than recomputing it from scratch. + try: + Phi = _cache[l] + except KeyError: + pass + else: + return Phi(j, Y) + try: + Phi = _db[l] + except ValueError: + pass + else: + if l <= classical_modular_polynomial.cache_bound: + _cache[l] = ZZ['X,Y'](Phi) + return Phi(j, Y) + + # Now try to get the instantiated modular polynomial directly from PARI. + # This should be slightly more efficient (in particular regarding memory + # usage) than computing and evaluating the generic modular polynomial. + try: + pari_Phi = pari.polmodular(l, 0, j) + except PariError: + pass + else: + return R(pari_Phi) + + # Nothing worked. Fall back to computing the generic modular polynomial + # and simply evaluating it. + return classical_modular_polynomial(l)(j, Y) + +classical_modular_polynomial.cache_bound = 150 From 2ddd0d26beb2e3ee24d5336d5cf180c45e04cb74 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Tue, 26 Sep 2023 10:49:55 +0200 Subject: [PATCH 046/463] reviewer comments --- src/sage/schemes/elliptic_curves/all.py | 2 +- src/sage/schemes/elliptic_curves/mod_poly.py | 34 +++++++------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/all.py b/src/sage/schemes/elliptic_curves/all.py index c58602ffc6a..e339c40d843 100644 --- a/src/sage/schemes/elliptic_curves/all.py +++ b/src/sage/schemes/elliptic_curves/all.py @@ -40,6 +40,6 @@ from .ell_curve_isogeny import EllipticCurveIsogeny, isogeny_codomain_from_kernel -from .mod_poly import classical_modular_polynomial +lazy_import('sage.schemes.elliptic_curves.mod_poly', 'classical_modular_polynomial') from .heegner import heegner_points, heegner_point diff --git a/src/sage/schemes/elliptic_curves/mod_poly.py b/src/sage/schemes/elliptic_curves/mod_poly.py index d20b69c58e5..c034bed50aa 100644 --- a/src/sage/schemes/elliptic_curves/mod_poly.py +++ b/src/sage/schemes/elliptic_curves/mod_poly.py @@ -2,7 +2,7 @@ Modular polynomials for elliptic curves For a positive integer `\ell`, the classical modular polynomial -`\Phi_\ell\in\ZZ[X,Y]` is characterized by the property that its +`\Phi_\ell \in \ZZ[X,Y]` is characterized by the property that its zero set is exactly the set of pairs of `j`-invariants connected by a cyclic `\ell`-isogeny. @@ -11,12 +11,9 @@ - Lorenz Panny (2023) """ -from sage.misc.cachefunc import cached_function -from sage.structure.parent import Parent -from sage.structure.element import parent, FieldElement +from sage.structure.element import parent from sage.rings.integer_ring import ZZ -from sage.rings.polynomial.polynomial_ring import polygen, polygens from sage.libs.pari import pari from cypari2.handle_error import PariError @@ -44,21 +41,17 @@ def classical_modular_polynomial(l, j=None): INPUT: - ``l`` -- positive integer. - - - ``j`` -- either ``None`` or a ring element. - - - If ``None`` is given, the original modular polynomial - is returned as an element of `\ZZ[X,Y]`. - - - If a ring element `j \in R` is given, the evaluation + - ``j`` -- either ``None`` or a ring element: + * if ``None`` is given, the original modular polynomial + is returned as an element of `\ZZ[X,Y]` + * if a ring element `j \in R` is given, the evaluation `\Phi_\ell(j,Y)` is returned as an element of the - univariate polynomial ring `R[Y]`. + univariate polynomial ring `R[Y]` ALGORITHMS: - The Kohel database :class:`~sage.databases.db_modular_polynomials.ClassicalModularPolynomialDatabase` - - :pari:`polmodular` EXAMPLES:: @@ -96,7 +89,7 @@ def classical_modular_polynomial(l, j=None): pari_Phi = pari.polmodular(l) except PariError: raise NotImplementedError('modular polynomial is not in database and computing it on the fly is not yet implemented') - d = {(i,j): c for i,f in enumerate(pari_Phi) for j,c in enumerate(f)} + d = {(i, j): c for i,f in enumerate(pari_Phi) for j, c in enumerate(f)} Phi = ZZ['X,Y'](d) if l <= classical_modular_polynomial.cache_bound: @@ -104,16 +97,13 @@ def classical_modular_polynomial(l, j=None): return Phi - R,Y = parent(j)['Y'].objgen() + R = parent(j)['Y'] + Y = R.gen() # If the generic polynomial is in the cache or the database, evaluating # it directly should always be faster than recomputing it from scratch. - try: - Phi = _cache[l] - except KeyError: - pass - else: - return Phi(j, Y) + if l in _cache: + return _cache[l](j, Y) try: Phi = _db[l] except ValueError: From 905d0420cc6d20fbb81a1876642268fc362ac996 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Thu, 28 Sep 2023 15:26:34 +0200 Subject: [PATCH 047/463] class of matrices of Laurent mpolynomials --- .../matrix_laurent_mpolynomial_dense.pyx} | 0 src/sage/matrix/matrix_mpolynomial_dense.pyx | 52 ++++++++++++++++++- src/sage/matrix/matrix_space.py | 27 ++++++---- 3 files changed, 68 insertions(+), 11 deletions(-) rename src/sage/{rings/polynomial/laurent_reduction.py => matrix/matrix_laurent_mpolynomial_dense.pyx} (100%) diff --git a/src/sage/rings/polynomial/laurent_reduction.py b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx similarity index 100% rename from src/sage/rings/polynomial/laurent_reduction.py rename to src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx diff --git a/src/sage/matrix/matrix_mpolynomial_dense.pyx b/src/sage/matrix/matrix_mpolynomial_dense.pyx index e20c662cc0e..57f80149e88 100644 --- a/src/sage/matrix/matrix_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_mpolynomial_dense.pyx @@ -20,6 +20,8 @@ AUTHOR: from sage.matrix.matrix_generic_dense cimport Matrix_generic_dense from sage.matrix.matrix2 cimport Matrix +from sage.matrix.constructor import identity_matrix +from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular @@ -500,7 +502,7 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): N = self.__copy__() for j in range(self.ncols()): if j != ncoef: - N.add_multiple_of_column(j, ncoef, -R(self[nrow,j] / coef)) + N.add_multiple_of_column(j, ncoef, -R(self[nrow, j] / coef)) return N.fitting_ideal(i) for (ncolumn, column) in enumerate(self.columns()): if not column: @@ -619,3 +621,51 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): self.cache('det', d) return d + +cdef class Matrix_laurent_mpolynomial_dense(Matrix_generic_dense): + """ + Dense matrix over a multivariate polynomial ring over a field. + """ + def laurent_matrix_reduction(self): + """ + From a matrix `self` of Laurent polynomials, apply elementary operations + to obtain a matrix `P` of polynomials such that the variables do not divide + no column and no row. + + OUTPUT: Three matrices `L`, `P`, `R` such that `self = L P R`, where `L` and + `R` are diagonal with monomial entries. + + EXAMPLES: + + sage: R. = LaurentPolynomialRing(QQ) + sage: L = [1/3*x^-1*y - 6*x^-2*y^2 - 1/2*x^-2*y, 1/5*x + 1/2*y + 1/6] + sage: L += [1/2 - 5*x^-1*y - 2*x^-1, -1/3*y^-2 - 4*x^-1*y^-1 + 11*x^-1*y^-2] + sage: A = matrix(R, 2, L) + sage: lf, P, rg = A.laurent_matrix_reduction() + sage: lf + [ x^-2 0] + [ 0 x^-1*y^-2] + sage: P + [ 1/3*x - 6*y - 1/2 1/5*x^3 + 1/2*x^2*y + 1/6*x^2] + [ 1/2*x*y - 5*y^2 - 2*y -1/3*x - 4*y + 11] + sage: rg + [y 0] + [0 1] + """ + R = self.base_ring() + n_rows, n_cols = self.dimensions() + mat_l = identity_matrix(R, n_rows) + mat_r = identity_matrix(R, n_cols) + res = self + for j, rw in enumerate(self.rows()): + for t in R.gens(): + n = min(mon.degree(t) for a in rw for cf, mon in a) + res.rescale_row(j, t ** -n) + mat_l.rescale_col(j, t ** n) + for j, cl in enumerate(self.columns()): + for t in R.gens(): + n = min(mon.degree(t) for a in cl for cf, mon in a) + res.rescale_col(j, t ** -n) + mat_r.rescale_row(j, t ** n) + res = res.change_ring(R.polynomial_ring()) + return mat_l, res, mat_r diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 6aab58352be..31e2ce46224 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -306,6 +306,13 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): pass else: return matrix_mpolynomial_dense.Matrix_mpolynomial_dense + elif isinstance(R, sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_mpair) and R.base_ring() in _Fields: + try: + from . import matrix_mpolynomial_dense + except ImportError: + pass + else: + return matrix_mpolynomial_dense.Matrix_laurent_mpolynomial_dense # The fallback from sage.matrix.matrix_generic_dense import Matrix_generic_dense @@ -795,7 +802,7 @@ def transposed(self): Full MatrixSpace of 3 by 2 dense matrices over Integer Ring """ return MatrixSpace(self._base, self.__ncols, self.__nrows, - self.__is_sparse, self.Element) + self.__is_sparse, self.Element) @lazy_attribute def _copy_zero(self): @@ -2179,7 +2186,7 @@ def row_space(self): return self.__row_space except AttributeError: self.__row_space = sage.modules.free_module.FreeModule(self.base_ring(), - self.ncols(), sparse=self.is_sparse()) + self.ncols(), sparse=self.is_sparse()) return self.__row_space def column_space(self): @@ -2197,7 +2204,7 @@ def column_space(self): return self.__column_space except AttributeError: self.__column_space = sage.modules.free_module.FreeModule(self.base_ring(), self.nrows(), - sparse=self.is_sparse()) + sparse=self.is_sparse()) return self.__column_space def random_element(self, density=None, *args, **kwds): @@ -2255,10 +2262,10 @@ def random_element(self, density=None, *args, **kwds): Z = self.zero_matrix().__copy__() if density is None: Z.randomize(density=float(1), nonzero=kwds.pop('nonzero', False), - *args, **kwds) + *args, **kwds) else: Z.randomize(density=density, nonzero=kwds.pop('nonzero', True), - *args, **kwds) + *args, **kwds) return Z def _an_element_(self): @@ -2582,13 +2589,13 @@ def _MatrixSpace_ZZ_2x2(): register_unpickle_override('sage.matrix.matrix_modn_dense', - 'Matrix_modn_dense', Matrix_modn_dense_double) + 'Matrix_modn_dense', Matrix_modn_dense_double) register_unpickle_override('sage.matrix.matrix_integer_2x2', - 'Matrix_integer_2x2', Matrix_integer_dense) + 'Matrix_integer_2x2', Matrix_integer_dense) register_unpickle_override('sage.matrix.matrix_integer_2x2', - 'MatrixSpace_ZZ_2x2_class', MatrixSpace) + 'MatrixSpace_ZZ_2x2_class', MatrixSpace) register_unpickle_override('sage.matrix.matrix_integer_2x2', - 'MatrixSpace_ZZ_2x2', _MatrixSpace_ZZ_2x2) + 'MatrixSpace_ZZ_2x2', _MatrixSpace_ZZ_2x2) lazy_import('sage.matrix.matrix_gf2e_dense', 'unpickle_matrix_gf2e_dense_v0') register_unpickle_override('sage.matrix.matrix_mod2e_dense', - 'unpickle_matrix_mod2e_dense_v0', unpickle_matrix_gf2e_dense_v0) + 'unpickle_matrix_mod2e_dense_v0', unpickle_matrix_gf2e_dense_v0) From df401b2140d657bc778124266c2eb9a98dedf1ee Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Thu, 28 Sep 2023 17:52:27 +0200 Subject: [PATCH 048/463] use fitting_ideals for characteristic varieties --- src/sage/groups/finitely_presented.py | 98 +++++++++++++------- src/sage/matrix/matrix_mpolynomial_dense.pyx | 46 +++++++++ 2 files changed, 108 insertions(+), 36 deletions(-) diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index 96d03e90c83..c96ea32c0da 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -145,6 +145,7 @@ from sage.sets.set import Set from sage.structure.unique_representation import UniqueRepresentation + class GroupMorphismWithGensImages(SetMorphism): r""" Class used for morphisms from finitely presented groups to @@ -1549,12 +1550,12 @@ def sorted_presentation(self): C = [rel] for j in range(len(rel) - 1): C.append(rel[j + 1:] + rel[:j + 1]) - C1 = [tuple(-j for j in reversed(l)) for l in C] + C1 = [tuple(-j for j in reversed(l1)) for l1 in C] C += C1 C.sort() L1.append(C[0]) L1.sort() - return F/L1 + return F / L1 def epimorphisms(self, H): r""" @@ -1762,65 +1763,90 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): OUTPUT: If ``groebner`` is ``False`` a list of ideals defining the characteristic varieties. - If it is ``True``, a list of lists for Gröbner bases for each ideal. + If it is ``True``, a list of lists for Gröbner bases for the ideal of each irreducible + component. EXAMPLES:: sage: L = [2*(i, j) + 2* (-i, -j) for i, j in ((1, 2), (2, 3), (3, 1))] sage: G = FreeGroup(3) / L sage: G.characteristic_varieties(groebner=True) - [[(f1 - 1, f2 - 1, f3 - 1), - (f1 + 1, f2 - 1, f3 - 1), - (f1 - 1, f2 - 1, f3 + 1), - (f3^2 + 1, f1 - f3, f2 - f3), - (f1 - 1, f2 + 1, f3 - 1)], - [(f1 - 1, f2 - 1, f3 - 1), + {0: [(0,)], + 1: [(f1 - 1, f2 - 1, f3 - 1), (f1*f3 + 1, f2 - 1), (f1*f2 + 1, f3 - 1), (f2*f3 + 1, f1 - 1), (f2*f3 + 1, f1 - f2), (f2*f3 + 1, f1 - f3), - (f1*f3 + 1, f2 - f3)]] + (f1*f3 + 1, f2 - f3)], + 2: [(f1 - 1, f2 - 1, f3 + 1), + (f3^2 + 1, f1 - f3, f2 - f3), + (f1 - 1, f2 - 1, f3 - 1), + (f1 - 1, f2 + 1, f3 - 1), + (f1 + 1, f2 - 1, f3 - 1)], + 3: [(f1 - 1, f2 - 1, f3 - 1)]} sage: G = FreeGroup(2)/[2*(1,2,-1,-2)] sage: G.characteristic_varieties() - [Ideal (-2*f2 + 2, 2*f1 - 2) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field] + {0: Ideal (0, 0) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field, + 1: Ideal (0, -2*f2 + 2, 2*f1 - 2) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field, + 2: Ideal (f1 - 1, f2 - 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field} sage: G.characteristic_varieties(ring=ZZ) - [Ideal (-2*f2 + 2, 2*f1 - 2) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring] + {0: Ideal (0, 0) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring, + 1: Ideal (0, -2*f2 + 2, 2*f1 - 2) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring, + 2: Ideal (f1 - 1, f2 - 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring} sage: G = FreeGroup(2)/[(1,2,1,-2,-1,-2)] sage: G.characteristic_varieties() - [Ideal (1 - f2 + f2^2, -1 + f2 - f2^2) of Univariate Laurent Polynomial Ring in f2 over Rational Field] + {0: Ideal (0, 0) of Univariate Laurent Polynomial Ring in f2 over Rational Field, + 1: Ideal (-1 + 2*f2 - 2*f2^2 + f2^3, 1 - 2*f2 + 2*f2^2 - f2^3) of Univariate Laurent Polynomial Ring in f2 over Rational Field, + 2: Ideal (0, 1) of Univariate Laurent Polynomial Ring in f2 over Rational Field} sage: G.characteristic_varieties(groebner=True) - [[1 - f2 + f2^2]] + {0: [0], 1: [-1 + f2, 1 - f2 + f2^2], 2: [1]} """ - A, ideal = self.abelian_alexander_matrix(ring=ring, simplified=True) + A, rels = self.abelian_alexander_matrix(ring=ring, simplified=True) R = A.base_ring() - res = [] + eval_1 = {x: ring(1) for x in R.gens()} + A_scalar = A.apply_map(lambda p: p.subs(eval_1)) + n = A.ncols() + n1 = n - A_scalar.rank() + ideal_1 = R.ideal([x - 1 for x in R.gens()]) S = R.polynomial_ring() - ideal = [S(elt) for elt in ideal] - for j in range(1, A.ncols()): - L = [p.monomial_reduction()[0] for p in A.minors(j)] - J = R.ideal(L + ideal) - res.append(J) - if not groebner or not R.base_ring().is_field(): + K = R.base_ring() + id_rels = R.ideal(rels) + res = dict() + for j in range(n + 1): + if R.ngens() != 1: + J = id_rels + A.fitting_ideal(j) + elif R.ngens() == 1: + J = R.ideal(id_rels.gens() + A.fitting_ideal(j).gens()) + if j <= n1: + J1 = K.ideal([K(p.subs(eval_1)) for p in J.gens()]) + if J1: + J *= ideal_1 + res[j] = J + if not groebner or not ring.is_field(): return res if R.ngens() == 1: - res0 = [gcd(S(p) for p in J.gens()) for J in res] - res1 = [] - for p in res0: - if p == 0: - res1.append([R(0)]) + res = {j: gcd(S(p) for p in res[j].gens()) for j in range(n + 1)} + char_var = dict() + for j in range(n + 1): + if res[j] == 0: + char_var[j] = [R(0)] else: - fct = [q[0] for q in R(p).factor()] + fct = [q[0] for q in R(res[j]).factor()] if fct: - res1.append(fct) - return res1 - res1 = [] - for J in res: - LJ = J.minimal_associated_primes() + char_var[j] = fct + else: + char_var[j] = [R(1)] + return char_var + char_var = dict() + for j in range(n + 1): + LJ = res[j].minimal_associated_primes() fct = [id.groebner_basis() for id in LJ] - if fct != [(S.one(),)]: - res1.append(fct) - return res1 + if fct != [(S.one(), )]: + char_var[j] = fct + else: + char_var[j] = [R(1)] + return char_var def rewriting_system(self): """ diff --git a/src/sage/matrix/matrix_mpolynomial_dense.pyx b/src/sage/matrix/matrix_mpolynomial_dense.pyx index 57f80149e88..d3f22015465 100644 --- a/src/sage/matrix/matrix_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_mpolynomial_dense.pyx @@ -669,3 +669,49 @@ cdef class Matrix_laurent_mpolynomial_dense(Matrix_generic_dense): mat_r.rescale_row(j, t ** n) res = res.change_ring(R.polynomial_ring()) return mat_l, res, mat_r + + def _fitting_ideal(self, i): + r""" + Return the `i`-th Fitting ideal of the matrix. This is the ideal generated + by the `n - i` minors, where `n` is the number of columns. + + INPUT: + + ``i`` -- an integer + + OUTPUT: + + An ideal on the base ring. + + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(QQ) + sage: M = matrix(R, [[2*x^-1-z, 0, y-z^-2, 0], [0, z - y^-1, z - x, 0],[z - y, x^-2 - y, 0, z]]) + sage: M + [-z + 2*x^-1 0 y - z^-2 0] + [ 0 z - y^-1 -x + z 0] + [ -y + z -y + x^-2 0 z] + sage: M.fitting_ideal(0) + Ideal (0) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field + sage: M.fitting_ideal(1) == M._fitting_ideal(1) + True + sage: M.fitting_ideal(1).groebner_basis() + (x^4 - 2*x^3*y - x*z^3 - 4*x^2*y + 8*x*y^2 + 4*x*y*z + 2*z^2 - 8*y, + x*y*z^2 - x*z - 2*y*z + 2, + x^2*z - x*z^2 - 2*x + 2*z, + y^2*z + 1/4*x^2 - 1/2*x*y - 1/4*x*z - y + 1/2) + sage: M.fitting_ideal(2).groebner_basis() + (1,) + sage: M.fitting_ideal(3).groebner_basis() + (1,) + sage: M.fitting_ideal(4).groebner_basis() + (1,) + sage: [R.ideal(M.minors(i)) == M._fitting_ideal(4 - i) for i in range(5)] + [True, True, True, True, True] + + """ + R = self.base_ring() + S = R.polynomial_ring() + A = self.laurent_matrix_reduction()[1].change_ring(S) + J = A._fitting_ideal(i) + return J.change_ring(R) From 68a94e5fd3f168718044d11e5610894a7af2a86e Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Thu, 28 Sep 2023 22:07:32 +0200 Subject: [PATCH 049/463] adding xgcd, etc, for laurent polynomials in one variable --- src/sage/groups/finitely_presented.py | 6 +- src/sage/matrix/matrix2.pyx | 14 +-- src/sage/matrix/matrix_mpolynomial_dense.pyx | 6 +- .../rings/polynomial/laurent_polynomial.pyx | 113 ++++++++++++++++++ .../polynomial/laurent_polynomial_ideal.py | 10 ++ 5 files changed, 135 insertions(+), 14 deletions(-) diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index c96ea32c0da..d2192bdcbbd 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -1814,10 +1814,8 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): id_rels = R.ideal(rels) res = dict() for j in range(n + 1): - if R.ngens() != 1: - J = id_rels + A.fitting_ideal(j) - elif R.ngens() == 1: - J = R.ideal(id_rels.gens() + A.fitting_ideal(j).gens()) + # J = id_rels + A.fitting_ideal(j) + J = R.ideal(id_rels.gens() + A.fitting_ideal(j).gens()) if j <= n1: J1 = K.ideal([K(p.subs(eval_1)) for p in J.gens()]) if J1: diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 09a90f0c2a1..a872e2264a2 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -15902,7 +15902,7 @@ cdef class Matrix(Matrix1): dd, uu, vv = mm.smith_form(transformation=True) else: dd = mm.smith_form(transformation=False) - d = dd.new_matrix(1,1,[t[0,0]]).block_sum(dd) + d = dd.new_matrix(1, 1, [t[0, 0]]).block_sum(dd) if transformation: u = uu.new_matrix(1, 1, [1]).block_sum(uu) * u v = v * vv.new_matrix(1, 1, [1]).block_sum(vv) @@ -18121,9 +18121,9 @@ def _smith_diag(d, transformation=True): else: left = right = None for i in range(n): - I = ideal_or_fractional(R, dp[i, i]) + I0 = ideal_or_fractional(R, dp[i, i]) - if I == ideal_or_fractional(R, 1): + if I0 == ideal_or_fractional(R, 1): if dp[i, i] != 1: if transformation: left.add_multiple_of_row(i, i, R(R(1) / (dp[i, i])) - 1) @@ -18131,7 +18131,7 @@ def _smith_diag(d, transformation=True): continue for j in range(i + 1, n): - if dp[j, j] not in I: + if dp[j, j] not in I0: t = ideal_or_fractional(R, [dp[i, i], dp[j, j]]).gens_reduced() if len(t) > 1: raise ArithmeticError @@ -18215,9 +18215,9 @@ def _generic_clear_column(m): # [e,f] # is invertible over R - I = ideal_or_fractional(R, a[0, 0]) # need to make sure we change this when a[0,0] changes + I0 = ideal_or_fractional(R, a[0, 0]) # need to make sure we change this when a[0,0] changes for k in range(1, a.nrows()): - if a[k, 0] not in I: + if a[k, 0] not in I0: try: v = ideal_or_fractional(R, a[0, 0], a[k, 0]).gens_reduced() except Exception as msg: @@ -18257,7 +18257,7 @@ def _generic_clear_column(m): if newlmat.det() != 1: raise ArithmeticError a = newlmat*a - I = ideal_or_fractional(R, a[0, 0]) + I0 = ideal_or_fractional(R, a[0, 0]) left_mat = newlmat*left_mat if left_mat * m != a: raise ArithmeticError diff --git a/src/sage/matrix/matrix_mpolynomial_dense.pyx b/src/sage/matrix/matrix_mpolynomial_dense.pyx index d3f22015465..840be75c387 100644 --- a/src/sage/matrix/matrix_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_mpolynomial_dense.pyx @@ -656,13 +656,13 @@ cdef class Matrix_laurent_mpolynomial_dense(Matrix_generic_dense): n_rows, n_cols = self.dimensions() mat_l = identity_matrix(R, n_rows) mat_r = identity_matrix(R, n_cols) - res = self - for j, rw in enumerate(self.rows()): + res = self.__copy__() + for j, rw in enumerate(res.rows()): for t in R.gens(): n = min(mon.degree(t) for a in rw for cf, mon in a) res.rescale_row(j, t ** -n) mat_l.rescale_col(j, t ** n) - for j, cl in enumerate(self.columns()): + for j, cl in enumerate(res.columns()): for t in R.gens(): n = min(mon.degree(t) for a in cl for cf, mon in a) res.rescale_col(j, t ** -n) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 5f563725296..bfb9e4ddd57 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -1316,6 +1316,119 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): return ~self raise ArithmeticError("element is not a unit") + def xgcd(self, other): + R = self.parent() + S = R.polynomial_ring() + f, df = self.monomial_reduction() + g, dg = other.monomial_reduction() + h, p, q = f.xgcd(g) + return R(h), p / df, q / dg + + def inverse_mod(a, m): + """ + Invert the polynomial ``a`` with respect to ``m``, or raise a :class:`ValueError` + if no such inverse exists. + + The parameter ``m`` may be either a single polynomial or an ideal + (for consistency with :meth:`inverse_mod` in other rings). + + EXAMPLES:: + + sage: S. = LaurentPolynomialRing(QQ) + sage: f = inverse_mod(t^2 + 1, t^3 + 1); f + -1/2*t^2 - 1/2*t + 1/2 + sage: f * (t^2 + 1) % (t^3 + 1) + 1 + sage: f = t.inverse_mod((t + 1)^7); f + -t^6 - 7*t^5 - 21*t^4 - 35*t^3 - 35*t^2 - 21*t - 7 + sage: (f * t) + (t + 1)^7 + 1 + sage: t.inverse_mod(S.ideal((t + 1)^7)) == f + True + + This also works over inexact rings, but note that due to rounding + error the product may not always exactly equal the constant + polynomial 1 and have extra terms with coefficients close to zero. :: + + sage: # needs sage.modules + sage: R. = RDF[] + sage: epsilon = RDF(1).ulp()*50 # Allow an error of up to 50 ulp + sage: f = inverse_mod(x^2 + 1, x^5 + x + 1); f # abs tol 1e-14 + 0.4*x^4 - 0.2*x^3 - 0.4*x^2 + 0.2*x + 0.8 + sage: poly = f * (x^2 + 1) % (x^5 + x + 1) + sage: # Remove noisy zero terms: + sage: parent(poly)([0.0 if abs(c) <= epsilon else c + ....: for c in poly.coefficients(sparse=False)]) + 1.0 + sage: f = inverse_mod(x^3 - x + 1, x - 2); f + 0.14285714285714285 + sage: f * (x^3 - x + 1) % (x - 2) + 1.0 + sage: g = 5*x^3 + x - 7; m = x^4 - 12*x + 13; f = inverse_mod(g, m); f + -0.0319636125...*x^3 - 0.0383269759...*x^2 - 0.0463050900...*x + 0.346479687... + sage: poly = f*g % m + sage: # Remove noisy zero terms: + sage: parent(poly)([0.0 if abs(c) <= epsilon else c # abs tol 1e-14 + ....: for c in poly.coefficients(sparse=False)]) + 1.0000000000000004 + + ALGORITHM: Solve the system `as + mt = 1`, returning `s` as the inverse + of `a` mod `m`. + + Uses the Euclidean algorithm for exact rings, and solves a linear + system for the coefficients of `s` and `t` for inexact rings (as the + Euclidean algorithm may not converge in that case). + """ + from sage.rings.ideal import is_Ideal + if is_Ideal(m): + v = m.gens_reduced() + if len(v) > 1: + raise NotImplementedError("Don't know how to invert modulo non-principal ideal %s" % m) + m = v[0] + if m.degree() == 1 and m[1].is_unit(): + # a(x) mod (x-r) = a(r) + r = -m[0] + if not m[1].is_one(): + r *= m.base_ring()(~m[1]) + u = a(r) + if u.is_unit(): + return a.parent()(~u) + if a.parent().is_exact(): + # use xgcd + g, s, _ = a.xgcd(m) + if g == 1: + return s + elif g.is_unit(): + return g.inverse_of_unit() * s + else: + raise ValueError("Impossible inverse modulo") + else: + # xgcd may not converge for inexact rings. + # Instead solve for the coefficients of + # s (degree n-1) and t (degree n-2) in + # as + mt = 1 + # as a linear system. + from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector + a %= m + n = m.degree() + R = a.parent().base_ring() + M = matrix(R, 2*n-1) + # a_i s_j x^{i+j} terms + for i in range(n): + for j in range(n): + M[i+j, j] = a[i] + # m_i t_j x^{i+j} terms + for i in range(n+1): + for j in range(n-1): + M[i+j, j+n] = m[i] + v = vector(R, [R.one()] + [R.zero()]*(2*n-2)) # the constant polynomial 1 + if M.is_invertible(): + x = M.solve_right(v) # there has to be a better way to solve + return a.parent()(list(x)[0:n]) + else: + raise ValueError("Impossible inverse modulo") + def _fraction_pair(self): """ Return one representation of ``self`` as a pair diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index b193569d3fa..991a3fa589c 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -204,6 +204,16 @@ def __contains__(self, f): g = f.__reduce__()[1][1] return (g in self.polynomial_ideal()) + def gens_reduced(self): + R = self.ring() + if R.ngens() > 1 or not R.base_ring().is_field(): + return self.gens() + gns = self.gens() + res = R(0) + for p in gns: + res = res.gcd(p) + return (res, ) + # Operations on ideals def change_ring(self, R, hint=None): From 8da8781f109e97e87885c0a05c55e5a6d2fef45e Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Thu, 28 Sep 2023 23:34:10 +0200 Subject: [PATCH 050/463] cut characteristic varieties when the total ideal is reached --- src/sage/groups/finitely_presented.py | 34 ++-- .../matrix_laurent_mpolynomial_dense.pyx | 168 +++++++++++++----- src/sage/matrix/matrix_mpolynomial_dense.pyx | 96 ---------- src/sage/matrix/matrix_space.py | 4 +- .../rings/polynomial/laurent_polynomial.pyx | 95 +++------- 5 files changed, 169 insertions(+), 228 deletions(-) diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index d2192bdcbbd..391cefc336c 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -1784,21 +1784,25 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): (f1 - 1, f2 - 1, f3 - 1), (f1 - 1, f2 + 1, f3 - 1), (f1 + 1, f2 - 1, f3 - 1)], - 3: [(f1 - 1, f2 - 1, f3 - 1)]} + 3: [(f1 - 1, f2 - 1, f3 - 1)], + 4: []} sage: G = FreeGroup(2)/[2*(1,2,-1,-2)] sage: G.characteristic_varieties() {0: Ideal (0, 0) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field, 1: Ideal (0, -2*f2 + 2, 2*f1 - 2) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field, - 2: Ideal (f1 - 1, f2 - 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field} + 2: Ideal (f1 - 1, f2 - 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field, + 3: Ideal (0, 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field} sage: G.characteristic_varieties(ring=ZZ) {0: Ideal (0, 0) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring, 1: Ideal (0, -2*f2 + 2, 2*f1 - 2) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring, - 2: Ideal (f1 - 1, f2 - 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring} + 2: Ideal (f1 - 1, f2 - 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring, + 3: Ideal (0, 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring} sage: G = FreeGroup(2)/[(1,2,1,-2,-1,-2)] sage: G.characteristic_varieties() {0: Ideal (0, 0) of Univariate Laurent Polynomial Ring in f2 over Rational Field, 1: Ideal (-1 + 2*f2 - 2*f2^2 + f2^3, 1 - 2*f2 + 2*f2^2 - f2^3) of Univariate Laurent Polynomial Ring in f2 over Rational Field, - 2: Ideal (0, 1) of Univariate Laurent Polynomial Ring in f2 over Rational Field} + 2: Ideal (0, 1) of Univariate Laurent Polynomial Ring in f2 over Rational Field, + 3: Ideal (0, 1) of Univariate Laurent Polynomial Ring in f2 over Rational Field} sage: G.characteristic_varieties(groebner=True) {0: [0], 1: [-1 + f2, 1 - f2 + f2^2], 2: [1]} """ @@ -1813,7 +1817,7 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): K = R.base_ring() id_rels = R.ideal(rels) res = dict() - for j in range(n + 1): + for j in range(n + 2): # J = id_rels + A.fitting_ideal(j) J = R.ideal(id_rels.gens() + A.fitting_ideal(j).gens()) if j <= n1: @@ -1824,9 +1828,11 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): if not groebner or not ring.is_field(): return res if R.ngens() == 1: - res = {j: gcd(S(p) for p in res[j].gens()) for j in range(n + 1)} + res = {j: gcd(S(p) for p in res[j].gens()) for j in range(n + 2)} char_var = dict() - for j in range(n + 1): + strict = True + j = 0 + while strict and j <= n + 1: if res[j] == 0: char_var[j] = [R(0)] else: @@ -1835,15 +1841,19 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): char_var[j] = fct else: char_var[j] = [R(1)] + strict = False + j += 1 return char_var char_var = dict() - for j in range(n + 1): + strict = True + j = 0 + while strict and j <= n + 1: LJ = res[j].minimal_associated_primes() fct = [id.groebner_basis() for id in LJ] - if fct != [(S.one(), )]: - char_var[j] = fct - else: - char_var[j] = [R(1)] + char_var[j] = fct + if not fct: + strict = False + j += 1 return char_var def rewriting_system(self): diff --git a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx index c26b667b492..769608b3ce1 100644 --- a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx @@ -1,50 +1,128 @@ +""" +Dense matrices over multivariate polynomials over fields + +This implementation inherits from Matrix_generic_dense, i.e. it is not +optimized for speed only some methods were added. + +AUTHOR: + +* Martin Albrecht +""" + +# ***************************************************************************** +# Copyright (C) 2013 Martin Albrecht +# +# 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.matrix.matrix_generic_dense cimport Matrix_generic_dense + +# from sage.matrix.matrix2 cimport Matrix +# +# from sage.matrix.constructor import identity_matrix +# from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic +# from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular +# from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular +# +# from sage.libs.singular.function import singular_function, lib +# +# from cysignals.signals cimport sig_on, sig_off + from sage.matrix.constructor import identity_matrix from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic - -def laurent_matrix_reduction(A): +cdef class Matrix_laurent_mpolynomial_dense(Matrix_generic_dense): """ - From a matrix `A` of Laurent polynomials, apply elementary operations - to obtain a matrix `P` of polynomials such that the variables do not divide - no column and no row. - - OUTPUT: Three matrices `L`, `P`, `R` such that `A = L P R`, where `L` and - `R` are diagonal with monomial entries. - - EXAMPLES: - - sage: from sage.rings.polynomial.laurent_reduction import laurent_matrix_reduction - sage: R. = LaurentPolynomialRing(QQ) - sage: L = [1/3*x^-1*y - 6*x^-2*y^2 - 1/2*x^-2*y, 1/5*x + 1/2*y + 1/6] - sage: L += [1/2 - 5*x^-1*y - 2*x^-1, -1/3*y^-2 - 4*x^-1*y^-1 + 11*x^-1*y^-2] - sage: A = matrix(R, 2, L) - sage: lf, P, rg = laurent_matrix_reduction(A) - sage: lf - [ x^-2 0] - [ 0 x^-1*y^-2] - sage: P - [ 1/3*x - 6*y - 1/2 1/5*x^3 + 1/2*x^2*y + 1/6*x^2] - [ 1/2*x*y - 5*y^2 - 2*y -1/3*x - 4*y + 11] - sage: rg - [y 0] - [0 1] + Dense matrix over a multivariate polynomial ring over a field. """ - R = A.base_ring() - n_rows, n_cols = A.dimensions() - mat_l = identity_matrix(R, n_rows) - mat_r = identity_matrix(R, n_cols) - if not isinstance(R, LaurentPolynomialRing_generic): - return mat_l, A, mat_r - res = A - for j, rw in enumerate(A.rows()): - for t in R.gens(): - n = min(mon.degree(t) for a in rw for cf, mon in a) - res.rescale_row(j, t ** -n) - mat_l.rescale_col(j, t ** n) - for j, cl in enumerate(A.columns()): - for t in R.gens(): - n = min(mon.degree(t) for a in cl for cf, mon in a) - res.rescale_col(j, t ** -n) - mat_r.rescale_row(j, t ** n) - res = res.change_ring(R.polynomial_ring()) - return mat_l, res, mat_r + def laurent_matrix_reduction(self): + """ + From a matrix `self` of Laurent polynomials, apply elementary operations + to obtain a matrix `P` of polynomials such that the variables do not divide + no column and no row. + + OUTPUT: Three matrices `L`, `P`, `R` such that `self = L P R`, where `L` and + `R` are diagonal with monomial entries. + + EXAMPLES: + + sage: R. = LaurentPolynomialRing(QQ) + sage: L = [1/3*x^-1*y - 6*x^-2*y^2 - 1/2*x^-2*y, 1/5*x + 1/2*y + 1/6] + sage: L += [1/2 - 5*x^-1*y - 2*x^-1, -1/3*y^-2 - 4*x^-1*y^-1 + 11*x^-1*y^-2] + sage: A = matrix(R, 2, L) + sage: lf, P, rg = A.laurent_matrix_reduction() + sage: lf + [ x^-2 0] + [ 0 x^-1*y^-2] + sage: P + [ 1/3*x - 6*y - 1/2 1/5*x^3 + 1/2*x^2*y + 1/6*x^2] + [ 1/2*x*y - 5*y^2 - 2*y -1/3*x - 4*y + 11] + sage: rg + [y 0] + [0 1] + """ + R = self.base_ring() + n_rows, n_cols = self.dimensions() + mat_l = identity_matrix(R, n_rows) + mat_r = identity_matrix(R, n_cols) + res = self.__copy__() + for j, rw in enumerate(res.rows()): + for t in R.gens(): + n = min(mon.degree(t) for a in rw for cf, mon in a) + res.rescale_row(j, t ** -n) + mat_l.rescale_col(j, t ** n) + for j, cl in enumerate(res.columns()): + for t in R.gens(): + n = min(mon.degree(t) for a in cl for cf, mon in a) + res.rescale_col(j, t ** -n) + mat_r.rescale_row(j, t ** n) + res = res.change_ring(R.polynomial_ring()) + return mat_l, res, mat_r + + def _fitting_ideal(self, i): + r""" + Return the `i`-th Fitting ideal of the matrix. This is the ideal generated + by the `n - i` minors, where `n` is the number of columns. + + INPUT: + + ``i`` -- an integer + + OUTPUT: + + An ideal on the base ring. + + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(QQ) + sage: M = matrix(R, [[2*x^-1-z, 0, y-z^-2, 0], [0, z - y^-1, z - x, 0],[z - y, x^-2 - y, 0, z]]) + sage: M + [-z + 2*x^-1 0 y - z^-2 0] + [ 0 z - y^-1 -x + z 0] + [ -y + z -y + x^-2 0 z] + sage: M.fitting_ideal(0) + Ideal (0) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field + sage: M.fitting_ideal(1) == M._fitting_ideal(1) + True + sage: M.fitting_ideal(1).groebner_basis() + (x^4 - 2*x^3*y - x*z^3 - 4*x^2*y + 8*x*y^2 + 4*x*y*z + 2*z^2 - 8*y, + x*y*z^2 - x*z - 2*y*z + 2, + x^2*z - x*z^2 - 2*x + 2*z, + y^2*z + 1/4*x^2 - 1/2*x*y - 1/4*x*z - y + 1/2) + sage: M.fitting_ideal(2).groebner_basis() + (1,) + sage: M.fitting_ideal(3).groebner_basis() + (1,) + sage: M.fitting_ideal(4).groebner_basis() + (1,) + sage: [R.ideal(M.minors(i)) == M._fitting_ideal(4 - i) for i in range(5)] + [True, True, True, True, True] + + """ + R = self.base_ring() + S = R.polynomial_ring() + A = self.laurent_matrix_reduction()[1].change_ring(S) + J = A._fitting_ideal(i) + return J.change_ring(R) diff --git a/src/sage/matrix/matrix_mpolynomial_dense.pyx b/src/sage/matrix/matrix_mpolynomial_dense.pyx index 840be75c387..589b5b33331 100644 --- a/src/sage/matrix/matrix_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_mpolynomial_dense.pyx @@ -20,8 +20,6 @@ AUTHOR: from sage.matrix.matrix_generic_dense cimport Matrix_generic_dense from sage.matrix.matrix2 cimport Matrix -from sage.matrix.constructor import identity_matrix -from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular @@ -621,97 +619,3 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): self.cache('det', d) return d - -cdef class Matrix_laurent_mpolynomial_dense(Matrix_generic_dense): - """ - Dense matrix over a multivariate polynomial ring over a field. - """ - def laurent_matrix_reduction(self): - """ - From a matrix `self` of Laurent polynomials, apply elementary operations - to obtain a matrix `P` of polynomials such that the variables do not divide - no column and no row. - - OUTPUT: Three matrices `L`, `P`, `R` such that `self = L P R`, where `L` and - `R` are diagonal with monomial entries. - - EXAMPLES: - - sage: R. = LaurentPolynomialRing(QQ) - sage: L = [1/3*x^-1*y - 6*x^-2*y^2 - 1/2*x^-2*y, 1/5*x + 1/2*y + 1/6] - sage: L += [1/2 - 5*x^-1*y - 2*x^-1, -1/3*y^-2 - 4*x^-1*y^-1 + 11*x^-1*y^-2] - sage: A = matrix(R, 2, L) - sage: lf, P, rg = A.laurent_matrix_reduction() - sage: lf - [ x^-2 0] - [ 0 x^-1*y^-2] - sage: P - [ 1/3*x - 6*y - 1/2 1/5*x^3 + 1/2*x^2*y + 1/6*x^2] - [ 1/2*x*y - 5*y^2 - 2*y -1/3*x - 4*y + 11] - sage: rg - [y 0] - [0 1] - """ - R = self.base_ring() - n_rows, n_cols = self.dimensions() - mat_l = identity_matrix(R, n_rows) - mat_r = identity_matrix(R, n_cols) - res = self.__copy__() - for j, rw in enumerate(res.rows()): - for t in R.gens(): - n = min(mon.degree(t) for a in rw for cf, mon in a) - res.rescale_row(j, t ** -n) - mat_l.rescale_col(j, t ** n) - for j, cl in enumerate(res.columns()): - for t in R.gens(): - n = min(mon.degree(t) for a in cl for cf, mon in a) - res.rescale_col(j, t ** -n) - mat_r.rescale_row(j, t ** n) - res = res.change_ring(R.polynomial_ring()) - return mat_l, res, mat_r - - def _fitting_ideal(self, i): - r""" - Return the `i`-th Fitting ideal of the matrix. This is the ideal generated - by the `n - i` minors, where `n` is the number of columns. - - INPUT: - - ``i`` -- an integer - - OUTPUT: - - An ideal on the base ring. - - EXAMPLES:: - - sage: R. = LaurentPolynomialRing(QQ) - sage: M = matrix(R, [[2*x^-1-z, 0, y-z^-2, 0], [0, z - y^-1, z - x, 0],[z - y, x^-2 - y, 0, z]]) - sage: M - [-z + 2*x^-1 0 y - z^-2 0] - [ 0 z - y^-1 -x + z 0] - [ -y + z -y + x^-2 0 z] - sage: M.fitting_ideal(0) - Ideal (0) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field - sage: M.fitting_ideal(1) == M._fitting_ideal(1) - True - sage: M.fitting_ideal(1).groebner_basis() - (x^4 - 2*x^3*y - x*z^3 - 4*x^2*y + 8*x*y^2 + 4*x*y*z + 2*z^2 - 8*y, - x*y*z^2 - x*z - 2*y*z + 2, - x^2*z - x*z^2 - 2*x + 2*z, - y^2*z + 1/4*x^2 - 1/2*x*y - 1/4*x*z - y + 1/2) - sage: M.fitting_ideal(2).groebner_basis() - (1,) - sage: M.fitting_ideal(3).groebner_basis() - (1,) - sage: M.fitting_ideal(4).groebner_basis() - (1,) - sage: [R.ideal(M.minors(i)) == M._fitting_ideal(4 - i) for i in range(5)] - [True, True, True, True, True] - - """ - R = self.base_ring() - S = R.polynomial_ring() - A = self.laurent_matrix_reduction()[1].change_ring(S) - J = A._fitting_ideal(i) - return J.change_ring(R) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 31e2ce46224..04ab6b138a2 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -308,11 +308,11 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): return matrix_mpolynomial_dense.Matrix_mpolynomial_dense elif isinstance(R, sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_mpair) and R.base_ring() in _Fields: try: - from . import matrix_mpolynomial_dense + from . import matrix_laurent_mpolynomial_dense except ImportError: pass else: - return matrix_mpolynomial_dense.Matrix_laurent_mpolynomial_dense + return matrix_laurent_mpolynomial_dense.Matrix_laurent_mpolynomial_dense # The fallback from sage.matrix.matrix_generic_dense import Matrix_generic_dense diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index bfb9e4ddd57..d4dff8b1361 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -1317,7 +1317,18 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): raise ArithmeticError("element is not a unit") def xgcd(self, other): + """ + Extended `gcd` for univariate Laurent polynomial rings over a field. + + EXAMPLES:: + + sage: S. = LaurentPolynomialRing(QQ) + sage: (t^-2 + 1).xgcd(t^-3 + 1) + (1, 1/2*t^2 - 1/2*t^3 - 1/2*t^4, 1/2*t^3 + 1/2*t^4) + """ R = self.parent() + if not R.is_exact() or not R.base_ring().is_field: + raise NotImplementedError("Not implemented") S = R.polynomial_ring() f, df = self.monomial_reduction() g, dg = other.monomial_reduction() @@ -1335,49 +1346,13 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): EXAMPLES:: sage: S. = LaurentPolynomialRing(QQ) - sage: f = inverse_mod(t^2 + 1, t^3 + 1); f - -1/2*t^2 - 1/2*t + 1/2 - sage: f * (t^2 + 1) % (t^3 + 1) - 1 - sage: f = t.inverse_mod((t + 1)^7); f - -t^6 - 7*t^5 - 21*t^4 - 35*t^3 - 35*t^2 - 21*t - 7 - sage: (f * t) + (t + 1)^7 + sage: f = inverse_mod(t^-2 + 1, t^-3 + 1); f + 1/2*t^2 - 1/2*t^3 - 1/2*t^4 + sage: f * (t^-2 + 1) + (1/2*t^4 + 1/2*t^3) * (t^-3 + 1) 1 - sage: t.inverse_mod(S.ideal((t + 1)^7)) == f - True - - This also works over inexact rings, but note that due to rounding - error the product may not always exactly equal the constant - polynomial 1 and have extra terms with coefficients close to zero. :: - - sage: # needs sage.modules - sage: R. = RDF[] - sage: epsilon = RDF(1).ulp()*50 # Allow an error of up to 50 ulp - sage: f = inverse_mod(x^2 + 1, x^5 + x + 1); f # abs tol 1e-14 - 0.4*x^4 - 0.2*x^3 - 0.4*x^2 + 0.2*x + 0.8 - sage: poly = f * (x^2 + 1) % (x^5 + x + 1) - sage: # Remove noisy zero terms: - sage: parent(poly)([0.0 if abs(c) <= epsilon else c - ....: for c in poly.coefficients(sparse=False)]) - 1.0 - sage: f = inverse_mod(x^3 - x + 1, x - 2); f - 0.14285714285714285 - sage: f * (x^3 - x + 1) % (x - 2) - 1.0 - sage: g = 5*x^3 + x - 7; m = x^4 - 12*x + 13; f = inverse_mod(g, m); f - -0.0319636125...*x^3 - 0.0383269759...*x^2 - 0.0463050900...*x + 0.346479687... - sage: poly = f*g % m - sage: # Remove noisy zero terms: - sage: parent(poly)([0.0 if abs(c) <= epsilon else c # abs tol 1e-14 - ....: for c in poly.coefficients(sparse=False)]) - 1.0000000000000004 ALGORITHM: Solve the system `as + mt = 1`, returning `s` as the inverse of `a` mod `m`. - - Uses the Euclidean algorithm for exact rings, and solves a linear - system for the coefficients of `s` and `t` for inexact rings (as the - Euclidean algorithm may not converge in that case). """ from sage.rings.ideal import is_Ideal if is_Ideal(m): @@ -1393,41 +1368,15 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): u = a(r) if u.is_unit(): return a.parent()(~u) - if a.parent().is_exact(): - # use xgcd - g, s, _ = a.xgcd(m) - if g == 1: - return s - elif g.is_unit(): - return g.inverse_of_unit() * s - else: - raise ValueError("Impossible inverse modulo") + if not a.parent().is_exact(): + raise NotImplementedError("Not implemented") + g, s, _ = a.xgcd(m) + if g == 1: + return s + elif g.is_unit(): + return g.inverse_of_unit() * s else: - # xgcd may not converge for inexact rings. - # Instead solve for the coefficients of - # s (degree n-1) and t (degree n-2) in - # as + mt = 1 - # as a linear system. - from sage.matrix.constructor import matrix - from sage.modules.free_module_element import vector - a %= m - n = m.degree() - R = a.parent().base_ring() - M = matrix(R, 2*n-1) - # a_i s_j x^{i+j} terms - for i in range(n): - for j in range(n): - M[i+j, j] = a[i] - # m_i t_j x^{i+j} terms - for i in range(n+1): - for j in range(n-1): - M[i+j, j+n] = m[i] - v = vector(R, [R.one()] + [R.zero()]*(2*n-2)) # the constant polynomial 1 - if M.is_invertible(): - x = M.solve_right(v) # there has to be a better way to solve - return a.parent()(list(x)[0:n]) - else: - raise ValueError("Impossible inverse modulo") + raise ValueError("Impossible inverse modulo") def _fraction_pair(self): """ From 1153822b0e99841d74bf629ba51ec5d32ddd5d92 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Thu, 28 Sep 2023 23:41:51 +0200 Subject: [PATCH 051/463] trailing spaces --- src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx index 769608b3ce1..4a5d3b1ea2a 100644 --- a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx @@ -20,14 +20,14 @@ AUTHOR: from sage.matrix.matrix_generic_dense cimport Matrix_generic_dense # from sage.matrix.matrix2 cimport Matrix -# +# # from sage.matrix.constructor import identity_matrix # from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic # from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular # from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular -# +# # from sage.libs.singular.function import singular_function, lib -# +# # from cysignals.signals cimport sig_on, sig_off from sage.matrix.constructor import identity_matrix From cbcc182b07a5f1664826aee23bf8e9712d5eec57 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Fri, 29 Sep 2023 12:16:03 +0200 Subject: [PATCH 052/463] redefine gens_reduced and more doctests --- src/sage/groups/finitely_presented.py | 63 +++++++++---------- .../matrix_laurent_mpolynomial_dense.pyx | 4 +- .../polynomial/laurent_polynomial_ideal.py | 9 +-- 3 files changed, 35 insertions(+), 41 deletions(-) diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index 391cefc336c..2552cc0940c 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -1762,9 +1762,10 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): OUTPUT: - If ``groebner`` is ``False`` a list of ideals defining the characteristic varieties. - If it is ``True``, a list of lists for Gröbner bases for the ideal of each irreducible - component. + A dictionary with keys the indices of the varieties. If ``groebner`` is ``False`` + the values are the ideals defining the characteristic varieties. + If it is ``True``, lists for Gröbner bases for the ideal of each irreducible + component, stopping when the first time a characteristic variety is empty. EXAMPLES:: @@ -1772,39 +1773,37 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): sage: G = FreeGroup(3) / L sage: G.characteristic_varieties(groebner=True) {0: [(0,)], - 1: [(f1 - 1, f2 - 1, f3 - 1), - (f1*f3 + 1, f2 - 1), - (f1*f2 + 1, f3 - 1), - (f2*f3 + 1, f1 - 1), - (f2*f3 + 1, f1 - f2), - (f2*f3 + 1, f1 - f3), - (f1*f3 + 1, f2 - f3)], - 2: [(f1 - 1, f2 - 1, f3 + 1), - (f3^2 + 1, f1 - f3, f2 - f3), - (f1 - 1, f2 - 1, f3 - 1), - (f1 - 1, f2 + 1, f3 - 1), - (f1 + 1, f2 - 1, f3 - 1)], - 3: [(f1 - 1, f2 - 1, f3 - 1)], - 4: []} + 1: [(f1 - 1, f2 - 1, f3 - 1), (f1*f3 + 1, f2 - 1), (f1*f2 + 1, f3 - 1), (f2*f3 + 1, f1 - 1), + (f2*f3 + 1, f1 - f2), (f2*f3 + 1, f1 - f3), (f1*f3 + 1, f2 - f3)], + 2: [(f1 - 1, f2 - 1, f3 - 1), (f1 + 1, f2 - 1, f3 - 1), (f1 - 1, f2 - 1, f3 + 1), + (f3^2 + 1, f1 - f3, f2 - f3), (f1 - 1, f2 + 1, f3 - 1)], + 3: [(f1 - 1, f2 - 1, f3 - 1)], + 4: []} sage: G = FreeGroup(2)/[2*(1,2,-1,-2)] sage: G.characteristic_varieties() - {0: Ideal (0, 0) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field, - 1: Ideal (0, -2*f2 + 2, 2*f1 - 2) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field, - 2: Ideal (f1 - 1, f2 - 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field, - 3: Ideal (0, 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field} + {0: Ideal (0) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field, + 1: Ideal (f2 - 1, f1 - 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field, + 2: Ideal (f2 - 1, f1 - 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field, + 3: Ideal (1) of Multivariate Laurent Polynomial Ring in f1, f2 over Rational Field} sage: G.characteristic_varieties(ring=ZZ) - {0: Ideal (0, 0) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring, - 1: Ideal (0, -2*f2 + 2, 2*f1 - 2) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring, - 2: Ideal (f1 - 1, f2 - 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring, - 3: Ideal (0, 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring} + {0: Ideal (0) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring, + 1: Ideal (2*f2 - 2, 2*f1 - 2) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring, + 2: Ideal (f2 - 1, f1 - 1) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring, + 3: Ideal (1) of Multivariate Laurent Polynomial Ring in f1, f2 over Integer Ring} sage: G = FreeGroup(2)/[(1,2,1,-2,-1,-2)] sage: G.characteristic_varieties() - {0: Ideal (0, 0) of Univariate Laurent Polynomial Ring in f2 over Rational Field, - 1: Ideal (-1 + 2*f2 - 2*f2^2 + f2^3, 1 - 2*f2 + 2*f2^2 - f2^3) of Univariate Laurent Polynomial Ring in f2 over Rational Field, - 2: Ideal (0, 1) of Univariate Laurent Polynomial Ring in f2 over Rational Field, - 3: Ideal (0, 1) of Univariate Laurent Polynomial Ring in f2 over Rational Field} + {0: Ideal (0) of Univariate Laurent Polynomial Ring in f2 over Rational Field, + 1: Ideal (-1 + 2*f2 - 2*f2^2 + f2^3) of Univariate Laurent Polynomial Ring in f2 over Rational Field, + 2: Ideal (1) of Univariate Laurent Polynomial Ring in f2 over Rational Field, + 3: Ideal (1) of Univariate Laurent Polynomial Ring in f2 over Rational Field} sage: G.characteristic_varieties(groebner=True) - {0: [0], 1: [-1 + f2, 1 - f2 + f2^2], 2: [1]} + {0: [0], 1: [-1 + f2, 1 - f2 + f2^2], 2: []} + sage: G = FreeGroup(2)/[3 * (1, ), 2 * (2, )] + sage: G.characteristic_varieties(groebner=True) + {0: [-1 + F1, 1 + F1, 1 - F1 + F1^2, 1 + F1 + F1^2], 1: [1 - F1 + F1^2], 2: []} + sage: G = FreeGroup(2)/[2 * (2, )] + sage: G.characteristic_varieties(groebner=True) + {0: [(f1 + 1,), (f1 - 1,)], 1: [(f1 + 1,), (f1 - 1, f2 - 1)], 2: []} """ A, rels = self.abelian_alexander_matrix(ring=ring, simplified=True) R = A.base_ring() @@ -1824,7 +1823,7 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): J1 = K.ideal([K(p.subs(eval_1)) for p in J.gens()]) if J1: J *= ideal_1 - res[j] = J + res[j] = R.ideal(J.gens_reduced()) if not groebner or not ring.is_field(): return res if R.ngens() == 1: @@ -1840,7 +1839,7 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): if fct: char_var[j] = fct else: - char_var[j] = [R(1)] + char_var[j] = [] strict = False j += 1 return char_var diff --git a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx index 4a5d3b1ea2a..3f0c1e968f2 100644 --- a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx @@ -6,11 +6,11 @@ optimized for speed only some methods were added. AUTHOR: -* Martin Albrecht +* Enrique Artal """ # ***************************************************************************** -# Copyright (C) 2013 Martin Albrecht +# Copyright (C) 2023 Enrique Artal # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 991a3fa589c..5c938466e1c 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -206,13 +206,8 @@ def __contains__(self, f): def gens_reduced(self): R = self.ring() - if R.ngens() > 1 or not R.base_ring().is_field(): - return self.gens() - gns = self.gens() - res = R(0) - for p in gns: - res = res.gcd(p) - return (res, ) + J = self.polynomial_ideal() + return tuple(R(p) for p in J.gens()) # Operations on ideals From fbb77c49de41e3d94404ea6861f0d2bab932175d Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Fri, 29 Sep 2023 15:47:12 +0200 Subject: [PATCH 053/463] sum of ideals --- src/sage/groups/finitely_presented.py | 4 ++-- src/sage/rings/polynomial/laurent_polynomial_ideal.py | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index 2552cc0940c..5b16bd3a7aa 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -1817,8 +1817,8 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): id_rels = R.ideal(rels) res = dict() for j in range(n + 2): - # J = id_rels + A.fitting_ideal(j) - J = R.ideal(id_rels.gens() + A.fitting_ideal(j).gens()) + J = id_rels + A.fitting_ideal(j) + # J = R.ideal(id_rels.gens() + A.fitting_ideal(j).gens()) if j <= n1: J1 = K.ideal([K(p.subs(eval_1)) for p in J.gens()]) if J1: diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 5c938466e1c..d8af3c8685d 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -95,10 +95,11 @@ def __init__(self, ring, gens, coerce=True, hint=None): self._poly_ring = ring.polynomial_ring() self._poly_ideal = None # Create only as needed self._saturated = False - if hint is None: - self._hint = self._poly_ring.zero_ideal() - else: - self._hint = hint.change_ring(self._poly_ring) + self._hint = self._poly_ring.ideal([f._fraction_pair()[0] for f in self.gens()]) + # if hint is None: + # self._hint = self._poly_ring.zero_ideal() + # else: + # self._hint = hint.change_ring(self._poly_ring) def set_hint(self, hint): """ From 56734816a8ba6e0784b23bca3b59ab5735ce9ef7 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sat, 30 Sep 2023 10:22:53 +0200 Subject: [PATCH 054/463] change hint definition --- src/sage/rings/polynomial/laurent_polynomial_ideal.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index d8af3c8685d..bea4b8bb76a 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -95,7 +95,7 @@ def __init__(self, ring, gens, coerce=True, hint=None): self._poly_ring = ring.polynomial_ring() self._poly_ideal = None # Create only as needed self._saturated = False - self._hint = self._poly_ring.ideal([f._fraction_pair()[0] for f in self.gens()]) + self._hint = self._poly_ring.ideal([f.monomial_reduction()[0] for f in self.gens()]) # if hint is None: # self._hint = self._poly_ring.zero_ideal() # else: @@ -115,7 +115,7 @@ def set_hint(self, hint): sage: P. = LaurentPolynomialRing(QQ, 3) sage: I = P.ideal([x^2*y + 3*x*y^2]) sage: I.hint() - Ideal (0) of Multivariate Polynomial Ring in x, y, z over Rational Field + Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y, z over Rational Field sage: I.set_hint(P.polynomial_ring().ideal([x + 3*y])) sage: I.hint() Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y, z over Rational Field @@ -136,7 +136,7 @@ def hint(self): sage: P. = LaurentPolynomialRing(QQ, 3) sage: I = P.ideal([x^2*y + 3*x*y^2]) sage: I.hint() - Ideal (0) of Multivariate Polynomial Ring in x, y, z over Rational Field + Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y, z over Rational Field """ return self._hint From 9e9185cac2e9790e683d62f61d1d5506ef42b926 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 1 Oct 2023 10:40:41 +0200 Subject: [PATCH 055/463] undo format changes for finitely_presented.py --- src/sage/groups/finitely_presented.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index 5b16bd3a7aa..a961df9a4c5 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -1550,12 +1550,12 @@ def sorted_presentation(self): C = [rel] for j in range(len(rel) - 1): C.append(rel[j + 1:] + rel[:j + 1]) - C1 = [tuple(-j for j in reversed(l1)) for l1 in C] + C1 = [tuple(-j for j in reversed(l)) for l in C] C += C1 C.sort() L1.append(C[0]) L1.sort() - return F / L1 + return F/L1 def epimorphisms(self, H): r""" From b498b59c637d094bff24eb0036d1cfaf7985f91b Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 1 Oct 2023 10:49:39 +0200 Subject: [PATCH 056/463] undo format changes for matrix2.pyx --- src/sage/matrix/matrix2.pyx | 731 ++++++++++++++++++------------------ 1 file changed, 357 insertions(+), 374 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index a872e2264a2..86aca6e00d8 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -209,10 +209,10 @@ cdef class Matrix(Matrix1): from sage.matrix.constructor import matrix if self.is_sparse(): return matrix({ij: self[ij].subs(*args, **kwds) for ij in self.nonzero_positions()}, - nrows=self._nrows, ncols=self._ncols, sparse=True) + nrows=self._nrows, ncols=self._ncols, sparse=True) else: return matrix([a.subs(*args, **kwds) for a in self.list()], - nrows=self._nrows, ncols=self._ncols, sparse=False) + nrows=self._nrows, ncols=self._ncols, sparse=False) def solve_left(self, B, check=True): """ @@ -890,8 +890,8 @@ cdef class Matrix(Matrix1): # Elements of SR "remember" whether or not they are exact. # If every element in the system is exact, we can probably # still check the solution over the inexact ring SR. - check = (check and all(e.is_exact() - for e in self.list() + B.list())) + check = (check and all( e.is_exact() + for e in self.list() + B.list() )) else: check = (check and K.is_exact()) @@ -975,7 +975,7 @@ cdef class Matrix(Matrix1): raise NotFullRankError D = self.augment(B) D.echelonize() - return D.matrix_from_columns(range(self.ncols(), D.ncols())) + return D.matrix_from_columns(range(self.ncols(),D.ncols())) def pivot_rows(self): """ @@ -1075,8 +1075,8 @@ cdef class Matrix(Matrix1): for row from 0 <= row < self._nrows: tmp = [] for c in cols: - # if c<0 or c >= self._ncols: - # raise IndexError("matrix column index out of range") +# if c<0 or c >= self._ncols: +# raise IndexError("matrix column index out of range") tmp.append(self.get_unsafe(row, c)) pr = pr * sum(tmp) return pr @@ -1173,10 +1173,7 @@ cdef class Matrix(Matrix1): sage: A.elementwise_product(vector(ZZ, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: - 'Full MatrixSpace of 5 by 10 dense matrices over Integer Ring' - and 'Ambient free module of rank 4 over the principal ideal - domain Integer Ring' + TypeError: no common canonical parent for objects with parents: 'Full MatrixSpace of 5 by 10 dense matrices over Integer Ring' and 'Ambient free module of rank 4 over the principal ideal domain Integer Ring' sage: A = matrix(2, 2, range(4)) sage: A.elementwise_product(polygen(parent(A))) @@ -1191,11 +1188,7 @@ cdef class Matrix(Matrix1): sage: A.elementwise_product(B) Traceback (most recent call last): ... - TypeError: no common canonical parent - for objects with parents: 'Full MatrixSpace of - 5 by 10 dense matrices over Integer Ring' and - 'Full MatrixSpace of 10 by 5 dense matrices over - Integer Ring' + TypeError: no common canonical parent for objects with parents: 'Full MatrixSpace of 5 by 10 dense matrices over Integer Ring' and 'Full MatrixSpace of 10 by 5 dense matrices over Integer Ring' Some pairs of rings do not have a common parent where multiplication makes sense. This will raise an error. :: @@ -1393,7 +1386,7 @@ cdef class Matrix(Matrix1): m = self._nrows n = self._ncols if not m <= n: - raise ValueError("must have m <= n, but m (=%s) and n (=%s)" % (m, n)) + raise ValueError("must have m <= n, but m (=%s) and n (=%s)"%(m,n)) for r from 1 <= r < m+1: lst = _choose(n, r) @@ -1514,8 +1507,8 @@ cdef class Matrix(Matrix1): return R.zero() pm = 0 - for cols in _choose(n, k): - for rows in _choose(m, k): + for cols in _choose(n,k): + for rows in _choose(m,k): pm = pm + self.matrix_from_rows_and_columns(rows, cols).permanent() return pm @@ -1824,14 +1817,14 @@ cdef class Matrix(Matrix1): ....: if v != [1, 16, 78, 128, 53]: ....: print("ERROR with algorithm={} use_complement=False".format(algorithm)) """ - cdef Py_ssize_t i, j + cdef Py_ssize_t i,j cdef unsigned int num_ones cdef int m = self._nrows cdef int n = self._ncols cdef int mn = min(m, n) cdef Matrix B zero = self.base_ring().zero() - one = self.base_ring().one() + one = self.base_ring().one() if algorithm is None: algorithm = "ButeraPernici" @@ -1845,7 +1838,7 @@ cdef class Matrix(Matrix1): num_ones = 1 for i in range(m): for j in range(n): - x = self.get_unsafe(i, j) + x = self.get_unsafe(i,j) if x != zero: if x != one: z2 = False @@ -1857,7 +1850,7 @@ cdef class Matrix(Matrix1): break if not z2 and (complement or algorithm == "Godsil"): - raise ValueError("coefficients must be zero or one, but we have '{}' in position ({},{}).".format(x, i, j)) + raise ValueError("coefficients must be zero or one, but we have '{}' in position ({},{}).".format(x,i,j)) if use_complement is None: use_complement = z2 and num_ones > 0.55 * m * n @@ -1871,7 +1864,7 @@ cdef class Matrix(Matrix1): complement = not complement elif algorithm == "Ryser": - b = [self.permanental_minor(k, algorithm="Ryser") + b = [self.permanental_minor(k,algorithm="Ryser") for k in range(mn + 1)] elif algorithm == "ButeraPernici": @@ -1960,9 +1953,9 @@ cdef class Matrix(Matrix1): all_rows = range(self.nrows()) all_cols = range(self.ncols()) m = [] - for rows in Combinations(all_rows, k): - for cols in Combinations(all_cols, k): - m.append(self.matrix_from_rows_and_columns(rows, cols).determinant()) + for rows in Combinations(all_rows,k): + for cols in Combinations(all_cols,k): + m.append(self.matrix_from_rows_and_columns(rows,cols).determinant()) return m def det(self, *args, **kwds): @@ -2120,13 +2113,13 @@ cdef class Matrix(Matrix1): if n == 0: d = R.one() elif n == 1: - d = self.get_unsafe(0, 0) + d = self.get_unsafe(0,0) elif n == 2: - d = self.get_unsafe(0, 0)*self.get_unsafe(1, 1) - self.get_unsafe(1, 0)*self.get_unsafe(0, 1) + d = self.get_unsafe(0,0)*self.get_unsafe(1,1) - self.get_unsafe(1,0)*self.get_unsafe(0,1) elif n == 3: - d = self.get_unsafe(0, 0) * (self.get_unsafe(1, 1)*self.get_unsafe(2, 2) - self.get_unsafe(1, 2)*self.get_unsafe(2, 1)) \ - - self.get_unsafe(1, 0) * (self.get_unsafe(0, 1)*self.get_unsafe(2, 2) - self.get_unsafe(0, 2)*self.get_unsafe(2, 1)) \ - + self.get_unsafe(2, 0) * (self.get_unsafe(0, 1)*self.get_unsafe(1, 2) - self.get_unsafe(0, 2)*self.get_unsafe(1, 1)) + d = self.get_unsafe(0,0) * (self.get_unsafe(1,1)*self.get_unsafe(2,2) - self.get_unsafe(1,2)*self.get_unsafe(2,1)) \ + - self.get_unsafe(1,0) * (self.get_unsafe(0,1)*self.get_unsafe(2,2) - self.get_unsafe(0,2)*self.get_unsafe(2,1)) \ + + self.get_unsafe(2,0) * (self.get_unsafe(0,1)*self.get_unsafe(1,2) - self.get_unsafe(0,2)*self.get_unsafe(1,1)) self.cache('det', d) return d @@ -2140,7 +2133,7 @@ cdef class Matrix(Matrix1): d = R(self.__pari__().matdet()) else: # Lift to ZZ and compute there. - d = R(self.apply_map(lambda x: x.lift_centered()).det()) + d = R(self.apply_map(lambda x : x.lift_centered()).det()) self.cache('det', d) return d @@ -2196,18 +2189,18 @@ cdef class Matrix(Matrix1): """ cdef Py_ssize_t i if level == 2: - return self.get_unsafe(0, 0) * self.get_unsafe(1, 1) - self.get_unsafe(0, 1) * self.get_unsafe(1, 0) + return self.get_unsafe(0,0) * self.get_unsafe(1,1) - self.get_unsafe(0,1) * self.get_unsafe(1,0) else: level -= 1 - d = self.get_unsafe(level, level) * self._det_by_minors(level) + d = self.get_unsafe(level,level) * self._det_by_minors(level) # on each iteration, row i will be missing in the first (level) rows # swapping is much faster than taking submatrices for i from level > i >= 0: self.swap_rows(level, i) if (level - i) % 2: - d -= self.get_unsafe(level, level) * self._det_by_minors(level) + d -= self.get_unsafe(level,level) * self._det_by_minors(level) else: - d += self.get_unsafe(level, level) * self._det_by_minors(level) + d += self.get_unsafe(level,level) * self._det_by_minors(level) # undo all our permutations to get us back to where we started for i from 0 <= i < level: self.swap_rows(level, i) @@ -2658,7 +2651,7 @@ cdef class Matrix(Matrix1): """ M = self.parent().change_ring(phi.codomain()) if self.is_sparse(): - values = {(i, j): phi(z) for (i, j), z in self.dict()} + values = {(i,j): phi(z) for (i,j),z in self.dict()} else: values = [phi(z) for z in self.list()] image = M(values) @@ -2767,7 +2760,7 @@ cdef class Matrix(Matrix1): return self.dense_matrix() if self.is_sparse(): - values = {(i, j): phi(v) for (i, j), v in self.dict().iteritems()} + values = {(i,j): phi(v) for (i,j),v in self.dict().iteritems()} if R is None: R = sage.structure.sequence.Sequence(values.values()).universe() else: @@ -2785,7 +2778,7 @@ cdef class Matrix(Matrix1): else: from sage.matrix.matrix_space import MatrixSpace M = MatrixSpace(R, self._nrows, - self._ncols, sparse=sparse) + self._ncols, sparse=sparse) image = M(values) if self._subdivisions is not None: image.subdivide(*self.subdivisions()) @@ -2896,7 +2889,7 @@ cdef class Matrix(Matrix1): # At least check that the minimal polynomial kills the matrix tester.assertTrue(self.minpoly().subs(x=self).is_zero()) - def charpoly(self, var='x', algorithm=None): + def charpoly(self, var = 'x', algorithm = None): r""" Returns the characteristic polynomial of self, as a polynomial over the base ring. @@ -3091,7 +3084,7 @@ cdef class Matrix(Matrix1): self.cache('charpoly', f) return f - def _charpoly_df(self, var='x'): + def _charpoly_df(self, var = 'x'): r""" Computes the characteristic polynomial of ``self`` without divisions. @@ -3179,10 +3172,10 @@ cdef class Matrix(Matrix1): # Extract parameters # - cdef Matrix M = self - n = M._ncols - R = M._base_ring - S = PolynomialRing(R, var) + cdef Matrix M = self + n = M._ncols + R = M._base_ring + S = PolynomialRing(R, var) # Corner cases # N.B. We already tested for M to be square, hence we do not need to @@ -3207,11 +3200,11 @@ cdef class Matrix(Matrix1): from sage.matrix.constructor import matrix F = [R.zero()] * n - cdef Matrix a = matrix(R, n - 1, n) + cdef Matrix a = matrix(R, n-1, n) A = [R.zero()] * n F[0] = - M.get_unsafe(0, 0) - for t in range(1, n): + for t in range(1,n): # Set a(1, t) to be M(<=t, t) # @@ -3381,7 +3374,7 @@ cdef class Matrix(Matrix1): [] """ n = min(self.nrows(), self.ncols()) - return [self[i, i] for i in range(n)] + return [self[i,i] for i in range(n)] def trace(self): """ @@ -3418,7 +3411,7 @@ cdef class Matrix(Matrix1): cdef object s s = R(0) for i from 0 <= i < self._nrows: - s = s + self.get_unsafe(i, i) + s = s + self.get_unsafe(i,i) return s def trace_of_product(self, Matrix other): @@ -3476,11 +3469,11 @@ cdef class Matrix(Matrix1): H = self.change_ring(K) H.hessenbergize() except TypeError as msg: - raise TypeError("%s\nHessenberg form only possible for matrices over a field" % msg) + raise TypeError("%s\nHessenberg form only possible for matrices over a field"%msg) else: H = self.__copy__() H.hessenbergize() - # end if + #end if self.cache('hessenberg_form', H) return H @@ -3524,7 +3517,7 @@ cdef class Matrix(Matrix1): cdef Py_ssize_t i, j, m, n, r n = self._nrows - tm = verbose("Computing Hessenberg Normal Form of %sx%s matrix" % (n, n)) + tm = verbose("Computing Hessenberg Normal Form of %sx%s matrix"%(n,n)) if not self.is_square(): raise TypeError("self must be square") @@ -3551,20 +3544,20 @@ cdef class Matrix(Matrix1): if i != -1: # Found a nonzero entry in column m-1 that is strictly below row m # Now set i to be the first nonzero position >= m in column m-1 - if not self.get_is_zero_unsafe(m, m - 1): + if not self.get_is_zero_unsafe(m,m-1): i = m - t = self.get_unsafe(i, m - 1) + t = self.get_unsafe(i,m-1) t_inv = None if i > m: - self.swap_rows_c(i, m) + self.swap_rows_c(i,m) # We must do the corresponding column swap to # maintain the characteristic polynomial (which is # an invariant of Hessenberg form) - self.swap_columns_c(i, m) + self.swap_columns_c(i,m) # Now the nonzero entry in position (m,m-1) is t. # Use t to clear the entries in column m-1 below m. for j from m+1 <= j < n: - x = self.get_unsafe(j, m - 1) + x = self.get_unsafe(j, m-1) if x != zero: if t_inv is None: t_inv = one / t @@ -3575,7 +3568,7 @@ cdef class Matrix(Matrix1): # column m, and we're only worried about column m-1 right now. # Add u*column_j to column_m. self.add_multiple_of_column_c(m, j, u, 0) - verbose("Finished Hessenberg Normal Form of %sx%s matrix" % (n, n), tm) + verbose("Finished Hessenberg Normal Form of %sx%s matrix"%(n,n),tm) def _charpoly_hessenberg(self, var): """ @@ -3626,9 +3619,9 @@ cdef class Matrix(Matrix1): n = self._nrows cdef Matrix c - c = H.new_matrix(nrows=n + 1, ncols=n + 1) # the 0 matrix + c = H.new_matrix(nrows=n+1,ncols=n+1) # the 0 matrix one = H._coerce_element(1) - c.set_unsafe(0, 0, one) + c.set_unsafe(0,0,one) for m from 1 <= m <= n: # Set the m-th row of c to (x - H[m-1,m-1])*c[m-1] = x*c[m-1] - H[m-1,m-1]*c[m-1] @@ -3636,21 +3629,20 @@ cdef class Matrix(Matrix1): # shifted to the right by one. We then add # -H[m-1,m-1]*c[m-1] to the resulting m-th row. for i from 1 <= i <= n: - c.set_unsafe(m, i, c.get_unsafe(m - 1, i - 1)) - c.add_multiple_of_row_c(m, m-1, -H.get_unsafe(m - 1, m - 1), 0) + c.set_unsafe(m, i, c.get_unsafe(m-1,i-1)) + c.add_multiple_of_row_c(m, m-1, -H.get_unsafe(m-1, m-1), 0) t = one for i from 1 <= i < m: - t = t * H.get_unsafe(m - i, m - i - 1) + t = t * H.get_unsafe(m-i,m-i-1) # Set the m-th row of c to c[m] - t*H[m-i-1,m-1]*c[m-i-1] - c.add_multiple_of_row_c(m, m - i - 1, -t * H.get_unsafe(m - i - 1, m - 1), 0) + c.add_multiple_of_row_c(m, m-i-1, - t*H.get_unsafe(m-i-1,m-1), 0) # The answer is now the n-th row of c. v = PyList_New(n+1) # this is really sort of v = []..." for i from 0 <= i <= n: # Finally, set v[i] = c[n,i] - o = c.get_unsafe(n, i) - Py_INCREF(o) - PyList_SET_ITEM(v, i, o) + o = c.get_unsafe(n,i) + Py_INCREF(o); PyList_SET_ITEM(v, i, o) R = self._base_ring[var] # polynomial ring over the base ring return R(v) @@ -3768,12 +3760,12 @@ cdef class Matrix(Matrix1): [0 0 1] """ from sage.matrix.matrix_space import MatrixSpace - tm = verbose("computing right kernel matrix over a number field for %sx%s matrix" % (self.nrows(), self.ncols()), level=1) + tm = verbose("computing right kernel matrix over a number field for %sx%s matrix" % (self.nrows(), self.ncols()),level=1) basis = self.__pari__().matker() # Coerce PARI representations into the number field R = self.base_ring() basis = [[R(x) for x in row] for row in basis] - verbose("done computing right kernel matrix over a number field for %sx%s matrix" % (self.nrows(), self.ncols()), level=1, t=tm) + verbose("done computing right kernel matrix over a number field for %sx%s matrix" % (self.nrows(), self.ncols()),level=1,t=tm) return 'pivot-pari-numberfield', MatrixSpace(R, len(basis), ncols=self._ncols)(basis) def _right_kernel_matrix_over_field(self, *args, **kwds): @@ -3827,7 +3819,7 @@ cdef class Matrix(Matrix1): [0 0 1] """ from sage.matrix.matrix_space import MatrixSpace - tm = verbose("computing right kernel matrix over an arbitrary field for %sx%s matrix" % (self.nrows(), self.ncols()), level=1) + tm = verbose("computing right kernel matrix over an arbitrary field for %sx%s matrix" % (self.nrows(), self.ncols()),level=1) E = self.echelon_form(*args, **kwds) pivots = E.pivots() pivots_set = set(pivots) @@ -3856,7 +3848,7 @@ cdef class Matrix(Matrix1): basis.append(v) M = MS(basis, coerce=False) tm = verbose("done computing right kernel matrix over an arbitrary field for %sx%s matrix" - % (self.nrows(), self.ncols()), level=1, t=tm) + % (self.nrows(), self.ncols()),level=1,t=tm) return 'pivot-generic', M def _right_kernel_matrix_over_domain(self): @@ -3920,7 +3912,7 @@ cdef class Matrix(Matrix1): cdef Py_ssize_t i, nrows = self._nrows for i in range(self._ncols): if i >= nrows or d[i, i] == 0: - basis.append(v.column(i)) + basis.append( v.column(i) ) verbose("done computing right kernel matrix over a domain for %sx%s matrix" % (self.nrows(), self.ncols()), level=1, t=tm) return 'computed-smith-form', self.new_matrix(nrows=len(basis), ncols=self._ncols, entries=basis) @@ -4511,7 +4503,7 @@ cdef class Matrix(Matrix1): if algorithm is None: algorithm = 'default' elif algorithm not in ['default', 'generic', 'flint', 'pari', 'padic', 'pluq']: - raise ValueError("matrix kernel algorithm '%s' not recognized" % algorithm) + raise ValueError("matrix kernel algorithm '%s' not recognized" % algorithm ) elif algorithm == 'padic' and not (is_IntegerRing(R) or is_RationalField(R)): raise ValueError("'padic' matrix kernel algorithm only available over the rationals and the integers, not over %s" % R) elif algorithm == 'flint' and not (is_IntegerRing(R) or is_RationalField(R)): @@ -4528,7 +4520,7 @@ cdef class Matrix(Matrix1): if basis is None: basis = 'default' elif basis not in ['default', 'computed', 'echelon', 'pivot', 'LLL']: - raise ValueError("matrix kernel basis format '%s' not recognized" % basis) + raise ValueError("matrix kernel basis format '%s' not recognized" % basis ) elif basis == 'pivot' and R not in _Fields: raise ValueError('pivot basis only available over a field, not over %s' % R) elif basis == 'LLL' and not is_IntegerRing(R): @@ -4562,8 +4554,7 @@ cdef class Matrix(Matrix1): # Third: generic first, if requested explicitly # then try specialized class methods, and finally # delegate to ad-hoc methods in greater generality - M = None - format = '' + M = None; format = '' if algorithm == 'generic': format, M = self._right_kernel_matrix_over_field() @@ -4593,7 +4584,7 @@ cdef class Matrix(Matrix1): # zero columns as well. (eg PARI?) This could be fixed at the source # with a careful study of the phenomenon. Start by commenting out # the following and running doctests in sage/matrix - if M.nrows() == 0 and M.ncols() != self.ncols(): + if M.nrows()==0 and M.ncols()!=self.ncols(): M = M.new_matrix(nrows=0, ncols=self.ncols()) # Convert basis to requested type and return the matrix @@ -5156,10 +5147,10 @@ cdef class Matrix(Matrix1): if K is not None: return K - tm = verbose("computing left kernel for %sx%s matrix" % (self.nrows(), self.ncols()), level=1) + tm = verbose("computing left kernel for %sx%s matrix" % (self.nrows(), self.ncols()),level=1) K = self.transpose().right_kernel(*args, **kwds) self.cache('left_kernel', K) - verbose("done computing left kernel for %sx%s matrix" % (self.nrows(), self.ncols()), level=1, t=tm) + verbose("done computing left kernel for %sx%s matrix" % (self.nrows(), self.ncols()),level=1,t=tm) return K kernel = left_kernel @@ -5531,15 +5522,15 @@ cdef class Matrix(Matrix1): False) ] """ if algorithm == 'kernel' or self.base_ring() not in _Fields: - return self._decomposition_using_kernels(is_diagonalizable=is_diagonalizable, dual=dual) + return self._decomposition_using_kernels(is_diagonalizable = is_diagonalizable, dual=dual) elif algorithm == 'spin': - X = self._decomposition_spin_generic(is_diagonalizable=is_diagonalizable) + X = self._decomposition_spin_generic(is_diagonalizable = is_diagonalizable) if dual: - Y = self.transpose()._decomposition_spin_generic(is_diagonalizable=is_diagonalizable) + Y = self.transpose()._decomposition_spin_generic(is_diagonalizable = is_diagonalizable) return X, Y return X else: - raise ValueError("no algorithm '%s'" % algorithm) + raise ValueError("no algorithm '%s'"%algorithm) def _decomposition_spin_generic(self, is_diagonalizable=False): r""" @@ -5569,13 +5560,13 @@ cdef class Matrix(Matrix1): if len(F) == 1: V = self.base_ring()**self.nrows() - return decomp_seq([(V, F[0][1] == 1)]) + return decomp_seq([(V,F[0][1]==1)]) V = self.base_ring()**self.nrows() v = V.random_element() num_iterates = max([0] + [f.degree() - g.degree() for g, _ in F if g.degree() > 1]) + 1 - S = [] + S = [ ] F.sort() for i in range(len(F)): @@ -5585,11 +5576,11 @@ cdef class Matrix(Matrix1): # Just use kernel -- much easier. B = self.__copy__() for k from 0 <= k < self.nrows(): - B[k, k] += g[0] + B[k,k] += g[0] if m > 1 and not is_diagonalizable: B = B**m W = B.kernel() - E.append((W, m == 1)) + E.append((W, m==1)) continue # General case, i.e., deg(g) > 1: @@ -5602,40 +5593,40 @@ cdef class Matrix(Matrix1): v = h.list() while len(S) < tries: - t = verbose('%s-spinning %s-th random vector' % (num_iterates, len(S)), level=2, caller_name='generic spin decomp') + t = verbose('%s-spinning %s-th random vector'%(num_iterates, len(S)), level=2, caller_name='generic spin decomp') S.append(self.iterates(V.random_element(), num_iterates)) verbose('done spinning', level=2, t=t, caller_name='generic spin decomp') for j in range(0 if W is None else W.nrows() // g.degree(), len(S)): # Compute one element of the kernel of g(A)**m. - t = verbose('compute element of kernel of g(A), for g of degree %s' % g.degree(), level=2, + t = verbose('compute element of kernel of g(A), for g of degree %s'%g.degree(),level=2, caller_name='generic spin decomp') w = S[j].linear_combination_of_rows(h.list()) - t = verbose('done computing element of kernel of g(A)', t=t, level=2, caller_name='generic spin decomp') + t = verbose('done computing element of kernel of g(A)', t=t,level=2, caller_name='generic spin decomp') # Get the rest of the kernel. - t = verbose('fill out rest of kernel', level=2, caller_name='generic spin decomp') + t = verbose('fill out rest of kernel',level=2, caller_name='generic spin decomp') if W is None: W = self.iterates(w, g.degree()) else: W = W.stack(self.iterates(w, g.degree())) - t = verbose('finished filling out more of kernel', level=2, t=t, caller_name='generic spin decomp') + t = verbose('finished filling out more of kernel',level=2, t=t, caller_name='generic spin decomp') if W.rank() == m * g.degree(): t = verbose('now computing row space', level=2, caller_name='generic spin decomp') W.echelonize() - E.append((W.row_space(), m == 1)) - verbose('computed row space', level=2, t=t, caller_name='generic spin decomp') + E.append((W.row_space(), m==1)) + verbose('computed row space', level=2,t=t, caller_name='generic spin decomp') break else: - verbose('we have not yet generated all the kernel (rank so far=%s, target rank=%s)' % ( + verbose('we have not yet generated all the kernel (rank so far=%s, target rank=%s)'%( W.rank(), m*g.degree()), level=2, caller_name='generic spin decomp') tries += 1 if tries > 1000*m: # avoid an insanely long infinite loop raise RuntimeError("likely bug in decomposition") # end if - # end while - # end for + #end while + #end for return E def _decomposition_using_kernels(self, is_diagonalizable=False, dual=False): @@ -5659,30 +5650,30 @@ cdef class Matrix(Matrix1): V = self.column_ambient_module() m = F[0][1] if dual: - return decomp_seq([(V, m == 1)]), decomp_seq([(V, m == 1)]) + return decomp_seq([(V, m==1)]), decomp_seq([(V, m==1)]) else: - return decomp_seq([(V, m == 1)]) + return decomp_seq([(V, m==1)]) F.sort() for g, m in f.factor(): - t = verbose('decomposition -- Computing g(self) for an irreducible factor g of degree %s' % g.degree(), level=2) + t = verbose('decomposition -- Computing g(self) for an irreducible factor g of degree %s'%g.degree(),level=2) if is_diagonalizable: B = g(self) else: B = g(self) - t2 = verbose('decomposition -- raising g(self) to the power %s' % m, level=2) + t2 = verbose('decomposition -- raising g(self) to the power %s'%m,level=2) B = B ** m - verbose('done powering', t2) + verbose('done powering',t2) t = verbose('decomposition -- done computing g(self)', level=2, t=t) - E.append((B.kernel(), m == 1)) + E.append((B.kernel(), m==1)) t = verbose('decomposition -- time to compute kernel', level=2, t=t) if dual: - Edual.append((B.transpose().kernel(), m == 1)) + Edual.append((B.transpose().kernel(), m==1)) verbose('decomposition -- time to compute dual kernel', level=2, t=t) if dual: return E, Edual return E - def decomposition_of_subspace(self, M, check_restrict=True, **kwds): + def decomposition_of_subspace(self, M, check_restrict = True, **kwds): """ Suppose the right action of self on M leaves M invariant. Return the decomposition of M as a list of pairs (W, is_irred) where @@ -5758,7 +5749,7 @@ cdef class Matrix(Matrix1): if not self.is_square(): raise ArithmeticError("self must be a square matrix") if M.base_ring() != self.base_ring(): - raise ArithmeticError("base rings must be the same, but self is over %s and module is over %s" % ( + raise ArithmeticError("base rings must be the same, but self is over %s and module is over %s"%( self.base_ring(), M.base_ring())) if M.degree() != self.ncols(): raise ArithmeticError("M must be a subspace of an %s-dimensional space" % self.ncols()) @@ -5766,18 +5757,16 @@ cdef class Matrix(Matrix1): time = verbose(t=0) # 1. Restrict - B = self.restrict(M, check=check_restrict) + B = self.restrict(M, check = check_restrict) time0 = verbose("decompose restriction -- ", time) # 2. Decompose restriction D = B.decomposition(**kwds) - sum_dim = sum([A.dimension() for A, _ in D]) + sum_dim = sum([A.dimension() for A,_ in D]) assert sum_dim == M.dimension(), \ "bug in decomposition; " + \ - "the sum of the dimensions (=%s) of the factors must equal" + \ - "the dimension (%s) of the acted on space:\nFactors found:" + \ - "%s\nSpace: %s" % (sum_dim, M.dimension(), D, M) + "the sum of the dimensions (=%s) of the factors must equal the dimension (%s) of the acted on space:\nFactors found: %s\nSpace: %s"%(sum_dim, M.dimension(), D, M) # 3. Lift decomposition to subspaces of ambient vector space. # Each basis vector for an element of D defines a linear @@ -5847,7 +5836,7 @@ cdef class Matrix(Matrix1): """ if not isinstance(V, sage.modules.free_module.FreeModule_generic): raise TypeError("V must be a free module") - # if V.base_ring() != self.base_ring(): + #if V.base_ring() != self.base_ring(): # raise ValueError("matrix and module must have the same base ring, but matrix is over %s and module is over %s"%(self.base_ring(), V.base_ring())) if V.degree() != self.nrows(): raise IndexError("degree of V (=%s) must equal number of rows of self (=%s)" % (V.degree(), self.nrows())) @@ -6029,8 +6018,7 @@ cdef class Matrix(Matrix1): sage: t.charpoly() # needs sage.libs.pari x^3 - 12*x^2 - 18*x """ - i = int(i) - t = int(t) + i = int(i); t=int(t) if self.nrows() != self.ncols(): raise ArithmeticError("self must be a square matrix") n = self.nrows() @@ -6435,7 +6423,7 @@ cdef class Matrix(Matrix1): if algebraic_multiplicity: return x else: - return Sequence([(e[0], e[1]) for e in x], cr=True, check=False) + return Sequence([(e[0],e[1]) for e in x], cr=True, check=False) # Possible improvements: # algorithm for dual_eigenvector in sage/modular/hecke/module.py @@ -6447,7 +6435,7 @@ cdef class Matrix(Matrix1): G = self.fcp() # factored characteristic polynomial V = [] - i = -1 # variable name index, increments for each eigenvalue + i = -1 # variable name index, increments for each eigenvalue for h, e in G: i = i + 1 if h.degree() == 1: @@ -6459,7 +6447,7 @@ cdef class Matrix(Matrix1): W = A.kernel() V.append((alpha, W.ambient_module().span_of_basis(W.basis()), e)) else: - F = h.root_field('{0}{1}'.format(var, i)) + F = h.root_field('{0}{1}'.format(var,i)) alpha = F.gen(0) A = self.change_ring(F) - alpha W = A.kernel() @@ -6483,7 +6471,7 @@ cdef class Matrix(Matrix1): if algebraic_multiplicity: return V else: - return Sequence([(e[0], e[1]) for e in V], cr=True, check=False) + return Sequence([(e[0],e[1]) for e in V], cr=True, check=False) left_eigenspaces = eigenspaces_left @@ -6687,7 +6675,7 @@ cdef class Matrix(Matrix1): if algebraic_multiplicity: return x else: - return Sequence([(e[0], e[1]) for e in x], cr=True, check=False) + return Sequence([(e[0],e[1]) for e in x], cr=True, check=False) V = self.transpose().eigenspaces_left(format=format, var=var, algebraic_multiplicity=True) @@ -6695,7 +6683,7 @@ cdef class Matrix(Matrix1): if algebraic_multiplicity: return V else: - return Sequence([(e[0], e[1]) for e in V], cr=True, check=False) + return Sequence([(e[0],e[1]) for e in V], cr=True, check=False) right_eigenspaces = eigenspaces_right @@ -6808,7 +6796,7 @@ cdef class Matrix(Matrix1): warn("Using generic algorithm for an inexact ring, which will probably give incorrect results due to numerical precision issues.") if not extend: - return Sequence(r for r, m in self.charpoly().roots() for _ in range(m)) + return Sequence(r for r,m in self.charpoly().roots() for _ in range(m)) # now we need to find a natural algebraic closure for the base ring K = self.base_ring() @@ -6828,7 +6816,7 @@ cdef class Matrix(Matrix1): if f.degree() == 1: res.extend([-f.constant_coefficient()]*e) else: - for r, ee in f.change_ring(A).roots(): + for r,ee in f.change_ring(A).roots(): res.extend([r]*(e*ee)) eigenvalues = Sequence(res) @@ -6938,7 +6926,7 @@ cdef class Matrix(Matrix1): from sage.categories.homset import hom eigenspaces = self.eigenspaces_left(format='galois', algebraic_multiplicity=True) - evec_list = [] + evec_list=[] n = self._nrows evec_eval_list = [] F = self.base_ring().fraction_field() @@ -6960,7 +6948,7 @@ cdef class Matrix(Matrix1): m = hom(eigval.parent(), e.parent(), e) space = (e.parent())**n evec_list = [(space)([m(i) for i in v]) for v in eigbasis] - evec_eval_list.append((e, evec_list, eigmult)) + evec_eval_list.append( (e, evec_list, eigmult)) return evec_eval_list @@ -7242,7 +7230,7 @@ cdef class Matrix(Matrix1): "failed to compute eigenvectors for eigenvalue %s, " "check eigenvectors_left() for partial results" % e[0]) P = matrix(rows) - return D, P + return D,P left_eigenmatrix = eigenmatrix_left @@ -7410,9 +7398,9 @@ cdef class Matrix(Matrix1): True """ - D, P = self.transpose().eigenmatrix_left(None if other is None - else other.transpose()) - return D, P.transpose() + D,P = self.transpose().eigenmatrix_left(None if other is None + else other.transpose()) + return D,P.transpose() right_eigenmatrix = eigenmatrix_right @@ -7628,7 +7616,7 @@ cdef class Matrix(Matrix1): d = self.dense_matrix().echelon_form(**kwds) for c from 0 <= c < self.ncols(): for r from 0 <= r < self.nrows(): - self.set_unsafe(r, c, d.get_unsafe(r, c)) + self.set_unsafe(r, c, d.get_unsafe(r,c)) self.clear_cache() self.cache('pivots', d.pivots()) self.cache('in_echelon_form', True) @@ -7636,11 +7624,11 @@ cdef class Matrix(Matrix1): try: a, d, p = self._echelon_form_PID() except TypeError as msg: - raise NotImplementedError("%s\nechelon form over %s not yet implemented" % (msg, self.base_ring())) + raise NotImplementedError("%s\nechelon form over %s not yet implemented"%(msg, self.base_ring())) for c from 0 <= c < self.ncols(): for r from 0 <= r < self.nrows(): - self.set_unsafe(r, c, d.get_unsafe(r, c)) + self.set_unsafe(r, c, d.get_unsafe(r,c)) self.clear_cache() self.cache('pivots', tuple(p)) self.cache('in_echelon_form', True) @@ -7840,7 +7828,7 @@ cdef class Matrix(Matrix1): kwds['algorithm'] = algorithm return self._echelonize_ring(**kwds) except ArithmeticError as msg: - raise NotImplementedError("%s\nEchelon form not implemented over '%s'." % (msg, basring)) + raise NotImplementedError("%s\nEchelon form not implemented over '%s'."%(msg,basring)) def echelon_form(self, algorithm="default", cutoff=0, **kwds): r""" @@ -7935,7 +7923,7 @@ cdef class Matrix(Matrix1): if algorithm == 'default': v = E.echelonize(cutoff=cutoff, **kwds) else: - v = E.echelonize(algorithm=algorithm, cutoff=cutoff, **kwds) + v = E.echelonize(algorithm = algorithm, cutoff=cutoff, **kwds) E.set_immutable() # so we can cache the echelon form. self.cache('echelon_form', E) if v is not None: @@ -8137,21 +8125,21 @@ cdef class Matrix(Matrix1): if algorithm == 'partial_pivoting': for r in range(start_row, nr): - abs_val = A.get_unsafe(r, c).abs() + abs_val = A.get_unsafe(r,c).abs() if abs_val > max_abs_val: max_abs_val = abs_val best_r = r elif algorithm == 'scaled_partial_pivoting': for r in range(start_row, nr): if scale_factors[r]: - abs_val = A.get_unsafe(r, c).abs() / scale_factors[r] + abs_val = A.get_unsafe(r,c).abs() / scale_factors[r] if abs_val > max_abs_val: max_abs_val = abs_val best_r = r - else: # algorithm == 'scaled_partial_pivoting_valuation': + else: # algorithm == 'scaled_partial_pivoting_valuation': for r in range(start_row, nr): if scale_factors[r] is not None: - abs_val = scale_factors[r] - A.get_unsafe(r, c).valuation() + abs_val = scale_factors[r] - A.get_unsafe(r,c).valuation() if max_abs_val is None or abs_val > max_abs_val: max_abs_val = abs_val best_r = r @@ -8493,7 +8481,7 @@ cdef class Matrix(Matrix1): permutations.append( (PermutationGroupElement([p(1 + i) for i in range(nrows)]), PermutationGroupElement([p(1 + nrows + i) - nrows for i in range(ncols)]) - )) + )) return permutations def permutation_normal_form(self, check=False): @@ -8600,14 +8588,14 @@ cdef class Matrix(Matrix1): # Sort each row with respect to S for the first matrix in X = MS X = copy(MS) SM = [sorted([(S[j], X[0][k][j]) for j in range(ncols)], reverse=True) - for k in range(l, nrows)] + for k in range(l, nrows)] SM = [[k[1] for k in s] for s in SM] # and pick the maximal row b = max(SM) # Find all rows equal to the maximal (potential new cases) m = [[j for j in range(nrows - l) if SM[j] == b]] - w = 0 # keeps track of how many entries we have removed from MS + w = 0 # keeps track of how many entries we have removed from MS # Let us find the maximal row in each of the entries in X = MS for i in range(1, len(X)): SN = [sorted([(S[j], X[i][k][j]) for j in range(ncols)], reverse=True) @@ -8743,7 +8731,7 @@ cdef class Matrix(Matrix1): truth, perm = N_B.is_isomorphic(M_B, certificate=True, edge_labels=True) from sage.groups.perm_gps.constructor import PermutationGroupElement if perm: - s = sorted(perm.items(), key=lambda x: x[0]) + s = sorted(perm.items(), key=lambda x:x[0]) row_perms = [value for k, value in s if k <= nrows] col_perms = [value - nrows for k, value in s if k > nrows] perm = (PermutationGroupElement(row_perms), PermutationGroupElement(col_perms)) @@ -8794,15 +8782,16 @@ cdef class Matrix(Matrix1): output = self.new_matrix(self._nrows, right._ncols) # The following used to be a little faster, but meanwhile # the previous line is faster. - # if self.is_sparse(): + #if self.is_sparse(): # output = self.matrix_space(self._nrows, right._ncols, sparse = True)(0) - # else: + #else: # output = self.matrix_space(self._nrows, right._ncols, sparse = False).zero_matrix().__copy__() - self_window = self.matrix_window() - right_window = right.matrix_window() + self_window = self.matrix_window() + right_window = right.matrix_window() output_window = output.matrix_window() + from . import strassen strassen.strassen_window_multiply(output_window, self_window, right_window, cutoff) return output @@ -8824,7 +8813,7 @@ cdef class Matrix(Matrix1): [ 0 0 0 0] [ 0 0 0 0] """ - tm = verbose('strassen echelon of %s x %s matrix' % (self._nrows, self._ncols)) + tm = verbose('strassen echelon of %s x %s matrix'%(self._nrows, self._ncols)) self.check_mutability() @@ -8847,8 +8836,8 @@ cdef class Matrix(Matrix1): verbose('done with strassen', tm) cpdef matrix_window(self, Py_ssize_t row=0, Py_ssize_t col=0, - Py_ssize_t nrows=-1, Py_ssize_t ncols=-1, - bint check=1): + Py_ssize_t nrows=-1, Py_ssize_t ncols=-1, + bint check=1): """ Return the requested matrix window. @@ -9102,7 +9091,7 @@ cdef class Matrix(Matrix1): """ if self._subdivisions is None: self._subdivisions = ([0, self._nrows], [0, self._ncols]) - key = "subdivision %s %s" % (i, j) + key = "subdivision %s %s"%(i,j) sd = self.fetch(key) if sd is None: sd = self[self._subdivisions[0][i]:self._subdivisions[0][i+1], @@ -9148,13 +9137,13 @@ cdef class Matrix(Matrix1): """ if self._subdivisions is None: if not i and not j: - return self[x, y] + return self[x,y] else: - raise IndexError("No such submatrix %s, %s" % (i, j)) + raise IndexError("No such submatrix %s, %s"%(i,j)) if x >= self._subdivisions[0][i+1]-self._subdivisions[0][i] or \ y >= self._subdivisions[1][j+1]-self._subdivisions[1][j]: - raise IndexError("Submatrix %s,%s has no entry %s,%s" % (i, j, x, y)) - return self[self._subdivisions[0][i] + x, self._subdivisions[1][j] + y] + raise IndexError("Submatrix %s,%s has no entry %s,%s"%(i,j, x, y)) + return self[self._subdivisions[0][i] + x , self._subdivisions[1][j] + y] def _subdivide_on_augment(self, left, right): r""" @@ -9465,7 +9454,7 @@ cdef class Matrix(Matrix1): for i from 0 <= i < self._nrows: for j from 0 <= j < self._ncols: self.set_unsafe(i, j, R._random_nonzero_element(*args, - **kwds)) + **kwds)) else: num = int(self._nrows * self._ncols * density) for i from 0 <= i < num: @@ -9505,7 +9494,7 @@ cdef class Matrix(Matrix1): """ return self.is_scalar(self.base_ring().one()) - def is_scalar(self, a=None): + def is_scalar(self, a = None): """ Return True if this matrix is a scalar matrix. @@ -9540,13 +9529,13 @@ cdef class Matrix(Matrix1): if a is None: if self._nrows == 0: return True - a = self.get_unsafe(0, 0) + a = self.get_unsafe(0,0) else: a = self.base_ring()(a) for i in range(self._nrows): for j in range(self._ncols): if i != j: - if not self.get_unsafe(i, j).is_zero(): + if not self.get_unsafe(i,j).is_zero(): return False else: if self.get_unsafe(i, i) != a: @@ -9583,7 +9572,7 @@ cdef class Matrix(Matrix1): for i in range(self._nrows): for j in range(self._ncols): if i != j: - if not self.get_unsafe(i, j).is_zero(): + if not self.get_unsafe(i,j).is_zero(): return False return True @@ -9693,7 +9682,7 @@ cdef class Matrix(Matrix1): P = self.transpose() * self # Orthogonal return P.is_scalar(1) - def is_bistochastic(self, normalized=True): + def is_bistochastic(self, normalized = True): r""" Returns ``True`` if this matrix is bistochastic. @@ -9856,12 +9845,12 @@ cdef class Matrix(Matrix1): cdef Matrix left = self*CT cdef Matrix right = CT*self - cdef Py_ssize_t i, j + cdef Py_ssize_t i,j normal = True # two products are Hermitian, need only check lower triangle for i from 0 <= i < self._nrows: for j from 0 <= j <= i: - if left.get_unsafe(i, j) != right.get_unsafe(i, j): + if left.get_unsafe(i,j) != right.get_unsafe(i,j): normal = False break if not normal: @@ -9978,11 +9967,11 @@ cdef class Matrix(Matrix1): ir = mc ic = mr b = 1.0 - elif max(mr, mc) > maxsize: + elif max(mr,mc) > maxsize: maxsize = float(maxsize) - ir = int(mc * maxsize / max(mr, mc)) - ic = int(mr * maxsize / max(mr, mc)) - b = max(mr, mc) / maxsize + ir = int(mc * maxsize/max(mr,mc)) + ic = int(mr * maxsize/max(mr,mc)) + b = max(mr,mc)/maxsize else: ir = mc ic = mr @@ -9999,7 +9988,7 @@ cdef class Matrix(Matrix1): for _x in range(bi): for _y in range(bi): if not self.get_unsafe((x*b + _x), (y*b + _y)).is_zero(): - v -= 1 # increase darkness + v -= 1 #increase darkness v = (v * fct + 0.5) pixel[y, x] = (v, v, v) return img @@ -10035,7 +10024,7 @@ cdef class Matrix(Matrix1): sage: a.density() 0 """ - cdef int x, y, k + cdef int x,y,k k = 0 nr = self.nrows() nc = self.ncols() @@ -10043,8 +10032,8 @@ cdef class Matrix(Matrix1): return 0 for x from 0 <= x < nr: for y from 0 <= y < nc: - if not self.get_unsafe(x, y).is_zero(): - k += 1 + if not self.get_unsafe(x,y).is_zero(): + k+=1 return QQ(k)/QQ(nr*nc) def inverse(self): @@ -10264,13 +10253,13 @@ cdef class Matrix(Matrix1): This is all left to the method `adjugate`. """ - n = self._ncols + n = self._ncols if self._nrows != n: raise ValueError("self must be a square matrix") A = self.charpoly().shift(-1)(self) - return A if n % 2 else -A + return A if n%2 else -A def QR(self, full=True): r""" @@ -10540,16 +10529,16 @@ cdef class Matrix(Matrix1): scale = sqrt(hip) q = (1/scale)*v Q.append(q) - R[row, i] = scale - for j in range(i + 1, n): - R[row, j] = q.hermitian_inner_product(V[j]) - V[j] = V[j] - R[row, j] * q + R[row,i] = scale + for j in range(i+1, n): + R[row,j] = q.hermitian_inner_product(V[j]) + V[j] = V[j] - R[row,j]*q row = row + 1 except TypeError: raise TypeError('QR decomposition unable to compute square roots in %s' % F) # complete to full orthonormal basis, or reduce to truncated R if full: - Qt = matrix(Q) # as rows here + Qt = matrix(Q) # as rows here if Qt.nrows() == 0: Qt = zero_matrix(F, 0, m) orthogonal = Qt.right_kernel().basis_matrix().transpose() @@ -10698,12 +10687,12 @@ cdef class Matrix(Matrix1): zero = F(0) Bstar = [] R = zero_matrix(F, n) - nnz = 0 # number non-zero rows in R, or number of nonzero vectors in Bstar + nnz = 0 # number non-zero rows in R, or number of nonzero vectors in Bstar for i in range(n): ortho = B[i] for j in range(nnz): - R[j, i] = Bstar[j].hermitian_inner_product(B[i]) / Bstar[j].hermitian_inner_product(Bstar[j]) - ortho = ortho - R[j, i] * Bstar[j] + R[j,i] = Bstar[j].hermitian_inner_product(B[i])/Bstar[j].hermitian_inner_product(Bstar[j]) + ortho = ortho - R[j,i]*Bstar[j] if ortho.hermitian_inner_product(ortho) != zero: Bstar.append(ortho) R[nnz, i] = 1 @@ -11039,8 +11028,7 @@ cdef class Matrix(Matrix1): R = self.base_ring() if isinstance(R, (sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField)): Q, R = self.transpose().QR() - m = R.nrows() - n = R.ncols() + m = R.nrows(); n = R.ncols() if m > n: Q = Q[0:m, 0:n] R = R[0:n, 0:n] @@ -11477,7 +11465,7 @@ cdef class Matrix(Matrix1): blocks = [] for eval, mult in evals: if mult == 1: - blocks.append((eval, 1)) + blocks.append((eval,1)) else: B = A - diagonal_matrix([eval]*n, sparse=sparse) C = B @@ -11506,7 +11494,7 @@ cdef class Matrix(Matrix1): # a Jordan chain for each, adding the chain (a sequence of # vectors) to the entry for the eigenvalue (which is a list). jordan_chains = {} - for eval, _ in evals: + for eval,_ in evals: jordan_chains[eval] = [] # Let B be the matrix `A - eval Id`. @@ -11544,9 +11532,9 @@ cdef class Matrix(Matrix1): # Now ``jordan_chains`` has all the columns of the transformation # matrix; we just need to put them in the right order. jordan_basis = [] - for eval, size in blocks: + for eval,size in blocks: # Find a block with the right size - for index, chain in enumerate(jordan_chains[eval]): + for index,chain in enumerate(jordan_chains[eval]): if len(chain) == size: jordan_basis += jordan_chains[eval].pop(index) break @@ -12604,7 +12592,7 @@ cdef class Matrix(Matrix1): R = self.base_ring() if not is_Vector(v): raise TypeError('first input should be a vector, not {0}'.format(v)) - if not (var is None or isinstance(var, str)): + if not (var is None or isinstance(var, str)): generator = False try: generator = var.is_gen() @@ -12923,7 +12911,7 @@ cdef class Matrix(Matrix1): True """ - cdef Matrix C # output matrix + cdef Matrix C # output matrix C = self.fetch('cholesky') if C is not None: return C @@ -12945,7 +12933,7 @@ cdef class Matrix(Matrix1): cdef Matrix L # block_ldlt() results cdef list d # block_ldlt() results try: - _, L, d = self._block_ldlt(True) + _,L,d = self._block_ldlt(True) except ValueError: # If the matrix was positive-definite, that would # have worked. @@ -12958,7 +12946,7 @@ cdef class Matrix(Matrix1): cdef bint extend = False for X in d: # The X are guaranteed to be one-by-one blocks. - x = X[0, 0] + x = X[0,0] if x <= zero: raise ValueError("matrix is not positive definite") @@ -12985,7 +12973,7 @@ cdef class Matrix(Matrix1): from sage.rings.qqbar import AA try: C = L.change_ring(AA) - except ValueError: # cannot coerce... + except ValueError: # cannot coerce... C = L.change_ring(F_ac) else: C = L.__copy__() @@ -12993,11 +12981,11 @@ cdef class Matrix(Matrix1): # Overwrite the (strict) upper-triangular part of "C", since a # priori it contains junk after _block_ldlt(). zero = C.base_ring().zero() - cdef Py_ssize_t i, j # loop indices + cdef Py_ssize_t i, j # loop indices for i in range(n): C.rescale_col_c(i, splits[i], 0) - for j in range(i + 1, n): - C.set_unsafe(i, j, zero) + for j in range(i+1,n): + C.set_unsafe(i,j,zero) C.set_immutable() self.cache('cholesky', C) return C @@ -13117,7 +13105,7 @@ cdef class Matrix(Matrix1): sage: actual == expected True """ - P, L, D = self.block_ldlt() + P,L,D = self.block_ldlt() # The default "echelonize" inverse() method works just fine for # triangular matrices. @@ -13570,24 +13558,24 @@ cdef class Matrix(Matrix1): # abs() necessary to convert zero to the # correct type for comparisons (Issue #12208) max_entry = abs(zero) - for i in range(k, m): - entry = abs(M.get_unsafe(i, k)) + for i in range(k,m): + entry = abs(M.get_unsafe(i,k)) if entry > max_entry: max_location = i max_entry = entry else: - for i in range(k, m): - if M.get_unsafe(i, k) != zero: + for i in range(k,m): + if M.get_unsafe(i,k) != zero: max_location = i break if max_location != -1: perm[k], perm[max_location] = perm[max_location], perm[k] M.swap_rows(k, max_location) for j in range(k+1, m): - scale = -M.get_unsafe(j, k) / M.get_unsafe(k, k) - M.set_unsafe(j, k, -scale) - for p in range(k + 1, n): - M.set_unsafe(j, p, M.get_unsafe(j, p) + scale * M.get_unsafe(k, p)) + scale = -M.get_unsafe(j,k)/M.get_unsafe(k,k) + M.set_unsafe(j,k, -scale) + for p in range(k+1,n): + M.set_unsafe(j,p, M.get_unsafe(j,p) + scale*M.get_unsafe(k,p)) perm = tuple(perm) M.set_immutable() compact = (perm, M) @@ -13606,11 +13594,11 @@ cdef class Matrix(Matrix1): perm = [perm[i]+1 for i in range(m)] P = sage.combinat.permutation.Permutation(perm).to_matrix() P = P.change_ring(F) - L = M.matrix_space(m, m).identity_matrix().__copy__() + L = M.matrix_space(m,m).identity_matrix().__copy__() for i in range(1, m): - for k in range(min(i, d)): - L[i, k] = M[i, k] - M[i, k] = zero + for k in range(min(i,d)): + L[i,k] = M[i,k] + M[i,k] = zero return P, L, M def _indefinite_factorization(self, algorithm, check=True): @@ -13852,16 +13840,16 @@ cdef class Matrix(Matrix1): t = L.get_unsafe(i, j) if conjugate: for k in range(j): - t -= L.get_unsafe(k, i) * L.get_unsafe(j, k).conjugate() + t -= L.get_unsafe(k,i)*L.get_unsafe(j,k).conjugate() else: for k in range(j): - t -= L.get_unsafe(k, i) * L.get_unsafe(j, k) + t -= L.get_unsafe(k,i)*L.get_unsafe(j,k) if i == j: if not t: - self.cache(cache_string, (False, i + 1)) - return (False, i + 1) + self.cache(cache_string, (False,i+1)) + return (False, i+1) d.append(t) - d_inv.append(one / t) + d_inv.append(one/t) L.set_unsafe(i, i, one) else: L.set_unsafe(j, i, t) @@ -14077,7 +14065,7 @@ cdef class Matrix(Matrix1): if result is not None: return result - cdef Py_ssize_t i, j, k # loop indices + cdef Py_ssize_t i, j, k # loop indices cdef Py_ssize_t r # another row/column index # We need to construct 1x1 and 2x2 matrices to stick in d. @@ -14101,7 +14089,7 @@ cdef class Matrix(Matrix1): # at the end of the function, not as its columns are computed. ring = self.base_ring().fraction_field() - cdef Matrix A # A copy of the input matrix + cdef Matrix A # A copy of the input matrix if self.base_ring() == ring: A = self.__copy__() else: @@ -14139,7 +14127,7 @@ cdef class Matrix(Matrix1): cdef list d = [] # And the parent of those diagonal blocks that are 1x1... - one_by_one_space = A.matrix_space(1, 1) + one_by_one_space = A.matrix_space(1,1) # The case n == 0 is *almost* handled by skipping the # forthcoming loop entirely. However, we must stick a trivial @@ -14155,7 +14143,7 @@ cdef class Matrix(Matrix1): # where we're storing the next iterate. So our indices are # always "k" greater than those of Higham or B&K. - A_kk = A.get_unsafe(k, k) + A_kk = A.get_unsafe(k,k) if k == (n-1): # Handle this trivial case manually, since otherwise the @@ -14163,7 +14151,7 @@ cdef class Matrix(Matrix1): # meaningless. The corresponding entry of "L" will be # fixed later (since it's an on-diagonal element, it gets # set to one eventually). - d.append(one_by_one_space(A_kk)) + d.append( one_by_one_space(A_kk) ) k += 1 continue @@ -14173,8 +14161,8 @@ cdef class Matrix(Matrix1): # It's a back door that lets us escape with only the standard non-block # non-pivoting LDL^T factorization. This allows us to implement e.g. # indefinite_factorization() in terms of this method. - d.append(one_by_one_space(A_kk)) - _block_ldlt_pivot1x1(A, k) + d.append( one_by_one_space(A_kk) ) + _block_ldlt_pivot1x1(A,k) k += 1 continue except ZeroDivisionError: @@ -14189,8 +14177,8 @@ cdef class Matrix(Matrix1): # Note: omega_1 is defined as a C double, but the abs() # below would make a complex number approximate anyway. omega_1 = 0 - for i in range(k + 1, n): - a_ik_abs = A.get_unsafe(i, k).abs() + for i in range(k+1,n): + a_ik_abs = A.get_unsafe(i,k).abs() if a_ik_abs > omega_1: omega_1 = a_ik_abs # We record the index "r" that corresponds to @@ -14210,7 +14198,7 @@ cdef class Matrix(Matrix1): # the 1x1 pivot "a" in the top-left position. The entry "a" # will be adjusted to "1" later on to ensure that "L" is # (block) unit-lower-triangular. - d.append(one_by_one_space(A_kk)) + d.append( one_by_one_space(A_kk) ) k += 1 continue @@ -14222,8 +14210,8 @@ cdef class Matrix(Matrix1): # otherwise. We are performing a 1x1 pivot, but the # rows/columns are already where we want them, so nothing # needs to be permuted. - d.append(one_by_one_space(A_kk)) - _block_ldlt_pivot1x1(A, k) + d.append( one_by_one_space(A_kk) ) + _block_ldlt_pivot1x1(A,k) k += 1 continue @@ -14237,30 +14225,27 @@ cdef class Matrix(Matrix1): # Note: omega_r is defined as a C double, but the abs() # below would make a complex number approximate anyway. omega_r = 0 - for j in range(k, r): - a_rj_abs = A.get_unsafe(r, j).abs() + for j in range(k,r): + a_rj_abs = A.get_unsafe(r,j).abs() if a_rj_abs > omega_r: omega_r = a_rj_abs if A_kk.abs()*omega_r >= alpha*(omega_1**2): # Step (2) in Higham or Step (4) in B&K. - d.append(one_by_one_space(A_kk)) - _block_ldlt_pivot1x1(A, k) + d.append( one_by_one_space(A_kk) ) + _block_ldlt_pivot1x1(A,k) k += 1 continue - A_rr = A.get_unsafe(r, r) + A_rr = A.get_unsafe(r,r) if A_rr.abs() > alpha*omega_r: # This is Step (3) in Higham or Step (5) in B&K. Still # a 1x1 pivot, but this time we need to swap # rows/columns k and r. - d.append(one_by_one_space(A_rr)) - A.swap_columns_c(k, r) - A.swap_rows_c(k, r) - p_k = p[k] - p[k] = p[r] - p[r] = p_k - _block_ldlt_pivot1x1(A, k) + d.append( one_by_one_space(A_rr) ) + A.swap_columns_c(k,r); A.swap_rows_c(k,r) + p_k = p[k]; p[k] = p[r]; p[r] = p_k + _block_ldlt_pivot1x1(A,k) k += 1 continue @@ -14268,19 +14253,16 @@ cdef class Matrix(Matrix1): # or Step (6) in B&K, where we perform a 2x2 pivot. See # pivot1x1() for an explanation of why it's OK to permute # the entries of "L" here as well. - A.swap_columns_c(k + 1, r) - A.swap_rows_c(k + 1, r) - p_k = p[k + 1] - p[k + 1] = p[r] - p[r] = p_k + A.swap_columns_c(k+1,r); A.swap_rows_c(k+1,r) + p_k = p[k+1]; p[k+1] = p[r]; p[r] = p_k # The top-left 2x2 submatrix (starting at position k,k) is # now our pivot. - E = A[k: k + 2, k: k + 2] + E = A[k:k+2,k:k+2] d.append(E) - C = A[k + 2: n, k: k + 2] - B = A[k + 2:, k+2:] + C = A[k+2:n,k:k+2] + B = A[k+2:,k+2:] # We don't actually need the inverse of E, what we really need # is C*E.inverse(), and that can be found by setting @@ -14297,10 +14279,10 @@ cdef class Matrix(Matrix1): # Compute the Schur complement that we'll work on during # the following iteration, and store it back in the lower- # right-hand corner of "A". - for i in range(n - k - 2): - for j in range(i + 1): - A.set_unsafe(k + 2 + i, k + 2 + j, schur_complement[i, j]) - A.set_unsafe(k + 2 + j, k + 2 + i, schur_complement[j, i]) + for i in range(n-k-2): + for j in range(i+1): + A.set_unsafe(k+2+i, k+2+j, schur_complement[i,j]) + A.set_unsafe(k+2+j, k+2+i, schur_complement[j,i]) # The on- and above-diagonal entries of "L" will be fixed # later, so we only need to worry about the lower-left entry @@ -14311,7 +14293,8 @@ cdef class Matrix(Matrix1): for j in range(2): # Store the new (k and (k+1)st) columns of "L" within # the lower-left-hand corner of "A". - A.set_unsafe(k+i+2, k+j, CE_inverse[i, j]) + A.set_unsafe(k+i+2, k+j, CE_inverse[i,j]) + k += 2 @@ -14320,7 +14303,7 @@ cdef class Matrix(Matrix1): # correctness. A.set_unsafe(i, i, one) - result = (p, A, d) + result = (p,A,d) self.cache(cache_string, result) return result @@ -14625,12 +14608,12 @@ cdef class Matrix(Matrix1): """ cdef Py_ssize_t n # size of the matrices - cdef Py_ssize_t i, j # loop indices - cdef Matrix P, L, D # output matrices + cdef Py_ssize_t i, j # loop indices + cdef Matrix P,L,D # output matrices - p, L, d = self._block_ldlt(classical) + p,L,d = self._block_ldlt(classical) MS = L.matrix_space() - P = MS.matrix(lambda i, j: p[j] == i) + P = MS.matrix(lambda i,j: p[j] == i) # Warning: when n == 0, this works, but returns a matrix # whose (nonexistent) entries are in ZZ rather than in @@ -14643,10 +14626,11 @@ cdef class Matrix(Matrix1): n = L._nrows zero = MS.base_ring().zero() for i in range(n): - for j in range(i + 1, n): - L.set_unsafe(i, j, zero) + for j in range(i+1,n): + L.set_unsafe(i,j,zero) + + return (P,L,D) - return (P, L, D) cdef bint _is_positive_definite_or_semidefinite(self, bint semi) except -1: """ @@ -14656,7 +14640,7 @@ cdef class Matrix(Matrix1): code. The boolean ``semi`` argument exists only to change "greater than zero" into "greater than or equal to zero." """ - from sage.rings.real_lazy import RLF, CLF + from sage.rings.real_lazy import RLF,CLF R = self.base_ring() @@ -14676,10 +14660,10 @@ cdef class Matrix(Matrix1): return False if self._nrows == 0: - return True # vacuously + return True # vacuously cdef list d - _, _, d = self._block_ldlt(False) + _,_,d = self._block_ldlt(False) # Check each 1x1 block for a nonpositive (negative) entry. If # we don't find any, the matrix is positive-(semi)definite. The @@ -14689,7 +14673,8 @@ cdef class Matrix(Matrix1): if semi: op = operator.ge - return all(d_i.nrows() == 1 and op(d_i[0, 0], 0) for d_i in d) + return all(d_i.nrows() == 1 and op(d_i[0,0], 0) for d_i in d) + def is_positive_semidefinite(self): r""" @@ -15001,7 +14986,7 @@ cdef class Matrix(Matrix1): result = self._is_positive_definite_or_semidefinite(False) if certificate: from sage.misc.superseded import deprecation - msg = "the 'certificate' argument is deprecated; if you " + msg = "the 'certificate' argument is deprecated; if you " msg += "need the corresponding factorization, you can " msg += "simply compute it yourself (the results are cached)" deprecation(31619, msg) @@ -15009,7 +14994,7 @@ cdef class Matrix(Matrix1): d = None if result: from sage.modules.free_module_element import vector - _, L, D = self.block_ldlt() + _,L,D = self.block_ldlt() d = vector(D.base_ring(), D.diagonal()) return (result, L, d) else: @@ -15090,7 +15075,7 @@ cdef class Matrix(Matrix1): m2 = hadamard_row_bound_mpfr(A) return min(m1, m2) - def find(self, f, indices=False): + def find(self,f, indices=False): r""" Find elements in this matrix satisfying the constraints in the function `f`. The function is evaluated on each element of @@ -15156,7 +15141,7 @@ cdef class Matrix(Matrix1): True """ from sage.matrix.matrix_space import MatrixSpace - cdef Py_ssize_t size, i, j + cdef Py_ssize_t size,i,j cdef object M if not indices: @@ -15165,20 +15150,20 @@ cdef class Matrix(Matrix1): M = PyList_New(0) for i from 0 <= i < size: - PyList_Append(M, f(PyList_GET_ITEM(L, i))) + PyList_Append(M,f(PyList_GET_ITEM(L,i))) from sage.rings.finite_rings.integer_mod_ring import IntegerModRing return MatrixSpace(IntegerModRing(2), - nrows=self._nrows, ncols=self._ncols).matrix(M) + nrows=self._nrows,ncols=self._ncols).matrix(M) else: # return matrix along with indices in a dictionary d = {} for i from 0 <= i < self._nrows: for j from 0 <= j < self._ncols: - if f(self.get_unsafe(i, j)): - d[(i, j)] = self.get_unsafe(i, j) + if f(self.get_unsafe(i,j)): + d[(i,j)] = self.get_unsafe(i,j) return d @@ -15669,7 +15654,7 @@ cdef class Matrix(Matrix1): """ d = self.smith_form(transformation=False) r = min(self.nrows(), self.ncols()) - return [d[i, i] for i in range(r)] + return [d[i,i] for i in range(r)] def smith_form(self, transformation=True, integral=None, exact=True): r""" @@ -15893,19 +15878,19 @@ cdef class Matrix(Matrix1): raise NotImplementedError("Smith form over non-exact rings not implemented at present") # first clear the first row and column - u, t, v = _smith_onestep(self) + u,t,v = _smith_onestep(self) # now recurse: t now has a nonzero entry at 0,0 and zero entries in the rest # of the 0th row and column, so we apply smith_form to the smaller submatrix - mm = t.submatrix(1, 1) + mm = t.submatrix(1,1) if transformation: dd, uu, vv = mm.smith_form(transformation=True) else: dd = mm.smith_form(transformation=False) - d = dd.new_matrix(1, 1, [t[0, 0]]).block_sum(dd) + d = dd.new_matrix(1,1,[t[0,0]]).block_sum(dd) if transformation: - u = uu.new_matrix(1, 1, [1]).block_sum(uu) * u - v = v * vv.new_matrix(1, 1, [1]).block_sum(vv) + u = uu.new_matrix(1,1,[1]).block_sum(uu) * u + v = v * vv.new_matrix(1,1,[1]).block_sum(vv) dp, up, vp = _smith_diag(d, transformation=transformation) if integral is False: dp = dp.change_ring(R) @@ -16128,37 +16113,36 @@ cdef class Matrix(Matrix1): pivot_cols = [] while j < n: k = i - while k < m and A.get_unsafe(k, j).is_zero(): # first nonzero entry + while k < m and A.get_unsafe(k,j).is_zero(): # first nonzero entry k += 1 if k < m: l = k + 1 while l < m: - while l < m and A.get_unsafe(l, j).is_zero(): # nonzero entry below + while l < m and A.get_unsafe(l,j).is_zero(): # nonzero entry below l += 1 - if l >= m: - break + if l >= m: break - a = A.get_unsafe(k, j) - b = A.get_unsafe(l, j) - d, p, q = a.xgcd(b) # p * a + q * b = d = gcd(a,b) + a = A.get_unsafe(k,j) + b = A.get_unsafe(l,j) + d,p,q = a.xgcd(b) # p * a + q * b = d = gcd(a,b) e = a // d f = b // d - for c in range(j, n): - Akc = A.get_unsafe(k, c) - Alc = A.get_unsafe(l, c) + for c in range(j,n): + Akc = A.get_unsafe(k,c) + Alc = A.get_unsafe(l,c) A.set_unsafe(k, c, p * Akc + q * Alc) A.set_unsafe(l, c, (-f) * Akc + e * Alc) if transformation: for c in range(m): - Ukc = U.get_unsafe(k, c) - Ulc = U.get_unsafe(l, c) + Ukc = U.get_unsafe(k,c) + Ulc = U.get_unsafe(l,c) U.set_unsafe(k, c, p * Ukc + q * Ulc) U.set_unsafe(l, c, (-f) * Ukc + e * Ulc) if i != k: - A.swap_rows_c(i, k) + A.swap_rows_c(i,k) if transformation: - U.swap_rows_c(i, k) + U.swap_rows_c(i,k) pivot_cols.append(j) i += 1 j += 1 @@ -16166,26 +16150,26 @@ cdef class Matrix(Matrix1): # reduce entries above pivots for i in range(len(pivot_cols)): j = pivot_cols[i] - pivot = A.get_unsafe(i, j) + pivot = A.get_unsafe(i,j) # possibly normalize the pivot if normalization: coeff = normalization(pivot) - for c in range(j, n): - A.set_unsafe(i, c, A.get_unsafe(i, c) * coeff) + for c in range(j,n): + A.set_unsafe(i, c, A.get_unsafe(i,c) * coeff) if transformation: for c in range(m): - U.set_unsafe(i, c, U.get_unsafe(i, c) * coeff) + U.set_unsafe(i, c, U.get_unsafe(i,c) * coeff) - pivot = A.get_unsafe(i, j) + pivot = A.get_unsafe(i,j) for k in range(i): - q = - (A.get_unsafe(k, j) // pivot) + q = - (A.get_unsafe(k,j) // pivot) if not q.is_zero(): - for c in range(j, n): - A.set_unsafe(k, c, A.get_unsafe(k, c) + q * A.get_unsafe(i, c)) + for c in range(j,n): + A.set_unsafe(k, c, A.get_unsafe(k,c) + q * A.get_unsafe(i,c)) if transformation: for c in range(m): - U.set_unsafe(k, c, U.get_unsafe(k, c) + q * U.get_unsafe(i, c)) + U.set_unsafe(k, c, U.get_unsafe(k,c) + q * U.get_unsafe(i,c)) if transformation: return U @@ -16329,25 +16313,25 @@ cdef class Matrix(Matrix1): return self.new_matrix(self.nrows(), self.nrows(), 1), self, [] else: return self.new_matrix(self.nrows(), self.nrows(), 1), self, [ - self.nonzero_positions_in_row(0)[0]] + self.nonzero_positions_in_row(0)[0] ] R = self.base_ring() # data type checks on R if not R.is_integral_domain(): raise TypeError("Generic echelon form only defined over " - "integral domains") + "integral domains") if not R.is_exact(): raise NotImplementedError("Echelon form over generic non-exact " - "rings not implemented at present") + "rings not implemented at present") left_mat, a = _generic_clear_column(self) assert left_mat * self == a - if a[0, 0] != 0: + if a[0,0] != 0: aa = a.submatrix(1, 1) s, t, pivs = aa._echelon_form_PID() - left_mat = s.new_matrix(1, 1, [1]).block_sum(s) * left_mat + left_mat = s.new_matrix(1,1,[1]).block_sum(s) * left_mat a = left_mat * self pivs = [0] + [x + 1 for x in pivs] @@ -16365,12 +16349,12 @@ cdef class Matrix(Matrix1): I = ideal_or_fractional(R, y) s = a[0][pivs[i]] t = I.small_residue(s) - v = R((s-t) / y) + v = R( (s-t) / y) left_mat.add_multiple_of_row(0, i, -v) a.add_multiple_of_row(0, i, -v) assert left_mat * self == a - except AttributeError: # on I.small_residue + except AttributeError: # on I.small_residue pass return left_mat, a, pivs @@ -16477,7 +16461,7 @@ cdef class Matrix(Matrix1): cdef list corners = [] # zero or one in corner of off-diagonal blocks if basis: from sage.matrix.constructor import identity_matrix - U = identity_matrix(R, n) # transformation matrix + U = identity_matrix(R, n) # transformation matrix # parity switch, True iff working on transpose # if False, mimic row operations only on U # if True, mimic column operations only on U @@ -16490,7 +16474,7 @@ cdef class Matrix(Matrix1): while zigging: # zigging means we are building a block nonzero = -1 for i in range(c+1, n): - if Z.get_unsafe(i, c): + if Z.get_unsafe(i,c): nonzero = i break zigging = (nonzero != -1) @@ -16534,7 +16518,7 @@ cdef class Matrix(Matrix1): # (inclusive), use it to clear entries to the right # but first record polynomial for block just built # this is the full monic polynomial, with correct coefficients - p = [-Z.get_unsafe(i, c) for i in range(s, c + 1)] + p = [-Z.get_unsafe(i,c) for i in range(s,c+1)] p.append(one) polys.append(p) @@ -16550,7 +16534,7 @@ cdef class Matrix(Matrix1): # Effectively: Z.add_multiple_of_row(i, j, scale) for k in range(c+1, n): # Z[i,k] = Z[i,k] + scale*Z[j,k] - Z.set_unsafe(i, k, Z.get_unsafe(i, k) + scale * Z.get_unsafe(j, k)) + Z.set_unsafe(i, k, Z.get_unsafe(i,k)+scale*Z.get_unsafe(j,k)) if basis: if trans: U.add_multiple_of_column(j, i, -scale) @@ -17317,7 +17301,7 @@ cdef class Matrix(Matrix1): companions.append(companion_matrix(poly, format=format)) return block_diagonal_matrix(companions, subdivide=subdivide) - def is_positive_operator_on(self, K1, K2=None): + def is_positive_operator_on(self,K1,K2=None): r""" Determine if this matrix is a positive operator on a cone. @@ -17751,7 +17735,7 @@ cdef class Matrix(Matrix1): """ return (-self).is_cross_positive_on(K) - def is_lyapunov_like_on(self, K): + def is_lyapunov_like_on(self,K): r""" Determine if this matrix is Lyapunov-like on a cone. @@ -18121,35 +18105,35 @@ def _smith_diag(d, transformation=True): else: left = right = None for i in range(n): - I0 = ideal_or_fractional(R, dp[i, i]) + I = ideal_or_fractional(R, dp[i,i]) - if I0 == ideal_or_fractional(R, 1): - if dp[i, i] != 1: + if I == ideal_or_fractional(R, 1): + if dp[i,i] != 1: if transformation: - left.add_multiple_of_row(i, i, R(R(1) / (dp[i, i])) - 1) - dp[i, i] = R(1) + left.add_multiple_of_row(i,i,R(R(1)/(dp[i,i])) - 1) + dp[i,i] = R(1) continue - for j in range(i + 1, n): - if dp[j, j] not in I0: - t = ideal_or_fractional(R, [dp[i, i], dp[j, j]]).gens_reduced() + for j in range(i+1,n): + if dp[j,j] not in I: + t = ideal_or_fractional(R, [dp[i,i], dp[j,j]]).gens_reduced() if len(t) > 1: raise ArithmeticError t = t[0] # find lambda, mu such that lambda*d[i,i] + mu*d[j,j] = t - lamb = R(dp[i, i] / t).inverse_mod(ideal_or_fractional(R, dp[j, j] / t)) - mu = R((t - lamb * dp[i, i]) / dp[j, j]) + lamb = R(dp[i,i]/t).inverse_mod( ideal_or_fractional(R, dp[j,j]/t)) + mu = R((t - lamb*dp[i,i]) / dp[j,j]) newlmat = dp.new_matrix(dp.nrows(), dp.nrows(), 1) - newlmat[i, i] = lamb - newlmat[i, j] = 1 - newlmat[j, i] = R(-dp[j, j] * mu / t) - newlmat[j, j] = R(dp[i, i] / t) + newlmat[i,i] = lamb + newlmat[i,j] = 1 + newlmat[j,i] = R(-dp[j,j]*mu/t) + newlmat[j,j] = R(dp[i,i]/t) newrmat = dp.new_matrix(dp.ncols(), dp.ncols(), 1) - newrmat[i, i] = 1 - newrmat[i, j] = R(-dp[j, j] / t) - newrmat[j, i] = mu - newrmat[j, j] = R(lamb * dp[i, i] / t) + newrmat[i,i] = 1 + newrmat[i,j] = R(-dp[j,j]/t) + newrmat[j,i] = mu + newrmat[j,j] = R(lamb*dp[i,i] / t) if transformation: left = newlmat*left @@ -18195,13 +18179,13 @@ def _generic_clear_column(m): k = 0 while a[k, 0] == 0: k += 1 - if k == a.nrows(): # first column is zero + if k == a.nrows(): # first column is zero return left_mat, a # k is now first row such that a[k, 0] is nonzero - left_mat[0, 0] = 0 - left_mat[k, k] = 0 - left_mat[0, k] = 1 - left_mat[k, 0] = -1 + left_mat[0,0] = 0 + left_mat[k,k] = 0 + left_mat[0,k] = 1 + left_mat[k,0] = -1 a = left_mat*a if left_mat * m != a: raise ArithmeticError("Something went wrong") @@ -18215,15 +18199,15 @@ def _generic_clear_column(m): # [e,f] # is invertible over R - I0 = ideal_or_fractional(R, a[0, 0]) # need to make sure we change this when a[0,0] changes + I = ideal_or_fractional(R, a[0, 0]) # need to make sure we change this when a[0,0] changes for k in range(1, a.nrows()): - if a[k, 0] not in I0: + if a[k,0] not in I: try: - v = ideal_or_fractional(R, a[0, 0], a[k, 0]).gens_reduced() + v = ideal_or_fractional(R, a[0,0], a[k,0]).gens_reduced() except Exception as msg: - raise ArithmeticError("%s\nCan't create ideal on %s and %s" % (msg, a[0, 0], a[k, 0])) + raise ArithmeticError("%s\nCan't create ideal on %s and %s" % (msg, a[0,0], a[k,0])) if len(v) > 1: - raise ArithmeticError("Ideal %s not principal" % ideal_or_fractional(R, a[0, 0], a[k, 0])) + raise ArithmeticError("Ideal %s not principal" % ideal_or_fractional(R, a[0,0], a[k,0])) B = v[0] # now we find c,d, using the fact that c * (a_{0,0}/B) - d * @@ -18232,40 +18216,40 @@ def _generic_clear_column(m): # need to handle carefully the case when a_{k,0}/B is a unit, i.e. a_{k,0} divides # a_{0,0}. - c = R(a[0, 0] / B).inverse_mod(ideal_or_fractional(R, a[k, 0] / B)) - d = R((c*a[0, 0] - B)/(a[k, 0])) + c = R(a[0,0] / B).inverse_mod(ideal_or_fractional(R, a[k,0] / B)) + d = R( (c*a[0,0] - B)/(a[k,0]) ) # sanity check - if c*a[0, 0] - d*a[k, 0] != B: + if c*a[0,0] - d*a[k,0] != B: raise ArithmeticError # now we find e,f such that e*d + c*f = 1 in the same way if c != 0: - e = d.inverse_mod(ideal_or_fractional(R, c)) + e = d.inverse_mod( ideal_or_fractional(R, c) ) f = R((1 - d*e)/c) else: - e = R(-a[k, 0] / B) # here d is a unit and this is just 1/d + e = R(-a[k,0]/B) # here d is a unit and this is just 1/d f = R(1) if e*d + c*f != 1: raise ArithmeticError newlmat = left_mat.parent()(1) - newlmat[0, 0] = c - newlmat[0, k] = -d - newlmat[k, 0] = e - newlmat[k, k] = f + newlmat[0,0] = c + newlmat[0,k] = -d + newlmat[k,0] = e + newlmat[k,k] = f if newlmat.det() != 1: raise ArithmeticError a = newlmat*a - I0 = ideal_or_fractional(R, a[0, 0]) + I = ideal_or_fractional(R, a[0,0]) left_mat = newlmat*left_mat if left_mat * m != a: raise ArithmeticError # now everything in column 0 is divisible by the pivot - for i in range(1, a.nrows()): - s = R(a[i, 0] / a[0, 0]) - a.add_multiple_of_row(i, 0, -s) + for i in range(1,a.nrows()): + s = R( a[i, 0]/a[0, 0]) + a.add_multiple_of_row(i, 0, -s ) left_mat.add_multiple_of_row(i, 0, -s) if left_mat * m != a: raise ArithmeticError @@ -18303,12 +18287,11 @@ def _smith_onestep(m): # preparation: if column 0 is zero, swap it with the first nonzero column j = 0 - while a.column(j) == 0: - j += 1 + while a.column(j) == 0: j += 1 if j > 0: - right_mat[0, 0] = right_mat[j, j] = 0 - right_mat[0, j] = 1 - right_mat[j, 0] = -1 + right_mat[0,0] = right_mat[j,j] = 0 + right_mat[0,j] = 1 + right_mat[j,0] = -1 a = a*right_mat if m * right_mat != a: raise ArithmeticError @@ -18319,15 +18302,15 @@ def _smith_onestep(m): # test if everything to the right of the pivot in row 0 is good as well isdone = True for jj in range(j+1, a.ncols()): - if a[0, jj] != 0: + if a[0,jj] != 0: isdone = False # if not we recurse -- algorithm must terminate if R is Noetherian. if not isdone: - s, t, u = _smith_onestep(a.transpose()) + s,t,u = _smith_onestep(a.transpose()) left_mat = u.transpose() * left_mat a = t.transpose() - right_mat = right_mat * s.transpose() + right_mat = right_mat* s.transpose() return left_mat, a, right_mat @@ -18602,7 +18585,7 @@ def _matrix_power_symbolic(A, n): # Jordan block Jk, its dimension nk, the eigenvalue m Jk = J.subdivision(k, k) nk = Jk.ncols() - mk = Jk[0, 0] + mk = Jk[0,0] # First row of block Mk; its entries are of the form # D^i(f) / i! with f = x^n and D = differentiation wrt x @@ -18649,28 +18632,28 @@ cdef inline bint _block_ldlt_pivot1x1(Matrix A, Py_ssize_t k) except 1: to return zero/one so that ``1`` can be used to indicate that a python exception occurred. """ - cdef Py_ssize_t i, j # dumy loop indices + cdef Py_ssize_t i,j # dumy loop indices cdef Py_ssize_t n = A._nrows - pivot = A.get_unsafe(k, k) + pivot = A.get_unsafe(k,k) # Compute the Schur complement that we'll work on during # the following iteration, and store it back in the lower- # right-hand corner of "A". - for i in range(n - k - 1): - for j in range(i + 1): - A.set_unsafe(k + 1 + i, - k + 1 + j, - (A.get_unsafe(k + 1 + i, k + 1 + j) - - A.get_unsafe(k + 1 + i, k) * A.get_unsafe(k, k + 1 + j) / pivot)) - A.set_unsafe(k + 1 + j, - k + 1 + i, - A.get_unsafe(k + 1 + i, k + 1 + j).conjugate()) + for i in range(n-k-1): + for j in range(i+1): + A.set_unsafe(k+1+i, + k+1+j, + ( A.get_unsafe(k+1+i,k+1+j) - + A.get_unsafe(k+1+i,k)*A.get_unsafe(k,k+1+j)/pivot )) + A.set_unsafe(k+1+j, + k+1+i, + A.get_unsafe(k+1+i,k+1+j).conjugate()) for i in range(n-k-1): # Store the new (kth) column of "L" within the lower- # left-hand corner of "A". - A.set_unsafe(k + i + 1, + A.set_unsafe(k+i+1, k, - A.get_unsafe(k + i + 1, k) / pivot) + A.get_unsafe(k+i+1,k)/ pivot) return 0 From d22015ca69e5bfff517a129c0c3df639ab060efd Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 1 Oct 2023 10:52:33 +0200 Subject: [PATCH 057/463] undo format changes for matrix_mpolynomial_dense.pyx --- src/sage/matrix/matrix_mpolynomial_dense.pyx | 55 ++++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/src/sage/matrix/matrix_mpolynomial_dense.pyx b/src/sage/matrix/matrix_mpolynomial_dense.pyx index 589b5b33331..e3de9bbdb57 100644 --- a/src/sage/matrix/matrix_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_mpolynomial_dense.pyx @@ -9,14 +9,14 @@ AUTHOR: * Martin Albrecht """ -# ***************************************************************************** +#***************************************************************************** # Copyright (C) 2013 Martin Albrecht # # 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.matrix.matrix_generic_dense cimport Matrix_generic_dense from sage.matrix.matrix2 cimport Matrix @@ -101,8 +101,7 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): [ 0 -x + y] """ x = self.fetch('echelon_form_'+algorithm) - if x is not None: - return x + if x is not None: return x if algorithm == "frac": E = self.matrix_over_field() @@ -117,8 +116,8 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): if algorithm == "frac": self.cache('pivots', E.pivots()) elif algorithm == "bareiss": - l1 = E.swapped_columns() - self.cache('pivots', tuple(sorted(l1))) + l = E.swapped_columns() + self.cache('pivots', tuple(sorted(l))) elif algorithm == "row_reduction": pass @@ -155,7 +154,7 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): x = self.fetch('pivots') if x is None: - raise RuntimeError("BUG: matrix pivots should have been set but weren't, matrix parent = '%s'" % self.parent()) + raise RuntimeError("BUG: matrix pivots should have been set but weren't, matrix parent = '%s'"%self.parent()) return x def echelonize(self, algorithm='row_reduction', **kwds): @@ -263,7 +262,7 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): self.clear_cache() singular_bareiss = singular_function("bareiss") - E, ln = singular_bareiss(self.T) + E, l = singular_bareiss(self.T) m = len(E) n = len(E[0]) @@ -278,33 +277,33 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): self.set_unsafe(r, c, R._zero_element) from sage.rings.integer_ring import ZZ - ln = [ZZ(e-1) for e in ln] + l = [ZZ(e-1) for e in l] - self.cache('in_echelon_form_bareiss', True) + self.cache('in_echelon_form_bareiss',True) self.cache('rank', len(E)) self.cache('pivots', tuple(range(len(E)))) - self.cache('swapped_columns', tuple(ln)) + self.cache('swapped_columns', tuple(l)) elif can_convert_to_singular(self.base_ring()): self.check_mutability() self.clear_cache() - E, ln = self.T._singular_().bareiss()._sage_(self.base_ring()) + E,l = self.T._singular_().bareiss()._sage_(self.base_ring()) # clear matrix for r from 0 <= r < self._nrows: for c from 0 <= c < self._ncols: - self.set_unsafe(r, c, R._zero_element) + self.set_unsafe(r,c,R._zero_element) for r from 0 <= r < E.nrows(): for c from 0 <= c < E.ncols(): - self.set_unsafe(c, r, E[r, c]) + self.set_unsafe(c,r, E[r,c]) - self.cache('in_echelon_form_bareiss', True) + self.cache('in_echelon_form_bareiss',True) self.cache('rank', E.nrows()) self.cache('pivots', tuple(range(E.nrows()))) - self.cache('swapped_columns', ln) + self.cache('swapped_columns', l) else: @@ -388,14 +387,14 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): if x is not None: return # already known to be in echelon form - nr, nc = self.nrows(), self.ncols() + nr,nc = self.nrows(),self.ncols() F = self.base_ring().base_ring() - cdef Matrix d = matrix(F, nr, nc) + cdef Matrix d = matrix(F,nr,nc) start_row = 0 for r from 0 <= r < nr: for c from 0 <= c < nc: - p = self.get_unsafe(r, c) + p = self.get_unsafe(r,c) if p.is_constant(): d.set_unsafe(r, c, p.constant_coefficient()) @@ -405,25 +404,25 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): if d.get_unsafe(rc, c): r = rc break - if r != -1: - a_inverse = ~self.get_unsafe(r, c) - self.rescale_row_c(r, a_inverse, c) + if r!=-1: + a_inverse = ~self.get_unsafe(r,c) + self.rescale_row_c(r, a_inverse , c) self.swap_rows_c(r, start_row) for i from 0 <= i < nr: if i != start_row: - minus_b = -self.get_unsafe(i, c) + minus_b = -self.get_unsafe(i,c) self.add_multiple_of_row(i, start_row, minus_b, 0) - start_row += 1 + start_row +=1 d = d._parent(0) for i from start_row <= i < nr: for j from c+1 <= j < nc: - if self.get_unsafe(i, j).is_constant(): - d.set_unsafe(i, j, self.get_unsafe(i, j).constant_coefficient()) + if self.get_unsafe(i,j).is_constant(): + d.set_unsafe(i,j, self.get_unsafe(i,j).constant_coefficient()) - self.cache('in_echelon_form_row_reduction', True) + self.cache('in_echelon_form_row_reduction',True) def swapped_columns(self): """ @@ -500,7 +499,7 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): N = self.__copy__() for j in range(self.ncols()): if j != ncoef: - N.add_multiple_of_column(j, ncoef, -R(self[nrow, j] / coef)) + N.add_multiple_of_column(j, ncoef, -R(self[nrow,j] / coef)) return N.fitting_ideal(i) for (ncolumn, column) in enumerate(self.columns()): if not column: From 53c99d2044076ce5c459e395f2fb562c6890a58a Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 1 Oct 2023 10:55:46 +0200 Subject: [PATCH 058/463] undo format changes for matrix_mpolynomial_dense.pyx and laurent_polynomial.pyx --- .../rings/polynomial/laurent_polynomial.pyx | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index d4dff8b1361..f0ccb4e2ce0 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -359,7 +359,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): elif (not isinstance(f, Polynomial)) or (parent is not f.parent()): if isinstance(f, dict): v = min(f) if f else 0 - f = {i-v: c for i, c in f.items()} + f = {i-v: c for i,c in f.items()} n += v f = parent._R(f) @@ -592,11 +592,11 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): elif e == 0: var = "" else: - var = "*{}^{}".format(X, e) - s += "{}{}".format(x, var) + var = "*{}^{}".format(X,e) + s += "{}{}".format(x,var) first = False s = s.replace(" + -", " - ") - s = s.replace(" 1*", " ") + s = s.replace(" 1*"," ") s = s.replace(" -1*", " -") return s[1:] @@ -653,19 +653,19 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): elif e == 0: var = "" elif e > 0: - var = "|{}^{{{}}}".format(X, e) + var = "|{}^{{{}}}".format(X,e) if e >= 0: - s += "{}{}".format(x, var) - else: # negative e + s += "{}{}".format(x,var) + else: # negative e if e == -1: s += "\\frac{{{}}}{{{}}}".format(x, X) else: - s += "\\frac{{{}}}{{{}^{{{}}}}}".format(x, X, -e) + s += "\\frac{{{}}}{{{}^{{{}}}}}".format(x, X,-e) first = False s = s.replace(" + -", " - ") - s = s.replace(" 1|", " ") + s = s.replace(" 1|"," ") s = s.replace(" -1|", " -") - s = s.replace("|", "") + s = s.replace("|","") return s[1:] @@ -701,7 +701,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): # degrees cdef long result = 0 cdef long result_mon - cdef int i, j + cdef int i,j cdef long var_hash_name = hash(self.__u._parent._names[0]) for i in range(self.__u.degree()+1): result_mon = hash(self.__u[i]) @@ -913,11 +913,11 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): j = i - self.__n if j >= 0: self.__u._unsafe_mutate(j, value) - else: # off to the left + else: # off to the left if value != 0: self.__n = self.__n + j R = self._parent.base_ring() - coeffs = [value] + [R.zero() for _ in range(1, -j)] + self.__u.list() + coeffs = [value] + [R.zero() for _ in range(1,-j)] + self.__u.list() self.__u = self.__u._parent(coeffs) self._normalize() @@ -1282,7 +1282,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): Fraction Field of Univariate Polynomial Ring in t over Rational Field """ cdef LaurentPolynomial_univariate ret - if self.__u.is_constant(): # this has a single term c*x^n + if self.__u.is_constant(): # this has a single term c*x^n ret = self._new_c() if self.__u.is_unit(): ret.__u = self.__u.inverse_of_unit() @@ -1680,6 +1680,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): """ return self.__n == 0 and self.__u.is_constant() + def is_square(self, root=False): r""" Return whether this Laurent polynomial is a square. @@ -1926,10 +1927,10 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): cdef list a = self.__u.list(copy=False) if n < 0: - v = [a[i] / (n + i + 1) for i in range(min(-1 - n, len(a)))] + [0] + v = [a[i]/(n+i+1) for i in range(min(-1-n,len(a)))] + [0] else: v = [] - v += [a[i] / (n + i + 1) for i in range(max(-n, 0), len(a))] + v += [a[i]/(n+i+1) for i in range(max(-n,0), len(a))] try: u = self._parent._R(v) except TypeError: @@ -1968,7 +1969,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): """ if kwds: f = self.subs(**kwds) - if x: # If there are non-keyword arguments + if x: # If there are non-keyword arguments return f(*x) else: return f From e5664d71849e6a367144ca9836c06510a6584307 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 1 Oct 2023 10:59:37 +0200 Subject: [PATCH 059/463] undo format changes for laurent_polynomial_ideal.py --- .../polynomial/laurent_polynomial_ideal.py | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index bea4b8bb76a..81bc095c382 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -26,8 +26,7 @@ from sage.structure.richcmp import op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE from sage.arith.misc import GCD - -class LaurentPolynomialIdeal(Ideal_generic): +class LaurentPolynomialIdeal( Ideal_generic ): def __init__(self, ring, gens, coerce=True, hint=None): r""" Create an ideal in a Laurent polynomial ring. @@ -93,7 +92,7 @@ def __init__(self, ring, gens, coerce=True, hint=None): """ Ideal_generic.__init__(self, ring, gens, coerce=coerce) self._poly_ring = ring.polynomial_ring() - self._poly_ideal = None # Create only as needed + self._poly_ideal = None # Create only as needed self._saturated = False self._hint = self._poly_ring.ideal([f.monomial_reduction()[0] for f in self.gens()]) # if hint is None: @@ -169,11 +168,11 @@ def _richcmp_(self, right_r, op): True """ if op in (op_EQ, op_NE): - if set(self.gens()) == set(right_r.gens()): # Early abort + if set(self.gens()) == set(right_r.gens()): # Early abort return (op == op_EQ) return ((self.polynomial_ideal() == right_r.polynomial_ideal()) == (op == op_EQ)) elif op == op_LE: - if all(f in right_r.gens() for f in self.gens()): # Early abort + if all(f in right_r.gens() for f in self.gens()): # Early abort return True return self.polynomial_ideal(saturate=False) <= right_r.polynomial_ideal() elif op == op_GE: @@ -308,10 +307,10 @@ def apply_coeff_map(self, f, new_base_ring=None, forward_hint=True): else: R = ring.change_ring(new_base_ring) if forward_hint: - apply_to_hint = lambda x, f=f: x.map_coefficients(f) + apply_to_hint = lambda x,f=f: x.map_coefficients(f) else: apply_to_hint = None - return self.apply_map(lambda x, f=f: + return self.apply_map(lambda x,f=f: x.map_coefficients(f, new_base_ring=new_base_ring), new_ring=R, apply_to_hint=apply_to_hint) @@ -429,17 +428,17 @@ def polynomial_ideal(self, saturate=True): l2 = [f.__reduce__()[1][0] for f in gens] hint = self._hint l2 += list(hint.groebner_basis()) - id = Q.ideal(l2) + I = Q.ideal(l2) if not saturate: - self._poly_ideal = id - self._hint = id + self._poly_ideal = I + self._hint = I return Q.ideal(l2) n = P.ngens() - id = id.saturation(Q.ideal([Q.monomial(*((1,) * n))]))[0] - self._poly_ideal = id - self._hint = id + I = I.saturation(Q.ideal([Q.monomial(*((1,) * n))]))[0] + self._poly_ideal = I + self._hint = I self._saturated = True - return id + return I def groebner_basis(self, saturate=True): """ @@ -453,8 +452,8 @@ def groebner_basis(self, saturate=True): sage: (I + J).groebner_basis() (x - 1, y + 1) """ - gb = self.polynomial_ideal(saturate=saturate).groebner_basis() - return tuple(self.ring()(x) for x in gb) + l = self.polynomial_ideal(saturate=saturate).groebner_basis() + return tuple(self.ring()(x) for x in l) def is_one(self): """ @@ -486,10 +485,10 @@ def is_binomial(self, groebner_basis=False): True """ if groebner_basis: - gb = self.groebner_basis() + l = self.groebner_basis() else: - gb = self.gens() - return all(not f or f.number_of_terms() == 2 for f in gb) + l = self.gens() + return all(not f or f.number_of_terms() == 2 for f in l) def associated_primes(self): """ @@ -509,9 +508,9 @@ def associated_primes(self): Ideal (z^2 - y, y*z + 2, y^2 + 2*z) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field) """ - ap = self.polynomial_ideal(saturate=False).associated_primes() - ap2 = [self.ring().ideal(id.gens(), hint=id) for id in ap] - return tuple(id for id in ap2 if not id.is_one()) + l = self.polynomial_ideal(saturate=False).associated_primes() + l2 = [self.ring().ideal(I.gens(), hint=I) for I in l] + return tuple(I for I in l2 if not I.is_one()) def minimal_associated_primes(self, saturate=False): """ @@ -531,9 +530,9 @@ def minimal_associated_primes(self, saturate=False): Ideal (z^3 + 2, -z^2 + y) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field) """ - ap = self.polynomial_ideal(saturate=saturate).minimal_associated_primes() - ap2 = [self.ring().ideal(id.gens(), hint=id) for id in ap] - return tuple(id for id in ap2 if not id.is_one()) + l = self.polynomial_ideal(saturate=saturate).minimal_associated_primes() + l2 = [self.ring().ideal(I.gens(), hint=I) for I in l] + return tuple(I for I in l2 if not I.is_one()) def radical(self): """ From 7285ecc55919324e6fb31c15500844b4cd6009fc Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 1 Oct 2023 11:00:54 +0200 Subject: [PATCH 060/463] undo format changes for laurent_polynomial_mpair.pyx --- src/sage/rings/polynomial/laurent_polynomial_mpair.pyx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index efab709fd44..fe199d281e3 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1241,19 +1241,19 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): else: return f - cdef int ln = len(x) + cdef int l = len(x) - if ln == 1 and isinstance(x[0], (tuple, list)): + if l == 1 and isinstance(x[0], (tuple, list)): x = x[0] - ln = len(x) + l = len(x) - if ln != self._parent.ngens(): + if l != self._parent.ngens(): raise TypeError("number of arguments does not match the number" " of generators in parent") # Check to make sure that we aren't dividing by zero cdef Py_ssize_t m - for m in range(ln): + for m in range(l): if x[m] == 0: if self.has_inverse_of(m): raise ZeroDivisionError From 61ea6e89a36e01741228e05a5f5d47e4395f64db Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 1 Oct 2023 11:02:27 +0200 Subject: [PATCH 061/463] undo format changes for laurent_polynomial_ring.py --- src/sage/rings/polynomial/laurent_polynomial_ring.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index 4cf0880880e..22d97975cd6 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -77,8 +77,6 @@ def is_LaurentPolynomialRing(R): _cache = {} - - def LaurentPolynomialRing(base_ring, *args, **kwds): r""" Return the globally unique univariate or multivariate Laurent polynomial @@ -254,7 +252,6 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): _cache[R] = P return P - def _split_dict_(D, indices, group_by=None): r""" Split the dictionary ``D`` by ``indices`` and ``group_by``. @@ -330,14 +327,13 @@ def extract(T, indices): if not all(r == 0 for r in extract(K, remaining)): raise SplitDictError('split not possible') G = extract(K, group_by) - In = extract(K, indices) - result.setdefault(G, dict()).update({In: V}) + I = extract(K, indices) + result.setdefault(G, dict()).update({I: V}) if not group_by: return result.popitem()[1] else: return result - def _split_laurent_polynomial_dict_(P, M, d): r""" Helper function for splitting a multivariate Laurent polynomial @@ -399,7 +395,6 @@ def value(d, R): pass return sum(P({k: 1}) * value(v, P) for k, v in D.items()).dict() - def from_fraction_field(L, x): r""" Helper function to construct a Laurent polynomial from an element of its @@ -760,7 +755,7 @@ def _element_constructor_(self, x, mon=None): P = parent(x) if P is self.polynomial_ring(): from sage.rings.polynomial.polydict import ETuple - return self.element_class(self, x, mon=ETuple({}, int(self.ngens()))) + return self.element_class( self, x, mon=ETuple({}, int(self.ngens())) ) elif isinstance(x, Expression): return x.laurent_polynomial(ring=self) From 16ce3c760dc7c12a72d9b3ac1dc2a33b19631c87 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 1 Oct 2023 11:03:57 +0200 Subject: [PATCH 062/463] undo format changes for laurent_polynomial_ring_base.py --- src/sage/rings/polynomial/laurent_polynomial_ring_base.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py index 95ea676e0d3..c10cbb219b0 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py @@ -278,7 +278,8 @@ def _coerce_map_from_(self, R): f = self._coerce_map_via([self._R], R) if f is not None: return f - if isinstance(R, LaurentPolynomialRing_generic) and self._R.has_coerce_map_from(R._R): + if (isinstance(R, LaurentPolynomialRing_generic) + and self._R.has_coerce_map_from(R._R)): return self._generic_coerce_map(R) def __eq__(self, right): @@ -479,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:: From 7bfdabf63b36743b5f43f646dc30681f7c5da921 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 1 Oct 2023 11:09:55 +0200 Subject: [PATCH 063/463] undo format changes for polynomial_element.pyx --- .../rings/polynomial/polynomial_element.pyx | 344 +++++++++--------- 1 file changed, 168 insertions(+), 176 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 06b5ab0eb43..c5a1129aecf 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -213,7 +213,7 @@ cdef class Polynomial(CommutativePolynomial): .. automethod:: _mul_trunc_ """ - def __init__(self, parent, is_gen=False, construct=False): + def __init__(self, parent, is_gen = False, construct=False): """ The following examples illustrate creation of elements of polynomial rings, and some basic arithmetic. @@ -357,7 +357,7 @@ cdef class Polynomial(CommutativePolynomial): from sage.plot.all import plot, point if R.characteristic() == 0: if xmin is None and xmax is None: - (xmin, xmax) = (-1, 1) + (xmin, xmax) = (-1,1) elif xmin is None or xmax is None: raise AttributeError("must give both plot endpoints") return plot(self.__call__, (xmin, xmax), *args, **kwds) @@ -365,10 +365,10 @@ cdef class Polynomial(CommutativePolynomial): if R.is_finite(): v = list(R) v.sort() - w = dict([(v[i], i) for i in range(len(v))]) + w = dict([(v[i],i) for i in range(len(v))]) z = [(i, w[self(v[i])]) for i in range(len(v))] return point(z, *args, **kwds) - raise NotImplementedError("plotting of polynomials over %s not implemented" % R) + raise NotImplementedError("plotting of polynomials over %s not implemented"%R) cpdef _lmul_(self, Element left): """ @@ -832,7 +832,7 @@ cdef class Polynomial(CommutativePolynomial): # is more permissive about its arguments than we are. top = top(*args, **kwds) except TypeError: - if args: # bwd compat: nonsense *keyword* arguments are okay + if args: # bwd compat: nonsense *keyword* arguments are okay raise TypeError("Wrong number of arguments") else: eval_coeffs = True @@ -912,7 +912,7 @@ cdef class Polynomial(CommutativePolynomial): d = pol.degree() if d <= 0 or (isinstance(a, Element) and R.is_exact() and a.is_zero()): - return cst # with the right parent thanks to the above coercion + return cst # with the right parent thanks to the above coercion elif pol._parent is R and a.is_gen(): return pol elif hasattr(a, "_evaluate_polynomial"): @@ -1078,18 +1078,18 @@ cdef class Polynomial(CommutativePolynomial): cdef Py_ssize_t d2 = pol.degree() # Special case constant polynomials - if d1 == -1: # self is the 0 polynomial + if d1 == -1: # self is the 0 polynomial if d2 == -1: - return rich_to_bool(op, 0) # both polynomials are 0 + return rich_to_bool(op, 0) # both polynomials are 0 elif d2 == 0: return richcmp(self._parent._base.zero(), pol.get_unsafe(0), op) - return rich_to_bool_sgn(op, -1) # we have d2 > 0 - elif d1 == 0: # self is a nonzero constant + return rich_to_bool_sgn(op, -1) # we have d2 > 0 + elif d1 == 0: # self is a nonzero constant if d2 == -1: return richcmp(self.get_unsafe(0), pol._parent._base.zero(), op) elif d2 == 0: return richcmp(self.get_unsafe(0), pol.get_unsafe(0), op) - return rich_to_bool_sgn(op, -1) # we have d2 > d1 == 0 + return rich_to_bool_sgn(op, -1) # we have d2 > d1 == 0 # For different degrees, compare the degree if d1 != d2: @@ -1272,12 +1272,12 @@ cdef class Polynomial(CommutativePolynomial): TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' """ - cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap + cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap cdef long result_mon cdef long c_hash cdef long var_name_hash cdef int i - for i from 0 <= i <= self.degree(): + for i from 0<= i <= self.degree(): if i == 1: # we delay the hashing until now to not waste it on a constant poly var_name_hash = hash(self._parent._names[0]) @@ -1331,7 +1331,7 @@ cdef class Polynomial(CommutativePolynomial): a = im_gens[0] d = self.degree() if d == -1: - return codomain.zero() # Special case: 0 should always coerce to 0 + return codomain.zero() # Special case: 0 should always coerce to 0 if base_map is None: base_map = codomain.coerce_map_from(self.base_ring()) result = base_map(self.get_unsafe(d)) @@ -1661,9 +1661,9 @@ cdef class Polynomial(CommutativePolynomial): for i in range(n+1): for j in range(n-1): M[i+j, j+n] = m[i] - v = vector(R, [R.one()] + [R.zero()]*(2*n-2)) # the constant polynomial 1 + v = vector(R, [R.one()] + [R.zero()]*(2*n-2)) # the constant polynomial 1 if M.is_invertible(): - x = M.solve_right(v) # there has to be a better way to solve + x = M.solve_right(v) # there has to be a better way to solve return a.parent()(list(x)[0:n]) else: raise ValueError("Impossible inverse modulo") @@ -1846,7 +1846,7 @@ cdef class Polynomial(CommutativePolynomial): This is the default implementation that does the multiplication and then truncate! There are custom implementations in several subclasses: - - :meth:`on dense polynomial over integers (via FLINT) ` + - :meth:`on dense polynomial over integers (via FLINT) ` - :meth:`on dense polynomial over Z/nZ (via FLINT) ` @@ -1961,7 +1961,7 @@ cdef class Polynomial(CommutativePolynomial): """ if self.degree() < 0: raise ValueError("square-free decomposition not defined for zero polynomial") - if hasattr(self.base_ring(), '_squarefree_decomposition_univariate_polynomial'): + if hasattr(self.base_ring(),'_squarefree_decomposition_univariate_polynomial'): return self.base_ring()._squarefree_decomposition_univariate_polynomial(self) raise NotImplementedError("square-free decomposition not implemented for this polynomial") @@ -2188,11 +2188,11 @@ cdef class Polynomial(CommutativePolynomial): raise ValueError("ring must be an extension of the base ring") if not (ring.is_field() and ring.is_finite()): raise NotImplementedError - allowed_deg_mult = Integer(ring.factored_order()[0][1]) # generally it will be the quotient of this by the degree of the base ring. + allowed_deg_mult = Integer(ring.factored_order()[0][1]) # generally it will be the quotient of this by the degree of the base ring. if degree is None: x = self._parent.gen() if allowed_deg_mult == 1: - xq = pow(x, q, self) + xq = pow(x,q,self) self = self.gcd(xq-x) degree = -1 if self.degree() == 0: @@ -2210,7 +2210,7 @@ cdef class Polynomial(CommutativePolynomial): break while d < allowed_deg_mult: d = d+1 - xq = pow(xq, q, self) + xq = pow(xq,q,self) if d.divides(allowed_deg_mult): break A = self.gcd(xq-x) @@ -2234,8 +2234,8 @@ cdef class Polynomial(CommutativePolynomial): break while True: # we waste a little effort here in computing the xq again. - d = d + 1 - xq = pow(xq, q, self) + d = d+1 + xq = pow(xq,q,self) if allowed_deg_mult.divides(d): break A = self.gcd(xq-x) @@ -2257,7 +2257,7 @@ cdef class Polynomial(CommutativePolynomial): raise ValueError("no roots D %s" % self) break d = d+1 - xq = pow(xq, q, self) + xq = pow(xq,q,self) if d == degree: break A = self.gcd(xq-x) @@ -2273,13 +2273,13 @@ cdef class Polynomial(CommutativePolynomial): if degree == 1: ring = self.base_ring() else: - ring = self.base_ring().extension(degree) # this won't work yet. + ring = self.base_ring().extension(degree) # this won't work yet. # now self has only roots of degree ``degree``. # for now, we only implement the Cantor-Zassenhaus split k = self.degree() // degree if k == 1: try: - return self.roots(ring, multiplicities=False)[0] # is there something better to do here? + return self.roots(ring, multiplicities=False)[0] # is there something better to do here? except IndexError: raise ValueError("no roots F %s" % self) if q % 2 == 0: @@ -2289,8 +2289,8 @@ cdef class Polynomial(CommutativePolynomial): continue T = T.monic() C = T - for i in range(degree - 1): - C = T + pow(C, q, self) + for i in range(degree-1): + C = T + pow(C,q,self) h = self.gcd(C) hd = h.degree() if hd != 0 and hd != self.degree(): @@ -2536,7 +2536,7 @@ cdef class Polynomial(CommutativePolynomial): else: v = [R.zero()]*right + [R.one()] return self.parent()(v, check=False) - if right > 20: # no gain below + if right > 20: # no gain below try: p = self.parent().characteristic() except (AttributeError, NotImplementedError): @@ -2557,7 +2557,7 @@ cdef class Polynomial(CommutativePolynomial): q, r = q.quo_rem(p) if r != 0: if sparse: - tmp = self.parent()({e * k: d[k] ** e for k in d}) + tmp = self.parent()({e*k : d[k]**e for k in d}) else: tmp = [0] * (e * len(c) - e + 1) for i in range(len(c)): @@ -2728,19 +2728,19 @@ cdef class Polynomial(CommutativePolynomial): if y.find("-") == 0: y = y[1:] if not atomic_repr and n > 0 and (y.find("+") != -1 or y.find("-") != -1): - x = "(%s)" % x + x = "(%s)"%x if n > 1: - var = "*%s^%s" % (name, n) - elif n == 1: - var = "*%s" % name + var = "*%s^%s"%(name,n) + elif n==1: + var = "*%s"%name else: var = "" sbuf.write(x) sbuf.write(var) s = sbuf.getvalue() s = s.replace(" + -", " - ") - s = re.sub(r' 1(\.0+)?\*', ' ', s) - s = re.sub(r' -1(\.0+)?\*', ' -', s) + s = re.sub(r' 1(\.0+)?\*',' ', s) + s = re.sub(r' -1(\.0+)?\*',' -', s) if s == " ": return "0" return s[1:] @@ -2813,7 +2813,7 @@ cdef class Polynomial(CommutativePolynomial): x = "\\left(%s\\right)" % x if n > 1: var = "|%s^{%s}" % (name, n) - elif n == 1: + elif n==1: var = "|%s" % name else: var = "" @@ -3150,12 +3150,12 @@ cdef class Polynomial(CommutativePolynomial): - Didier Deshommes (2006-05-25) """ - return self._parent(polynomial_fateman._mul_fateman_mul(self, right)) + return self._parent(polynomial_fateman._mul_fateman_mul(self,right)) @cython.boundscheck(False) @cython.wraparound(False) @cython.overflowcheck(False) - def _mul_karatsuba(self, right, K_threshold=None): + def _mul_karatsuba(self, right, K_threshold = None): r""" Compute the product of two polynomials using the Karatsuba divide and conquer multiplication algorithm. This is only used over a @@ -3328,8 +3328,8 @@ cdef class Polynomial(CommutativePolynomial): if n <= K_threshold or m <= K_threshold: return self._new_generic(do_schoolbook_product(f, g, -1)) if n == m: - return self._new_generic(do_karatsuba(f, g, K_threshold, 0, 0, n)) - return self._new_generic(do_karatsuba_different_size(f, g, K_threshold)) + return self._new_generic(do_karatsuba(f,g, K_threshold, 0, 0, n)) + return self._new_generic(do_karatsuba_different_size(f,g, K_threshold)) @cython.boundscheck(False) @cython.wraparound(False) @@ -3487,7 +3487,7 @@ cdef class Polynomial(CommutativePolynomial): if var not in variables: x = base_ring(self) if base_ring else self const_ix = ETuple((0,)*len(variables)) - return {const_ix: x} + return { const_ix: x } cdef tuple prev_variables = variables[:variables.index(var)] const_ix = ETuple((0,)*len(prev_variables)) @@ -3509,7 +3509,7 @@ cdef class Polynomial(CommutativePolynomial): cdef dict D = {} cdef tuple leftovers = (0,) * (len(variables) - len(prev_variables) - 1) for k in range(len(mpolys)): - for i, a in mpolys[k].iteritems(): + for i,a in mpolys[k].iteritems(): j = ETuple((k,) + leftovers) D[i + j] = a @@ -3680,7 +3680,7 @@ cdef class Polynomial(CommutativePolynomial): for y in x: d = d.lcm(y.denominator()) return d - except (AttributeError): + except(AttributeError): return self.base_ring().one() def numerator(self): @@ -3951,7 +3951,7 @@ cdef class Polynomial(CommutativePolynomial): """ return [self.diff()] - def integral(self, var=None): + def integral(self,var=None): """ Return the integral of this polynomial. @@ -4571,39 +4571,39 @@ cdef class Polynomial(CommutativePolynomial): # PARI for smaller degree over other rings besides Z, and use # NTL in general. # A remark from Bill Hart (2007-09-25) about the above observation: - # # NTL uses the Berlekamp-Zassenhaus method with van Hoeij's improvements. - # # But so does Magma since about Jul 2001. - # # - # # But here's the kicker. PARI also uses this algorithm. Even Maple uses - # # it! - # # - # # NTL's LLL algorithms are extremely well developed (van Hoeij uses - # # LLL). There is also a possible speed difference in whether one uses - # # quadratic convergence or not in the Hensel lift. But the right choice - # # is not always what one thinks. - # # - # # But more than likely NTL is just better for large problems because - # # Victor Shoup was very careful with the choice of strategies and - # # parameters he used. Paul Zimmerman supplied him with a pile of - # # polynomials to factor for comparison purposes and these seem to have - # # been used to tune the algorithm for a wide range of inputs, including - # # cases that van Hoeij's algorithm doesn't usually like. - # # - # # If you have a bound on the coefficients of the factors, one can surely - # # do better than a generic implementation, but probably not much better - # # if there are many factors. - # # - - # # HUGE TODO, refactor the code below here such that this method will - # # have as only the following code - # # - # # R = self.parent().base_ring() - # # return R._factor_univariate_polynomial(self) - # # - # # in this way we can move the specific logic of factoring to the - # # self.parent().base_ring() and get rid of all the ugly - # # is_SomeType(R) checks and get way nicer structured code - # # 200 lines of spaghetti code is just way to much! + ## NTL uses the Berlekamp-Zassenhaus method with van Hoeij's improvements. + ## But so does Magma since about Jul 2001. + ## + ## But here's the kicker. PARI also uses this algorithm. Even Maple uses + ## it! + ## + ## NTL's LLL algorithms are extremely well developed (van Hoeij uses + ## LLL). There is also a possible speed difference in whether one uses + ## quadratic convergence or not in the Hensel lift. But the right choice + ## is not always what one thinks. + ## + ## But more than likely NTL is just better for large problems because + ## Victor Shoup was very careful with the choice of strategies and + ## parameters he used. Paul Zimmerman supplied him with a pile of + ## polynomials to factor for comparison purposes and these seem to have + ## been used to tune the algorithm for a wide range of inputs, including + ## cases that van Hoeij's algorithm doesn't usually like. + ## + ## If you have a bound on the coefficients of the factors, one can surely + ## do better than a generic implementation, but probably not much better + ## if there are many factors. + ## + + ## HUGE TODO, refactor the code below here such that this method will + ## have as only the following code + ## + ## R = self.parent().base_ring() + ## return R._factor_univariate_polynomial(self) + ## + ## in this way we can move the specific logic of factoring to the + ## self.parent().base_ring() and get rid of all the ugly + ## is_SomeType(R) checks and get way nicer structured code + ## 200 lines of spaghetti code is just way to much! if self.degree() < 0: raise ArithmeticError("factorization of {!r} is not defined".format(self)) @@ -4617,7 +4617,7 @@ cdef class Polynomial(CommutativePolynomial): try: F = flatten(self).factor(**kwargs) unflatten = flatten.section() - return Factorization(((unflatten(f), m) for (f, m) in F), unit=F.unit()) + return Factorization(((unflatten(f),m) for (f,m) in F), unit = F.unit()) except NotImplementedError: pass @@ -4650,7 +4650,7 @@ cdef class Polynomial(CommutativePolynomial): # This was copied from the general multivariate implementation try: if R.is_finite(): - if R.characteristic() > 1 << 29: + if R.characteristic() > 1<<29: raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") P = self._parent @@ -4658,8 +4658,8 @@ cdef class Polynomial(CommutativePolynomial): S = self._singular_().factorize() factors = S[1] exponents = S[2] - v = sorted([(P(factors[i + 1]), - sage.rings.integer.Integer(exponents[i + 1])) + v = sorted([( P(factors[i+1]), + sage.rings.integer.Integer(exponents[i+1])) for i in range(len(factors))]) unit = P.one() for i in range(len(v)): @@ -4936,7 +4936,7 @@ cdef class Polynomial(CommutativePolynomial): raise NotImplementedError("splitting_field() is only implemented over number fields and finite fields") - def pseudo_quo_rem(self, other): + def pseudo_quo_rem(self,other): r""" Compute the pseudo-division of two polynomials. @@ -4996,7 +4996,7 @@ cdef class Polynomial(CommutativePolynomial): e -= 1 q = d**e - return (q * Q, q * R) + return (q*Q,q*R) @coerce_binop def gcd(self, other): @@ -5089,7 +5089,7 @@ cdef class Polynomial(CommutativePolynomial): try: doit = self._parent._base._gcd_univariate_polynomial except AttributeError: - raise NotImplementedError("%s does not provide a gcd implementation for univariate polynomials" % self._parent._base) + raise NotImplementedError("%s does not provide a gcd implementation for univariate polynomials"%self._parent._base) else: return doit(self, other) @@ -5462,7 +5462,7 @@ cdef class Polynomial(CommutativePolynomial): return R.fraction_field()[self._parent.variable_name()].quotient(self, names) - def sylvester_matrix(self, right, variable=None): + def sylvester_matrix(self, right, variable = None): """ Return the Sylvester matrix of ``self`` and ``right``. @@ -5588,10 +5588,10 @@ cdef class Polynomial(CommutativePolynomial): # sylvester_matrix() in multi_polynomial.pyx. if self._parent != right.parent(): - a, b = coercion_model.canonical_coercion(self, right) + a, b = coercion_model.canonical_coercion(self,right) variable = a.parent()(self.variables()[0]) - # We add the variable to cover the case that right is a multivariate - # polynomial + #We add the variable to cover the case that right is a multivariate + #polynomial return a.sylvester_matrix(b, variable) if variable: @@ -6446,18 +6446,13 @@ cdef class Polynomial(CommutativePolynomial): e = self.exponents() c = self.coefficients() - if len(e) == 0: - return [] + if len(e) == 0: return [] if len(e) == 1: - if e[0] == 0: - return [] - else: - return [(infinity.infinity, e[0])] + if e[0] == 0: return [] + else: return [(infinity.infinity, e[0])] - if e[0] == 0: - slopes = [] - else: - slopes = [(infinity.infinity, e[0])] + if e[0] == 0: slopes = [] + else: slopes = [(infinity.infinity, e[0])] points = [(e[0], c[0].valuation(p)), (e[1], c[1].valuation(p))] slopes.append((-(c[1].valuation(p)-c[0].valuation(p))/(e[1] - e[0]), e[1]-e[0])) @@ -6468,8 +6463,8 @@ cdef class Polynomial(CommutativePolynomial): slopes = slopes[:-1] points = points[:-1] s = -(v-points[-1][1])/(e[i]-points[-1][0]) - slopes.append((s, e[i] - points[-1][0])) - points.append((e[i], v)) + slopes.append((s,e[i]-points[-1][0])) + points.append((e[i],v)) return slopes @@ -6513,7 +6508,7 @@ cdef class Polynomial(CommutativePolynomial): if m != n or p[n] != q[n]: continue alpha = (q[n-1] - p[n-1])/(n*p[n]) - if alpha.is_integer(): # ZZ() might work for non-integers... + if alpha.is_integer(): # ZZ() might work for non-integers... alpha = ZZ(alpha) else: continue @@ -7183,7 +7178,7 @@ cdef class Polynomial(CommutativePolynomial): if Sf is not QQ or (d1 <= N and d2 <= N): algorithm = "resultant" else: - c = d1*sum(bool(p1[i]) for i in range(d1 + 1)) * \ + c = d1*sum(bool(p1[i]) for i in range(d1 + 1))*\ d2*sum(bool(p2[i]) for i in range(d2 + 1)) if c <= N**4: algorithm = "resultant" @@ -7596,7 +7591,8 @@ cdef class Polynomial(CommutativePolynomial): return self # return 0 n = self.degree() base_ring = self._parent.base_ring() - if (is_MPolynomialRing(base_ring) or is_PowerSeriesRing(base_ring)): + if (is_MPolynomialRing(base_ring) or + is_PowerSeriesRing(base_ring)): # It is often cheaper to compute discriminant of simple # multivariate polynomial and substitute the real # coefficients into that result (see #16014). @@ -7605,13 +7601,13 @@ cdef class Polynomial(CommutativePolynomial): k = d.degree() r = n % 4 - u = -1 # (-1)**(n*(n-1)/2) + u = -1 # (-1)**(n*(n-1)/2) if r == 0 or r == 1: u = 1 try: an = self.get_coeff_c(n)**(n - k - 2) except ZeroDivisionError: - assert (n-k-2 == -1) + assert(n-k-2 == -1) # Rather than dividing the resultant by the leading coefficient, # we alter the Sylvester matrix (see #11782). mat = self.sylvester_matrix(d) @@ -7660,14 +7656,14 @@ cdef class Polynomial(CommutativePolynomial): if degree is not None: d = degree if d != degree: - raise ValueError("degree argument must be a non-negative integer, got %s" % (degree)) + raise ValueError("degree argument must be a non-negative integer, got %s"%(degree)) if len(v) < degree+1: v.reverse() v = [self.base_ring().zero()]*(degree+1-len(v)) + v elif len(v) > degree+1: v = v[:degree+1] v.reverse() - else: # len(v) == degree + 1 + else: # len(v) == degree + 1 v.reverse() else: v.reverse() @@ -8422,9 +8418,9 @@ cdef class Polynomial(CommutativePolynomial): sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField)) output_fp = isinstance(L, (sage.rings.abc.RealField, - sage.rings.abc.ComplexField, - sage.rings.abc.RealDoubleField, - sage.rings.abc.ComplexDoubleField)) + sage.rings.abc.ComplexField, + sage.rings.abc.RealDoubleField, + sage.rings.abc.ComplexDoubleField)) input_complex = isinstance(K, (sage.rings.abc.ComplexField, sage.rings.abc.ComplexDoubleField)) output_complex = isinstance(L, (sage.rings.abc.ComplexField, sage.rings.abc.ComplexDoubleField)) input_gaussian = (isinstance(K, sage.rings.abc.NumberField_quadratic) @@ -8507,20 +8503,20 @@ cdef class Polynomial(CommutativePolynomial): from sage.symbolic.constants import I coeffs = self.list() D = coeffs[1]*coeffs[1] - 4*coeffs[0]*coeffs[2] - l0 = None + l = None if D > 0: - l0 = [((-coeffs[1] - sqrt(D)) / 2 / coeffs[2], 1), - ((-coeffs[1] + sqrt(D)) / 2 / coeffs[2], 1)] + l = [((-coeffs[1]-sqrt(D))/2/coeffs[2], 1), + ((-coeffs[1]+sqrt(D))/2/coeffs[2], 1)] elif D < 0: - l0 = [((-coeffs[1] - I * sqrt(-D)) / 2 / coeffs[2], 1), - ((-coeffs[1] + I * sqrt(-D)) / 2 / coeffs[2], 1)] + l = [((-coeffs[1]-I*sqrt(-D))/2/coeffs[2], 1), + ((-coeffs[1]+I*sqrt(-D))/2/coeffs[2], 1)] elif D == 0: - l0 = [(-coeffs[1] / 2 / coeffs[2], 2)] - if l0: + l = [(-coeffs[1]/2/coeffs[2], 2)] + if l: if multiplicities: - return l0 + return l else: - return [val for val, m in l0] + return [val for val,m in l] from sage.symbolic.ring import SR vname = 'do_not_use_this_name_in_a_polynomial_coefficient' var = SR(vname) @@ -8538,7 +8534,7 @@ cdef class Polynomial(CommutativePolynomial): # and complex root isolation and for p-adic factorization if (is_IntegerRing(K) or is_RationalField(K) or isinstance(K, sage.rings.abc.AlgebraicRealField)) and \ - isinstance(L, (sage.rings.abc.AlgebraicRealField, sage.rings.abc.RealIntervalField)): + isinstance(L, (sage.rings.abc.AlgebraicRealField, sage.rings.abc.RealIntervalField)): from sage.rings.polynomial.real_roots import real_roots @@ -8568,7 +8564,7 @@ cdef class Polynomial(CommutativePolynomial): if (is_IntegerRing(K) or is_RationalField(K) or isinstance(K, sage.rings.abc.AlgebraicField_common) or input_gaussian) and \ - isinstance(L, (sage.rings.abc.ComplexIntervalField, sage.rings.abc.AlgebraicField_common)): + isinstance(L, (sage.rings.abc.ComplexIntervalField, sage.rings.abc.AlgebraicField_common)): from sage.rings.polynomial.complex_roots import complex_roots @@ -8686,7 +8682,7 @@ cdef class Polynomial(CommutativePolynomial): pass else: if multiplicities: - seq.append((rt, fac[1])) + seq.append((rt,fac[1])) else: seq.append(rt) return seq @@ -9092,7 +9088,7 @@ cdef class Polynomial(CommutativePolynomial): coeffs = [] m = Q.degree() // 2 for i in reversed(range(m + 1)): - coeffs.insert(0, Q[2*i]) # Note: degree of Q may be less than 2*i + coeffs.insert(0, Q[2*i]) # Note: degree of Q may be less than 2*i Q = (Q % (x**2 + q)**i) // x return S(coeffs), cofactor, q @@ -9298,7 +9294,7 @@ cdef class Polynomial(CommutativePolynomial): if hasattr(self.base_ring(), '_xgcd_univariate_polynomial'): return self.base_ring()._xgcd_univariate_polynomial(self, other) else: - raise NotImplementedError("%s does not provide an xgcd implementation for univariate polynomials" % self.base_ring()) + raise NotImplementedError("%s does not provide an xgcd implementation for univariate polynomials"%self.base_ring()) def rational_reconstruction(self, m, n_deg=None, d_deg=None): r""" @@ -9463,9 +9459,9 @@ cdef class Polynomial(CommutativePolynomial): sF = Pf(self) mF = Pf(m) n, d = sF.rational_reconstruction(mF, n_deg, d_deg) - lc = lcm([n.denominator(), d.denominator()]) - n *= lc - d *= lc + l = lcm([n.denominator(), d.denominator()]) + n *= l + d *= l return P(n), P(d) # n and d are unique if m.degree() > (n.degree() + d.degree()) @@ -9476,9 +9472,9 @@ cdef class Polynomial(CommutativePolynomial): if n_deg < 0 or d_deg < 0: raise ValueError("the degree bounds " - "n_deg and d_deg should be positive") + "n_deg and d_deg should be positive") - # XGCD until degree the degree of t1 surpasses the degree of n + #XGCD until degree the degree of t1 surpasses the degree of n s0 = P(0) t0 = P(1) s1 = P(m) @@ -9587,15 +9583,15 @@ cdef class Polynomial(CommutativePolynomial): _p = self._parent.coerce(p) elif p is infinity.infinity: return -self.degree() - elif is_Ideal(p) and p.ring() is self._parent: # eventually need to handle fractional ideals in the fraction field - if self._parent.base_ring().is_field(): # common case + elif is_Ideal(p) and p.ring() is self._parent: # eventually need to handle fractional ideals in the fraction field + if self._parent.base_ring().is_field(): # common case _p = p.gen() else: raise NotImplementedError else: from sage.rings.fraction_field import is_FractionField if is_FractionField(p.parent()) and self._parent.has_coerce_map_from(p.parent().ring()): - _p = self._parent.coerce(p.parent().ring()(p)) # here we require that p be integral. + _p = self._parent.coerce(p.parent().ring()(p)) # here we require that p be integral. else: raise TypeError("The polynomial, p, must have the same parent as self.") @@ -10850,13 +10846,13 @@ cdef class Polynomial(CommutativePolynomial): elif n == 1 or self.is_zero() or self.is_one(): return self elif self.degree() % n: - raise ValueError("not a %s power" % Integer(n).ordinal_str()) - elif self.get_unsafe(0).is_zero(): # We know that self is not 0, so it must have degree >= 0 + raise ValueError("not a %s power"%Integer(n).ordinal_str()) + elif self.get_unsafe(0).is_zero(): # We know that self is not 0, so it must have degree >= 0 # p = x^k q # p^(1/n) = x^(k/n) q^(1/n) i = self.valuation() - if i % n: - raise ValueError("not a %s power" % Integer(n).ordinal_str()) + if i%n: + raise ValueError("not a %s power"%Integer(n).ordinal_str()) return (self >> i).nth_root(n) << (i // n) if self.get_unsafe(0).is_one(): @@ -10875,7 +10871,7 @@ cdef class Polynomial(CommutativePolynomial): if q**n == p: return S(q) else: - raise ValueError("not a %s power" % Integer(n).ordinal_str()) + raise ValueError("not a %s power"%Integer(n).ordinal_str()) def _nth_root_series(self, long n, long prec, start=None): r""" @@ -10968,12 +10964,12 @@ cdef class Polynomial(CommutativePolynomial): raise ValueError("n (={}) must be positive".format(m)) elif m.is_one() or self.is_zero() or self.is_one(): return self - elif self.get_unsafe(0).is_zero(): # we know that self is not zero, so the degree >= 0 + elif self.get_unsafe(0).is_zero(): # we know that self is not zero, so the degree >= 0 # p = x^i q # p^(1/m) = x^(i/m) q^(1/m) i = self.valuation() if i % m: - raise ValueError("not a %s power" % m.ordinal_str()) + raise ValueError("not a %s power"%m.ordinal_str()) return (self >> i)._nth_root_series(m, prec - i // m) << (i // m) else: c = R.characteristic() @@ -10985,7 +10981,7 @@ cdef class Polynomial(CommutativePolynomial): for i in range(self.degree()+1): if self.get_unsafe(i): if i % cc: - raise ValueError("not a %s power" % m.ordinal_str()) + raise ValueError("not a %s power"%m.ordinal_str()) ans[i//cc] = self.get_unsafe(i).nth_root(cc) p = self._parent(ans) m = m // cc @@ -11081,16 +11077,12 @@ cdef class Polynomial(CommutativePolynomial): if not self.base_ring().is_integral_domain(): raise NotImplementedError("divisibility test only implemented for polynomials over an integral domain") - if p.is_zero(): - return True # everything divides 0 - if self.is_zero(): - return False # 0 only divides 0 + if p.is_zero(): return True # everything divides 0 + if self.is_zero(): return False # 0 only divides 0 try: - if self.is_unit(): - return True # units divide everything + if self.is_unit(): return True # units divide everything except NotImplementedError: - if self.is_one(): - return True # if is_unit is not implemented + if self.is_one(): return True # if is_unit is not implemented if self.degree() > p.degree(): return False @@ -11142,9 +11134,10 @@ cdef class Polynomial(CommutativePolynomial): raise ValueError("either the dictionary or the specialization must be provided") else: from sage.rings.polynomial.flatten import SpecializationMorphism - phi = SpecializationMorphism(self._parent, D) + phi = SpecializationMorphism(self._parent,D) return phi(self) + def _log_series(self, long n): r""" Return the power series expansion of logarithm of this polynomial, @@ -11342,10 +11335,10 @@ cdef list do_schoolbook_product(list x, list y, Py_ssize_t deg): return y elif d1 == 0: c = x[0] - return [c * a for a in y[:deg]] # beware of noncommutative rings + return [c*a for a in y[:deg]] # beware of noncommutative rings elif d2 == 0: c = y[0] - return [a * c for a in x[:deg]] # beware of noncommutative rings + return [a*c for a in x[:deg]] # beware of noncommutative rings coeffs = [None]*deg for k in range(deg): start = 0 if k <= d2 else k-d2 # max(0, k-d2) @@ -11391,10 +11384,10 @@ cdef list do_karatsuba_different_size(list left, list right, Py_ssize_t K_thresh return [] if n == 1: c = left[0] - return [c * a for a in right] + return [c*a for a in right] if m == 1: c = right[0] - return [a * c for a in left] # beware of noncommutative rings + return [a*c for a in left] # beware of noncommutative rings if n <= K_threshold or m <= K_threshold: return do_schoolbook_product(left, right, -1) if n == m: @@ -11441,7 +11434,7 @@ cdef list do_karatsuba_different_size(list left, list right, Py_ssize_t K_thresh @cython.boundscheck(False) @cython.wraparound(False) @cython.overflowcheck(False) -cdef list do_karatsuba(list left, list right, Py_ssize_t K_threshold, Py_ssize_t start_l, Py_ssize_t start_r, Py_ssize_t num_elts): +cdef list do_karatsuba(list left, list right, Py_ssize_t K_threshold,Py_ssize_t start_l, Py_ssize_t start_r,Py_ssize_t num_elts): """ Core routine for Karatsuba multiplication. This function works for two polynomials of the same degree. @@ -11496,8 +11489,8 @@ cdef list do_karatsuba(list left, list right, Py_ssize_t K_threshold, Py_ssize_t d = right[start_r] c = right[start_r+1] return [b*d, a*d+b*c, a*c] - return do_schoolbook_product(left[start_l:start_l + num_elts], - right[start_r:start_r + num_elts], -1) + return do_schoolbook_product(left[start_l:start_l+num_elts], + right[start_r:start_r+num_elts], -1) if num_elts == 2: # beware of noncommutative rings b = left[start_l] @@ -11531,7 +11524,7 @@ cdef list do_karatsuba(list left, list right, Py_ssize_t K_threshold, Py_ssize_t bd[e+i] = bd[e+i] + tt1[i] bd.append(tt1[e-1]) for i from 0 <= i < lenac -e: - ac[i] = ac[i] + tt1[e + i] + ac[i] = ac[i] + tt1[e+i] return bd + ac @@ -11610,10 +11603,10 @@ cdef class Polynomial_generic_dense(Polynomial): check = 0 elif not isinstance(x, (list, tuple)): # We trust that the element constructors do not send x=0 - # if x: +# if x: x = [x] # constant polynomials - # else: - # x = [] # zero polynomial +# else: +# x = [] # zero polynomial if check: self._coeffs = [R(z, **kwds) for z in x] self._normalize() @@ -11646,9 +11639,9 @@ cdef class Polynomial_generic_dense(Polynomial): Univariate Polynomial Ring in x over Univariate Polynomial Ring in y over Rational Field """ if a: - return self._new_c([a], P) + return self._new_c([a],P) else: - return self._new_c([], P) + return self._new_c([],P) def __reduce__(self): """ @@ -11717,7 +11710,7 @@ cdef class Polynomial_generic_dense(Polynomial): for i in range(ell): v[i+d] = c * x[i] cdef Polynomial_generic_dense res = self._new_c(v, self._parent) - # if not v[len(v)-1]: + #if not v[len(v)-1]: # "normalize" checks this anyway... res._normalize() return res @@ -11860,7 +11853,7 @@ cdef class Polynomial_generic_dense(Polynomial): 2*y*x^3 + (y + 3)*x^2 + (-2*y + 1)*x + 1 """ cdef Polynomial_generic_dense res - cdef Py_ssize_t check = 0, i, min + cdef Py_ssize_t check=0, i, min x = (self)._coeffs y = (right)._coeffs if len(x) > len(y): @@ -11881,7 +11874,7 @@ cdef class Polynomial_generic_dense(Polynomial): cpdef _sub_(self, right): cdef Polynomial_generic_dense res - cdef Py_ssize_t check = 0, i, min + cdef Py_ssize_t check=0, i, min x = (self)._coeffs y = (right)._coeffs if len(x) > len(y): @@ -11907,7 +11900,7 @@ cdef class Polynomial_generic_dense(Polynomial): c = (self._coeffs[0])._parent.coerce(c) v = [c * a for a in self._coeffs] cdef Polynomial_generic_dense res = self._new_c(v, self._parent) - # if not v[len(v)-1]: + #if not v[len(v)-1]: # "normalize" checks this anyway... res._normalize() return res @@ -11919,7 +11912,7 @@ cdef class Polynomial_generic_dense(Polynomial): c = (self._coeffs[0])._parent.coerce(c) v = [a * c for a in self._coeffs] cdef Polynomial_generic_dense res = self._new_c(v, self._parent) - # if not v[len(v)-1]: + #if not v[len(v)-1]: # "normalize" checks this anyway... res._normalize() return res @@ -12128,7 +12121,7 @@ cdef class Polynomial_generic_dense(Polynomial): quo.append(q) quo.reverse() - return self._new_c(quo, self._parent), self._new_c(x, self._parent)._inplace_truncate(n-1) + return self._new_c(quo,self._parent), self._new_c(x,self._parent)._inplace_truncate(n-1) cpdef Polynomial truncate(self, long n): r""" @@ -12157,10 +12150,10 @@ cdef class Polynomial_generic_dense(Polynomial): sage: type(f) """ - ln = len(self._coeffs) - if n > ln: - n = ln - while n > 0 and not self._coeffs[n - 1]: + l = len(self._coeffs) + if n > l: + n = l + while n > 0 and not self._coeffs[n-1]: n -= 1 return self._new_c(self._coeffs[:n], self._parent) @@ -12171,7 +12164,6 @@ cdef class Polynomial_generic_dense(Polynomial): self._coeffs = self._coeffs[:n] return self - def make_generic_polynomial(parent, coeffs): return parent(coeffs) @@ -12213,7 +12205,7 @@ def universal_discriminant(n): pr1 = PolynomialRing(ZZ, n + 1, 'a') pr2 = PolynomialRing(pr1, 'x') p = pr2(list(pr1.gens())) - return (1 - (n & 2)) * p.resultant(p.derivative()) // pr1.gen(n) + return (1 - (n&2))*p.resultant(p.derivative())//pr1.gen(n) cpdef Polynomial generic_power_trunc(Polynomial p, Integer n, long prec): @@ -12309,7 +12301,7 @@ cpdef list _dict_to_list(dict x, zero): return [] n = max(x.keys()) cdef list v - if isinstance(n, tuple): # a mpoly dict + if isinstance(n, tuple): # a mpoly dict n = n[0] v = [zero] * (n+1) for i, z in x.iteritems(): From 5f215beed284d864663931cd95bdd067918c832c Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 1 Oct 2023 11:32:17 +0200 Subject: [PATCH 064/463] undo format changes for matrix_space.py --- src/sage/matrix/matrix_space.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 04ab6b138a2..905b6fcc779 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -802,7 +802,7 @@ def transposed(self): Full MatrixSpace of 3 by 2 dense matrices over Integer Ring """ return MatrixSpace(self._base, self.__ncols, self.__nrows, - self.__is_sparse, self.Element) + self.__is_sparse, self.Element) @lazy_attribute def _copy_zero(self): @@ -2186,7 +2186,7 @@ def row_space(self): return self.__row_space except AttributeError: self.__row_space = sage.modules.free_module.FreeModule(self.base_ring(), - self.ncols(), sparse=self.is_sparse()) + self.ncols(), sparse=self.is_sparse()) return self.__row_space def column_space(self): @@ -2204,7 +2204,7 @@ def column_space(self): return self.__column_space except AttributeError: self.__column_space = sage.modules.free_module.FreeModule(self.base_ring(), self.nrows(), - sparse=self.is_sparse()) + sparse=self.is_sparse()) return self.__column_space def random_element(self, density=None, *args, **kwds): @@ -2262,10 +2262,10 @@ def random_element(self, density=None, *args, **kwds): Z = self.zero_matrix().__copy__() if density is None: Z.randomize(density=float(1), nonzero=kwds.pop('nonzero', False), - *args, **kwds) + *args, **kwds) else: Z.randomize(density=density, nonzero=kwds.pop('nonzero', True), - *args, **kwds) + *args, **kwds) return Z def _an_element_(self): @@ -2589,13 +2589,13 @@ def _MatrixSpace_ZZ_2x2(): register_unpickle_override('sage.matrix.matrix_modn_dense', - 'Matrix_modn_dense', Matrix_modn_dense_double) + 'Matrix_modn_dense', Matrix_modn_dense_double) register_unpickle_override('sage.matrix.matrix_integer_2x2', - 'Matrix_integer_2x2', Matrix_integer_dense) + 'Matrix_integer_2x2', Matrix_integer_dense) register_unpickle_override('sage.matrix.matrix_integer_2x2', - 'MatrixSpace_ZZ_2x2_class', MatrixSpace) + 'MatrixSpace_ZZ_2x2_class', MatrixSpace) register_unpickle_override('sage.matrix.matrix_integer_2x2', - 'MatrixSpace_ZZ_2x2', _MatrixSpace_ZZ_2x2) + 'MatrixSpace_ZZ_2x2', _MatrixSpace_ZZ_2x2) lazy_import('sage.matrix.matrix_gf2e_dense', 'unpickle_matrix_gf2e_dense_v0') register_unpickle_override('sage.matrix.matrix_mod2e_dense', - 'unpickle_matrix_mod2e_dense_v0', unpickle_matrix_gf2e_dense_v0) + 'unpickle_matrix_mod2e_dense_v0', unpickle_matrix_gf2e_dense_v0) From 2a244659f345684656ac77fdee70f70adc45b33d Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Mon, 9 Oct 2023 20:07:00 -0600 Subject: [PATCH 065/463] after first review --- .../matrix_laurent_mpolynomial_dense.pyx | 7 ++----- .../rings/polynomial/laurent_polynomial.pyx | 21 ++++++++++++------- .../polynomial/laurent_polynomial_ideal.py | 10 +++++++++ .../polynomial/laurent_polynomial_mpair.pyx | 7 ++++++- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx index 3f0c1e968f2..31ccba6c5d7 100644 --- a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx @@ -1,12 +1,9 @@ """ -Dense matrices over multivariate polynomials over fields - -This implementation inherits from Matrix_generic_dense, i.e. it is not -optimized for speed only some methods were added. +Dense matrices over multivariate polynomials over fields. AUTHOR: -* Enrique Artal +- Enrique Artal (2023-??): initial version """ # ***************************************************************************** diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index f0ccb4e2ce0..c69859d443c 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -1325,10 +1325,17 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: S. = LaurentPolynomialRing(QQ) sage: (t^-2 + 1).xgcd(t^-3 + 1) (1, 1/2*t^2 - 1/2*t^3 - 1/2*t^4, 1/2*t^3 + 1/2*t^4) + sage: R. = LaurentPolynomialRing(ZZ) + sage: f = 2*x^-2 - x^-1 + 4 + x + 139*x^2 - 5*x^3 + sage: g = -2 - x + 5*x^2 + 4*x^3 - x^4 + x^5 + sage: f.xgcd(g) + Traceback (most recent call last): + ... + NotImplementedError: only implemented when the base ring is an exact field """ R = self.parent() - if not R.is_exact() or not R.base_ring().is_field: - raise NotImplementedError("Not implemented") + if not R.is_exact() or not R.base_ring().is_field(): + raise NotImplementedError("only implemented when the base ring is an exact field") S = R.polynomial_ring() f, df = self.monomial_reduction() g, dg = other.monomial_reduction() @@ -1369,14 +1376,13 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): if u.is_unit(): return a.parent()(~u) if not a.parent().is_exact(): - raise NotImplementedError("Not implemented") + raise NotImplementedError("only implemented when the base ring is exact") g, s, _ = a.xgcd(m) if g == 1: return s elif g.is_unit(): return g.inverse_of_unit() * s - else: - raise ValueError("Impossible inverse modulo") + raise ValueError("impossible inverse modulo") def _fraction_pair(self): """ @@ -2079,7 +2085,6 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): ... NotImplementedError: divisibility test only implemented for Laurent polynomials over an integral domain - sage: R. = GF(2)[] sage: S. = LaurentPolynomialRing(R) sage: p = (x+y+1) * z**-1 + x*y @@ -2087,10 +2092,10 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: p.divides(q), p.divides(p*q) # needs sage.libs.singular (False, True) """ - if not self.base_ring().is_integral_domain(): + if not self._parent.base_ring().is_integral_domain(): raise NotImplementedError("divisibility test only implemented for Laurent polynomials over an integral domain") - R = self.parent().polynomial_ring() + R = self._parent.polynomial_ring() p = R(self.polynomial_construction()[0]) q = R(other.polynomial_construction()[0]) return p.divides(q) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 81bc095c382..b3b1d391eb4 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -205,6 +205,16 @@ def __contains__(self, f): return (g in self.polynomial_ideal()) def gens_reduced(self): + """ + A reduced system of generators. + + EXAMPLES:: + + sage: P. = LaurentPolynomialRing(QQ) + sage: J = P.ideal([x^2 - y^-2, x * y^3 + 2 * y^2+ y]) + sage: J.gens_reduced() + (x + 6*y + 5, 3*y^2 + 4*y + 1) + """ R = self.ring() J = self.polynomial_ideal() return tuple(R(p) for p in J.gens()) diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index fe199d281e3..e8b919b437e 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1856,9 +1856,14 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): return ans def divides(self, other): - R = self.parent().polynomial_ring() + """ + Check if `self` divides `other` + """ + R = self._parent.polynomial_ring() if not R.base_ring().is_integral_domain(): raise NotImplementedError("divisibility test only implemented for polynomials over an integral domain") + if other.parent() != R: + return None p = R(self.monomial_reduction()[0]) q = R(other.monomial_reduction()[0]) return p.divides(q) From cc813a04bbc5501525ebdd8825c91fe9a7b9cab0 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Tue, 10 Oct 2023 09:47:51 -0600 Subject: [PATCH 066/463] changes in divides --- src/sage/rings/polynomial/laurent_polynomial.pyx | 5 +---- .../rings/polynomial/laurent_polynomial_ideal.py | 2 +- .../polynomial/laurent_polynomial_mpair.pyx | 16 ++++++++++++---- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index c69859d443c..fba83a5ff42 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -2083,7 +2083,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: p.divides(q) Traceback (most recent call last): ... - NotImplementedError: divisibility test only implemented for Laurent polynomials over an integral domain + NotImplementedError: divisibility test only implemented for polynomials over an integral domain sage: R. = GF(2)[] sage: S. = LaurentPolynomialRing(R) @@ -2092,9 +2092,6 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: p.divides(q), p.divides(p*q) # needs sage.libs.singular (False, True) """ - if not self._parent.base_ring().is_integral_domain(): - raise NotImplementedError("divisibility test only implemented for Laurent polynomials over an integral domain") - R = self._parent.polynomial_ring() p = R(self.polynomial_construction()[0]) q = R(other.polynomial_construction()[0]) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index b3b1d391eb4..0d5a6ad38ce 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -92,7 +92,7 @@ def __init__(self, ring, gens, coerce=True, hint=None): """ Ideal_generic.__init__(self, ring, gens, coerce=coerce) self._poly_ring = ring.polynomial_ring() - self._poly_ideal = None # Create only as needed + self._poly_ideal = None # Create only as needed self._saturated = False self._hint = self._poly_ring.ideal([f.monomial_reduction()[0] for f in self.gens()]) # if hint is None: diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index e8b919b437e..fe7c0bdd787 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1858,12 +1858,20 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): def divides(self, other): """ Check if `self` divides `other` + + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(QQ) + sage: f1 = x^-2*y^3 - 9 - 1/14*x^-1*y - 1/3*x^-1 + sage: h = 3*x^-1 - 3*x^-2*y - 1/2*x^-3*y^2 - x^-3*y + x^-3 + sage: f2 = f1 * h + sage: f3 = f2 + x * y + sage: f1.divides(f2) + True + sage: f1.divides(f3) + False """ R = self._parent.polynomial_ring() - if not R.base_ring().is_integral_domain(): - raise NotImplementedError("divisibility test only implemented for polynomials over an integral domain") - if other.parent() != R: - return None p = R(self.monomial_reduction()[0]) q = R(other.monomial_reduction()[0]) return p.divides(q) From d68f6a5625fb661c12475099ef0f2c3155be19ce Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Fri, 13 Oct 2023 07:51:57 -0600 Subject: [PATCH 067/463] trick to solve the hint issue --- src/sage/rings/polynomial/ideal.py | 15 +++++++++++++++ src/sage/rings/polynomial/laurent_polynomial.pyx | 9 --------- .../rings/polynomial/laurent_polynomial_ideal.py | 10 +++++----- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/sage/rings/polynomial/ideal.py b/src/sage/rings/polynomial/ideal.py index 1ab86736d5b..e61b6de3f39 100644 --- a/src/sage/rings/polynomial/ideal.py +++ b/src/sage/rings/polynomial/ideal.py @@ -85,3 +85,18 @@ def groebner_basis(self, algorithm=None): gb = self.gens_reduced() from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence_generic return PolynomialSequence_generic([gb], self.ring(), immutable=True) + + def change_ring(self, R): + """ + Coerce an ideal into a new ring. + + EXAMPLES:: + + sage: P. = LaurentPolynomialRing(QQ, 2) + sage: I = P.ideal([x + y]) + sage: Q. = LaurentPolynomialRing(QQ, 3) + sage: I.change_ring(Q) + Ideal (x + y) of Multivariate Laurent Polynomial Ring in x, y, z + over Rational Field + """ + return R.ideal(self.gens()) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index fba83a5ff42..748a07f7270 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -1325,17 +1325,8 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: S. = LaurentPolynomialRing(QQ) sage: (t^-2 + 1).xgcd(t^-3 + 1) (1, 1/2*t^2 - 1/2*t^3 - 1/2*t^4, 1/2*t^3 + 1/2*t^4) - sage: R. = LaurentPolynomialRing(ZZ) - sage: f = 2*x^-2 - x^-1 + 4 + x + 139*x^2 - 5*x^3 - sage: g = -2 - x + 5*x^2 + 4*x^3 - x^4 + x^5 - sage: f.xgcd(g) - Traceback (most recent call last): - ... - NotImplementedError: only implemented when the base ring is an exact field """ R = self.parent() - if not R.is_exact() or not R.base_ring().is_field(): - raise NotImplementedError("only implemented when the base ring is an exact field") S = R.polynomial_ring() f, df = self.monomial_reduction() g, dg = other.monomial_reduction() diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 0d5a6ad38ce..7b3b3a12ad3 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -94,11 +94,11 @@ def __init__(self, ring, gens, coerce=True, hint=None): self._poly_ring = ring.polynomial_ring() self._poly_ideal = None # Create only as needed self._saturated = False - self._hint = self._poly_ring.ideal([f.monomial_reduction()[0] for f in self.gens()]) - # if hint is None: - # self._hint = self._poly_ring.zero_ideal() - # else: - # self._hint = hint.change_ring(self._poly_ring) + # self._hint = self._poly_ring.ideal([f.monomial_reduction()[0] for f in self.gens()]) + if hint is None: + self._hint = self._poly_ring.zero_ideal() + else: + self._hint = hint.change_ring(self._poly_ring) def set_hint(self, hint): """ From fe045a2a5eceb4f73dd53e20097d60b56697aba1 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Mon, 16 Oct 2023 16:09:22 +0200 Subject: [PATCH 068/463] descripion of Laurent matrix class --- src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx index 31ccba6c5d7..3794854e222 100644 --- a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx @@ -32,7 +32,7 @@ from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomial cdef class Matrix_laurent_mpolynomial_dense(Matrix_generic_dense): """ - Dense matrix over a multivariate polynomial ring over a field. + Dense matrix over a Laurent multivariate polynomial ring over a field. """ def laurent_matrix_reduction(self): """ From 59e7c09eb75e8ca578e2ff56106cf6c1eba6b571 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Tue, 17 Oct 2023 17:58:56 +0200 Subject: [PATCH 069/463] tests polynomial ideal --- src/sage/rings/polynomial/laurent_polynomial_ideal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 7b3b3a12ad3..c556e1a7205 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -114,7 +114,7 @@ def set_hint(self, hint): sage: P. = LaurentPolynomialRing(QQ, 3) sage: I = P.ideal([x^2*y + 3*x*y^2]) sage: I.hint() - Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y, z over Rational Field + Ideal (0) of Multivariate Polynomial Ring in x, y, z over Rational Field sage: I.set_hint(P.polynomial_ring().ideal([x + 3*y])) sage: I.hint() Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y, z over Rational Field @@ -135,7 +135,7 @@ def hint(self): sage: P. = LaurentPolynomialRing(QQ, 3) sage: I = P.ideal([x^2*y + 3*x*y^2]) sage: I.hint() - Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y, z over Rational Field + Ideal (0) of Multivariate Polynomial Ring in x, y, z over Rational Field """ return self._hint From 01977ca18e1a818c73a0014f7568094891212f75 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Mon, 23 Oct 2023 09:08:51 +0200 Subject: [PATCH 070/463] changes from revision october 23rd --- .../matrix/matrix_laurent_mpolynomial_dense.pxd | 6 ++++++ .../matrix/matrix_laurent_mpolynomial_dense.pyx | 17 ++++------------- .../rings/polynomial/laurent_polynomial.pyx | 12 ++++-------- .../polynomial/laurent_polynomial_ideal.py | 6 +++--- .../polynomial/laurent_polynomial_mpair.pyx | 5 ++++- 5 files changed, 21 insertions(+), 25 deletions(-) create mode 100644 src/sage/matrix/matrix_laurent_mpolynomial_dense.pxd diff --git a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pxd b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pxd new file mode 100644 index 00000000000..4679933c7f5 --- /dev/null +++ b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pxd @@ -0,0 +1,6 @@ +from sage.matrix.matrix_generic_dense cimport Matrix_generic_dense + +from sage.libs.singular.decl cimport ideal + +cdef class Matrix_Laurent_mpolynomial_dense(Matrix_generic_dense): + pass diff --git a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx index 3794854e222..775f6318bac 100644 --- a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx @@ -16,17 +16,6 @@ AUTHOR: # ***************************************************************************** from sage.matrix.matrix_generic_dense cimport Matrix_generic_dense -# from sage.matrix.matrix2 cimport Matrix -# -# from sage.matrix.constructor import identity_matrix -# from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic -# from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular -# from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular -# -# from sage.libs.singular.function import singular_function, lib -# -# from cysignals.signals cimport sig_on, sig_off - from sage.matrix.constructor import identity_matrix from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic @@ -40,8 +29,10 @@ cdef class Matrix_laurent_mpolynomial_dense(Matrix_generic_dense): to obtain a matrix `P` of polynomials such that the variables do not divide no column and no row. - OUTPUT: Three matrices `L`, `P`, `R` such that `self = L P R`, where `L` and - `R` are diagonal with monomial entries. + OUTPUT: + + Three matrices `L`, `P`, `R` such that ``self` equals `L P R`, where `L` and + `R` are diagonal with monomial entries. EXAMPLES: diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 748a07f7270..91619cdfd69 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -1341,6 +1341,9 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): The parameter ``m`` may be either a single polynomial or an ideal (for consistency with :meth:`inverse_mod` in other rings). + ALGORITHM: Solve the system `as + mt = 1`, returning `s` as the inverse + of `a` mod `m`. + EXAMPLES:: sage: S. = LaurentPolynomialRing(QQ) @@ -1348,15 +1351,12 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): 1/2*t^2 - 1/2*t^3 - 1/2*t^4 sage: f * (t^-2 + 1) + (1/2*t^4 + 1/2*t^3) * (t^-3 + 1) 1 - - ALGORITHM: Solve the system `as + mt = 1`, returning `s` as the inverse - of `a` mod `m`. """ from sage.rings.ideal import is_Ideal if is_Ideal(m): v = m.gens_reduced() if len(v) > 1: - raise NotImplementedError("Don't know how to invert modulo non-principal ideal %s" % m) + raise NotImplementedError("only inversion modulo principal ideals implemented") m = v[0] if m.degree() == 1 and m[1].is_unit(): # a(x) mod (x-r) = a(r) @@ -1366,8 +1366,6 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): u = a(r) if u.is_unit(): return a.parent()(~u) - if not a.parent().is_exact(): - raise NotImplementedError("only implemented when the base ring is exact") g, s, _ = a.xgcd(m) if g == 1: return s @@ -2053,8 +2051,6 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): r""" Return ``True`` if ``self`` divides ``other``. - This method is only implemented for Laurent polynomials over an integral domain. - EXAMPLES:: sage: R. = LaurentPolynomialRing(ZZ) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index c556e1a7205..1b836305af1 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -206,7 +206,7 @@ def __contains__(self, f): def gens_reduced(self): """ - A reduced system of generators. + A reduced system of generators. EXAMPLES:: @@ -217,7 +217,7 @@ def gens_reduced(self): """ R = self.ring() J = self.polynomial_ideal() - return tuple(R(p) for p in J.gens()) + return tuple([R(p) for p in J.gens()]) # Operations on ideals @@ -423,7 +423,7 @@ def polynomial_ideal(self, saturate=True): Q = self._poly_ring if len(P.gens()) == 1: a = [Q(p.polynomial_construction()[0]) for p in self.gens()] - if P.is_integral_domain(): + if P.base_ring().is_field(): a = GCD(a) return Q.ideal(a) if self._poly_ideal is not None and (self._saturated or not saturate): diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index fe7c0bdd787..27c31754d8f 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1855,9 +1855,10 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): return new_ring(ans) return ans + @coerce_binop def divides(self, other): """ - Check if `self` divides `other` + Check if ``self`` divides ``other`` EXAMPLES:: @@ -1870,6 +1871,8 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): True sage: f1.divides(f3) False + sage: f1.divides(3) + False """ R = self._parent.polynomial_ring() p = R(self.monomial_reduction()[0]) From 314c4bb23283b0b9a155db6e2e4d41f7e0396f4c Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Mon, 23 Oct 2023 11:50:19 +0200 Subject: [PATCH 071/463] change position of conditional in divides --- .../polynomial/laurent_polynomial_ring.py | 1 + .../rings/polynomial/polynomial_element.pyx | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index 22d97975cd6..fdc04260001 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -443,6 +443,7 @@ def __init__(self, R): TESTS:: sage: TestSuite(LaurentPolynomialRing(Zmod(2), 'y')).run() + sage: TestSuite(LaurentPolynomialRing(Zmod(4), 'y')).run() sage: TestSuite(LaurentPolynomialRing(ZZ, 'u')).run() sage: TestSuite(LaurentPolynomialRing(Zmod(2)['T'], 'u')).run() """ diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index a5b7f937cfe..7e006973db3 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -11074,15 +11074,19 @@ cdef class Polynomial(CommutativePolynomial): sage: p.divides(q), p.divides(p*q) # needs sage.libs.singular (False, True) """ - if not self.base_ring().is_integral_domain(): - raise NotImplementedError("divisibility test only implemented for polynomials over an integral domain") - - if p.is_zero(): return True # everything divides 0 - if self.is_zero(): return False # 0 only divides 0 + if p.is_zero(): + return True # everything divides 0 + if self.is_zero(): + return False # 0 only divides 0 try: - if self.is_unit(): return True # units divide everything + if self.is_unit(): + return True # units divide everything except NotImplementedError: - if self.is_one(): return True # if is_unit is not implemented + if self.is_one(): + return True # if is_unit is not implemented + + if not self.base_ring().is_integral_domain(): + raise NotImplementedError("divisibility test only implemented for polynomials over an integral domain") if self.degree() > p.degree(): return False From 72a36de551a5d05841c6e025a76e2e54bdff6821 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Tue, 24 Oct 2023 14:37:14 +0200 Subject: [PATCH 072/463] revision october 24th --- .../matrix_laurent_mpolynomial_dense.pxd | 2 -- .../matrix_laurent_mpolynomial_dense.pyx | 2 -- .../rings/polynomial/laurent_polynomial.pyx | 9 +++----- .../polynomial/laurent_polynomial_ideal.py | 22 ++++++++++++++++--- .../polynomial/laurent_polynomial_mpair.pyx | 5 ++--- .../polynomial/laurent_polynomial_ring.py | 1 + 6 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pxd b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pxd index 4679933c7f5..2a1170d0bc5 100644 --- a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pxd +++ b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pxd @@ -1,6 +1,4 @@ from sage.matrix.matrix_generic_dense cimport Matrix_generic_dense -from sage.libs.singular.decl cimport ideal - cdef class Matrix_Laurent_mpolynomial_dense(Matrix_generic_dense): pass diff --git a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx index 775f6318bac..1f345a68ba6 100644 --- a/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_laurent_mpolynomial_dense.pyx @@ -14,8 +14,6 @@ AUTHOR: # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.matrix.matrix_generic_dense cimport Matrix_generic_dense - from sage.matrix.constructor import identity_matrix from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 91619cdfd69..1e04abe3bf5 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -2068,9 +2068,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: p = 4*x + 3*x^-1 sage: q = 5*x^2 + x + 2*x^-2 sage: p.divides(q) - Traceback (most recent call last): - ... - NotImplementedError: divisibility test only implemented for polynomials over an integral domain + False sage: R. = GF(2)[] sage: S. = LaurentPolynomialRing(R) @@ -2079,7 +2077,6 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: p.divides(q), p.divides(p*q) # needs sage.libs.singular (False, True) """ - R = self._parent.polynomial_ring() - p = R(self.polynomial_construction()[0]) - q = R(other.polynomial_construction()[0]) + p = self.polynomial_construction()[0] + q = other.polynomial_construction()[0] return p.divides(q) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 1b836305af1..43f9bca511c 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -94,7 +94,6 @@ def __init__(self, ring, gens, coerce=True, hint=None): self._poly_ring = ring.polynomial_ring() self._poly_ideal = None # Create only as needed self._saturated = False - # self._hint = self._poly_ring.ideal([f.monomial_reduction()[0] for f in self.gens()]) if hint is None: self._hint = self._poly_ring.zero_ideal() else: @@ -194,6 +193,14 @@ def __contains__(self, f): sage: I = P.ideal([x^2*y + 3*x*y^2]) sage: x + 3*y in I True + sage: I.gen(0).__reduce__() + (Multivariate Laurent Polynomial Ring in x, y over Rational Field, + (x^2*y + 3*x*y^2, (0, 0))) + sage: P. = LaurentPolynomialRing(QQ, 1) + sage: I = P.ideal([x^2 + 3*x]) + sage: I.gen(0).__reduce__() # Check the differences of __reduce__ for distinct Laurent polynomial rings + (Multivariate Laurent Polynomial Ring in x over Rational Field, + (x^2 + 3*x, (0,))) """ if not f or f in self.gens(): return True @@ -416,8 +423,17 @@ def polynomial_ideal(self, saturate=True): sage: P. = LaurentPolynomialRing(QQ, 2) sage: I = P.ideal([x^2*y + 3*x*y^2]) sage: I.polynomial_ideal() - Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y - over Rational Field + Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y over Rational Field + sage: P. = LaurentPolynomialRing(QQ) + sage: J = P.ideal(t^2 - t^-1) + sage: J.polynomial_ideal() + Principal ideal (t^3 - 1) of Univariate Polynomial Ring in t over Rational Field + sage: J = P.ideal([t^2 - t^-1, t + t^-1]) + sage: J.polynomial_ideal() + Principal ideal (1) of Univariate Polynomial Ring in t over Rational Field + sage: J = P.ideal([t^2 - t^-1, t - t^-1]) + sage: J.polynomial_ideal() + Principal ideal (t - 1) of Univariate Polynomial Ring in t over Rational Field """ P = self.ring() Q = self._poly_ring diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index 27c31754d8f..470c3b4ecc3 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1874,7 +1874,6 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: f1.divides(3) False """ - R = self._parent.polynomial_ring() - p = R(self.monomial_reduction()[0]) - q = R(other.monomial_reduction()[0]) + p = self.monomial_reduction()[0] + q = other.monomial_reduction()[0] return p.divides(q) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index fdc04260001..812a4b3a351 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -446,6 +446,7 @@ def __init__(self, R): sage: TestSuite(LaurentPolynomialRing(Zmod(4), 'y')).run() sage: TestSuite(LaurentPolynomialRing(ZZ, 'u')).run() sage: TestSuite(LaurentPolynomialRing(Zmod(2)['T'], 'u')).run() + sage: TestSuite(LaurentPolynomialRing(Zmod(4)['T'], 'u')).run() """ if R.ngens() != 1: raise ValueError("must be 1 generator") From 146508ebf4b48566127b1e92260b292d184c98bc Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Tue, 24 Oct 2023 22:57:38 +0200 Subject: [PATCH 073/463] forgot to push polynomial_element.pyx --- .../rings/polynomial/polynomial_element.pyx | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 7e006973db3..e6fc136df5e 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -11047,10 +11047,10 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = Zmod(6)[] sage: p = 4*x + 3 sage: q = 5*x**2 + x + 2 + sage: q.divides(p) + False sage: p.divides(q) - Traceback (most recent call last): - ... - NotImplementedError: divisibility test only implemented for polynomials over an integral domain + False TESTS:: @@ -11073,6 +11073,13 @@ cdef class Polynomial(CommutativePolynomial): sage: q = (y^2-x^2) * z^2 + z + x-y sage: p.divides(q), p.divides(p*q) # needs sage.libs.singular (False, True) + sage: R. = Zmod(6)[] + sage: p = 4*x + 3 + sage: q = 2*x**2 + x + 2 + sage: p.divides(q) + Traceback (most recent call last): + ... + NotImplementedError: divisibility test only implemented for polynomials over an integral domain unless obvious non divisibility of leading terms """ if p.is_zero(): return True # everything divides 0 @@ -11085,19 +11092,19 @@ cdef class Polynomial(CommutativePolynomial): if self.is_one(): return True # if is_unit is not implemented - if not self.base_ring().is_integral_domain(): - raise NotImplementedError("divisibility test only implemented for polynomials over an integral domain") - if self.degree() > p.degree(): return False if not self.leading_coefficient().divides(p.leading_coefficient()): return False + if not self.base_ring().is_integral_domain(): + raise NotImplementedError("divisibility test only implemented for polynomials over an integral domain unless obvious non divisibility of leading terms") + try: return (p % self).is_zero() # if quo_rem is defined except ArithmeticError: - return False # if division is not exact + return False def specialization(self, D=None, phi=None): r""" From d514d8d4a124e3b98a00e36426db3715c95c1bd6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 19 Dec 2022 19:17:31 -0800 Subject: [PATCH 074/463] pkgs/sage-sws2rst (pyproject.toml): Convert from setup.cfg using ini2toml-0.11.3 --- pkgs/sage-sws2rst/pyproject.toml | 25 +++++++++++++++++++++++++ pkgs/sage-sws2rst/setup.cfg | 16 ---------------- 2 files changed, 25 insertions(+), 16 deletions(-) create mode 100644 pkgs/sage-sws2rst/pyproject.toml delete mode 100644 pkgs/sage-sws2rst/setup.cfg diff --git a/pkgs/sage-sws2rst/pyproject.toml b/pkgs/sage-sws2rst/pyproject.toml new file mode 100644 index 00000000000..1232437fb1e --- /dev/null +++ b/pkgs/sage-sws2rst/pyproject.toml @@ -0,0 +1,25 @@ +[build-system] +requires = ["setuptools>=61.2"] +build-backend = "setuptools.build_meta" + +[project] +name = "sage-sws2rst" +description = "Sage: Open Source Mathematics Software: SageNB worksheet converter" +license = {text = "GNU General Public License (GPL) v3 or later"} +authors = [{name = "The Sage Developers", email = "sage-support@googlegroups.com"}] +urls = {Homepage = "https://www.sagemath.org"} +dynamic = ["version"] + +[project.readme] +file = "README.rst" +content-type = "text/x-rst" + +[tool.setuptools] +script-files = ["bin/sage-sws2rst"] +include-package-data = false + +[tool.setuptools.packages] +find = {namespaces = false} + +[tool.setuptools.dynamic] +version = {file = ["VERSION.txt"]} diff --git a/pkgs/sage-sws2rst/setup.cfg b/pkgs/sage-sws2rst/setup.cfg deleted file mode 100644 index 129f46d55e2..00000000000 --- a/pkgs/sage-sws2rst/setup.cfg +++ /dev/null @@ -1,16 +0,0 @@ -[metadata] -name = sage-sws2rst -version = file: VERSION.txt -description = Sage: Open Source Mathematics Software: SageNB worksheet converter -long_description = file: README.rst -long_description_content_type = text/x-rst -license = GNU General Public License (GPL) v3 or later -author = The Sage Developers -author_email = sage-support@googlegroups.com -url = https://www.sagemath.org - -[options] -packages = find: - -scripts = - bin/sage-sws2rst From 6fa10e9add40e04d0faa9525adcdb299543b2b05 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 28 Oct 2023 11:03:06 -0700 Subject: [PATCH 075/463] pkgs/sage-docbuild (pyproject.toml): Convert from setup.cfg using ini2toml-0.13 --- pkgs/sage-docbuild/pyproject.toml | 40 +++++++++++++++++++++++++++++++ pkgs/sage-docbuild/setup.cfg | 32 ------------------------- 2 files changed, 40 insertions(+), 32 deletions(-) create mode 100644 pkgs/sage-docbuild/pyproject.toml delete mode 100644 pkgs/sage-docbuild/setup.cfg diff --git a/pkgs/sage-docbuild/pyproject.toml b/pkgs/sage-docbuild/pyproject.toml new file mode 100644 index 00000000000..77840653af0 --- /dev/null +++ b/pkgs/sage-docbuild/pyproject.toml @@ -0,0 +1,40 @@ +[build-system] +requires = ["setuptools>=61.2"] +build-backend = "setuptools.build_meta" + +[project] +name = "sage-docbuild" +description = "Sage: Open Source Mathematics Software: Build system of the Sage documentation" +license = {text = "GNU General Public License (GPL) v2 or later"} +authors = [{name = "The Sage Developers", email = "sage-support@googlegroups.com"}] +classifiers = [ + "Development Status :: 6 - Mature", + "Intended Audience :: Education", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Operating System :: POSIX", + "Operating System :: MacOS :: MacOS X", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: Implementation :: CPython", + "Topic :: Scientific/Engineering :: Mathematics", +] +urls = {Homepage = "https://www.sagemath.org"} +dependencies = ["sphinx"] +dynamic = ["version"] + +[project.readme] +file = "README.rst" +content-type = "text/x-rst" + +[tool.setuptools] +packages = [ + "sage_docbuild", + "sage_docbuild.ext", +] +include-package-data = false + +[tool.setuptools.dynamic] +version = {file = ["VERSION.txt"]} diff --git a/pkgs/sage-docbuild/setup.cfg b/pkgs/sage-docbuild/setup.cfg deleted file mode 100644 index 596f9b4506e..00000000000 --- a/pkgs/sage-docbuild/setup.cfg +++ /dev/null @@ -1,32 +0,0 @@ -[metadata] -name = sage-docbuild -version = file: VERSION.txt -description = Sage: Open Source Mathematics Software: Build system of the Sage documentation -long_description = file: README.rst -long_description_content_type = text/x-rst -license = GNU General Public License (GPL) v2 or later -author = The Sage Developers -author_email = sage-support@googlegroups.com -url = https://www.sagemath.org - -classifiers = - Development Status :: 6 - Mature - Intended Audience :: Education - Intended Audience :: Science/Research - License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+) - Operating System :: POSIX - Operating System :: MacOS :: MacOS X - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: Implementation :: CPython - Topic :: Scientific/Engineering :: Mathematics - -[options] -packages = - sage_docbuild - sage_docbuild.ext - -install_requires = - sphinx From c67bd9a39f8c5556c335a36a788f9fbde2504789 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 28 Oct 2023 11:04:33 -0700 Subject: [PATCH 076/463] pkgs/sage-setup (pyproject.toml): Convert from setup.cfg using ini2toml-0.13 --- pkgs/sage-setup/pyproject.toml | 48 ++++++++++++++++++++++++++++++++++ pkgs/sage-setup/setup.cfg | 39 --------------------------- 2 files changed, 48 insertions(+), 39 deletions(-) create mode 100644 pkgs/sage-setup/pyproject.toml delete mode 100644 pkgs/sage-setup/setup.cfg diff --git a/pkgs/sage-setup/pyproject.toml b/pkgs/sage-setup/pyproject.toml new file mode 100644 index 00000000000..8042e92a244 --- /dev/null +++ b/pkgs/sage-setup/pyproject.toml @@ -0,0 +1,48 @@ +[build-system] +requires = ["setuptools>=61.2"] +build-backend = "setuptools.build_meta" + +[project] +name = "sage-setup" +description = "Sage: Open Source Mathematics Software: Build system of the Sage library" +license = {text = "GNU General Public License (GPL) v2 or later"} +authors = [{name = "The Sage Developers", email = "sage-support@googlegroups.com"}] +classifiers = [ + "Development Status :: 6 - Mature", + "Intended Audience :: Education", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Operating System :: POSIX", + "Operating System :: MacOS :: MacOS X", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: Implementation :: CPython", + "Topic :: Scientific/Engineering :: Mathematics", +] +urls = {Homepage = "https://www.sagemath.org"} +requires-python = ">=3.9, <3.12" +dependencies = [ + "pkgconfig", + "jinja2", +] +dynamic = ["version"] + +[project.readme] +file = "README.rst" +content-type = "text/x-rst" + +[tool.setuptools] +packages = [ + "sage_setup", + "sage_setup.autogen", + "sage_setup.autogen.interpreters", + "sage_setup.autogen.interpreters.specs", + "sage_setup.command", +] +include-package-data = false + +[tool.setuptools.dynamic] +version = {file = ["VERSION.txt"]} diff --git a/pkgs/sage-setup/setup.cfg b/pkgs/sage-setup/setup.cfg deleted file mode 100644 index 2355ef6b301..00000000000 --- a/pkgs/sage-setup/setup.cfg +++ /dev/null @@ -1,39 +0,0 @@ -[metadata] -name = sage-setup -version = file: VERSION.txt -description = Sage: Open Source Mathematics Software: Build system of the Sage library -long_description = file: README.rst -long_description_content_type = text/x-rst -license = GNU General Public License (GPL) v2 or later -author = The Sage Developers -author_email = sage-support@googlegroups.com -url = https://www.sagemath.org - -classifiers = - Development Status :: 6 - Mature - Intended Audience :: Education - Intended Audience :: Science/Research - License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+) - Operating System :: POSIX - Operating System :: MacOS :: MacOS X - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: Implementation :: CPython - Topic :: Scientific/Engineering :: Mathematics - -[options] -packages = - sage_setup - sage_setup.autogen - sage_setup.autogen.interpreters - sage_setup.autogen.interpreters.specs - sage_setup.command - -python_requires = >=3.9, <3.12 - -install_requires = - pkgconfig - jinja2 From 2b94d8d8f676ea39e3e8adb588af735b198a0a0d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 28 Oct 2023 11:05:31 -0700 Subject: [PATCH 077/463] pkgs/sage-setup/pyproject.toml: Remove Python 3.8 --- pkgs/sage-setup/pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/sage-setup/pyproject.toml b/pkgs/sage-setup/pyproject.toml index 8042e92a244..d8a870d2c92 100644 --- a/pkgs/sage-setup/pyproject.toml +++ b/pkgs/sage-setup/pyproject.toml @@ -15,7 +15,6 @@ classifiers = [ "Operating System :: POSIX", "Operating System :: MacOS :: MacOS X", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", From 5a273243a934697f39f432af434f10939ea1a094 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 29 Oct 2023 19:13:30 +0100 Subject: [PATCH 078/463] address siggestions from issue 36530 --- src/sage/graphs/generic_graph.py | 71 +++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index eedbc36bef3..33f50fd712d 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -7865,25 +7865,35 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", argument is set to ``None`` by default, which means that no constraint is set upon the first vertex in the path. + This parameter can only be used when ``algorithm`` is ``"MILP"``. + - ``t`` -- a vertex (default: ``None``); forces the destination of the path (the method then returns the longest path ending at ``t``). The argument is set to ``None`` by default, which means that no constraint is set upon the last vertex in the path. + This parameter can only be used when ``algorithm`` is ``"MILP"``. + - ``use_edge_labels`` -- boolean (default: ``False``); whether to compute a path with maximum weight where the weight of an edge is defined by its label (a label set to ``None`` or ``{}`` being considered as a weight of `1`), or to compute a path with the longest possible number of edges (i.e., edge weights are set to 1) + This parameter can only be used when ``algorithm`` is ``"MILP"``. + - ``algorithm`` -- string (default: ``"MILP"``); the algorithm to use - among ``"MILP"`` and ``"backtrack"``. Two remarks on this respect: + among ``"MILP"``, ``"backtrack"`` and ``"heuristic"``: - * While the MILP formulation returns an exact answer, the backtrack - algorithm is a randomized heuristic. + * ``"MILP"`` returns an exact answer. - * As the backtrack algorithm does not support edge weighting, setting - ``use_edge_labels=True`` will force the use of the MILP algorithm. + * ``"backtrack"`` will be renamed ``"heuristic"`` in the future. A + warning is raised when used. + + * ``"heuristic"`` is a randomized heuristic for finding a long path in + an unweighted (di)graph. This heuristic does not take into account + parameters ``s``, ``t`` and ``use_edge_labels``. An error is raised + if these parameters are set. - ``solver`` -- string (default: ``None``); specify a Mixed Integer Linear Programming (MILP) solver to be used. If set to ``None``, the @@ -7928,7 +7938,7 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", The heuristic totally agrees:: sage: g = graphs.PetersenGraph() - sage: p = g.longest_path(algorithm="backtrack").edges(sort=True, labels=False) + sage: p = g.longest_path(algorithm="heuristic").edges(sort=True, labels=False) sage: len(p) 9 @@ -7950,13 +7960,13 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", TESTS: - The argument ``algorithm`` must be either ``'backtrack'`` or - ``'MILP'``:: + The argument ``algorithm`` must be either ``'backtrack'``, + ``'heuristic'`` or ``'MILP'``:: sage: graphs.PetersenGraph().longest_path(algorithm="abc") Traceback (most recent call last): ... - ValueError: algorithm must be either 'backtrack' or 'MILP' + ValueError: algorithm must be either 'backtrack', 'heuristic' or 'MILP' Disconnected graphs not weighted:: @@ -8029,13 +8039,44 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", sage: H = {(0, 3), (2, 0), (3, 4)} sage: H == {x for x in G.longest_path().edge_iterator(labels=False)} # needs sage.numerical.mip True + + :gh:`12345`:: + + sage: G = graphs.PathGraph(3) + sage: P = G.longest_path(algorithm='backtrack') + doctest:...: FutureWarning: algorithm 'backtrack' will be renamed 'heuristic' in the future. + See https://github.com/sagemath/sage/issues/12345 for details. + sage: G.longest_path(algorithm='heuristic', s=0) + Traceback (most recent call last): + ... + ValueError: parameters s, t, and use_edge_labels can not be used in + combinaiton with algorithms 'backtrack' and 'heuristic' + sage: G.longest_path(algorithm='heuristic', t=2) + Traceback (most recent call last): + ... + ValueError: parameters s, t, and use_edge_labels can not be used in + combinaiton with algorithms 'backtrack' and 'heuristic' + sage: G.longest_path(algorithm='heuristic', use_edge_labels=True) + Traceback (most recent call last): + ... + ValueError: parameters s, t, and use_edge_labels can not be used in + combinaiton with algorithms 'backtrack' and 'heuristic' """ self._scream_if_not_simple() - if use_edge_labels: - algorithm = "MILP" - if algorithm not in ("backtrack", "MILP"): - raise ValueError("algorithm must be either 'backtrack' or 'MILP'") + if algorithm not in ("backtrack", "heuristic", "MILP"): + raise ValueError("algorithm must be either 'backtrack', 'heuristic' or 'MILP'") + if algorithm == "backtrack": + from sage.misc.superseded import warning + warning(12345, + "algorithm 'backtrack' will be renamed 'heuristic' in the future.", + FutureWarning) + algorithm = 'heuristic' + if algorithm == 'heuristic': + if s is not None or t is not None or use_edge_labels: + raise ValueError("parameters s, t, and use_edge_labels can not " + "be used in combinaiton with algorithms " + "'backtrack' and 'heuristic'") # Quick improvement if not self.is_connected(): @@ -8080,8 +8121,8 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", from sage.graphs.graph import Graph return [0, Graph()] if use_edge_labels else Graph() - # Calling the backtrack heuristic if asked - if algorithm == "backtrack": + # Calling the heuristic if asked + if algorithm == "heuristic": from sage.graphs.generic_graph_pyx import find_hamiltonian as fh x = fh(self, find_path=True)[1] return self.subgraph(vertices=x, edges=list(zip(x[:-1], x[1:]))) From 2aee48ba969c3f2e92b00574abba36ab7d4adee5 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 29 Oct 2023 19:24:27 +0100 Subject: [PATCH 079/463] add the number of this PR --- src/sage/graphs/generic_graph.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 33f50fd712d..0c2f0f88725 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -8040,12 +8040,12 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", sage: H == {x for x in G.longest_path().edge_iterator(labels=False)} # needs sage.numerical.mip True - :gh:`12345`:: + :issue:`36574`:: sage: G = graphs.PathGraph(3) sage: P = G.longest_path(algorithm='backtrack') doctest:...: FutureWarning: algorithm 'backtrack' will be renamed 'heuristic' in the future. - See https://github.com/sagemath/sage/issues/12345 for details. + See https://github.com/sagemath/sage/issues/36574 for details. sage: G.longest_path(algorithm='heuristic', s=0) Traceback (most recent call last): ... @@ -8068,7 +8068,7 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", raise ValueError("algorithm must be either 'backtrack', 'heuristic' or 'MILP'") if algorithm == "backtrack": from sage.misc.superseded import warning - warning(12345, + warning(36574, "algorithm 'backtrack' will be renamed 'heuristic' in the future.", FutureWarning) algorithm = 'heuristic' From 02799e4c29a068e386259ea8908a87ca4289b9a5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 29 Oct 2023 18:06:30 -0700 Subject: [PATCH 080/463] pkgs/sage-setup/pyproject.toml: Remove pkgconfig, make jinja2 an optional dep --- pkgs/sage-setup/pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/sage-setup/pyproject.toml b/pkgs/sage-setup/pyproject.toml index d8a870d2c92..1499fe4c9ba 100644 --- a/pkgs/sage-setup/pyproject.toml +++ b/pkgs/sage-setup/pyproject.toml @@ -23,16 +23,16 @@ classifiers = [ ] urls = {Homepage = "https://www.sagemath.org"} requires-python = ">=3.9, <3.12" -dependencies = [ - "pkgconfig", - "jinja2", -] +dependencies = [] dynamic = ["version"] [project.readme] file = "README.rst" content-type = "text/x-rst" +[project.optional-dependencies] +autogen = ["jinja2"] + [tool.setuptools] packages = [ "sage_setup", From 0eef9811bcef33209b3e8140f1275978c26578cd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 29 Oct 2023 18:08:01 -0700 Subject: [PATCH 081/463] src/pyproject.toml.m4: Use sage_setup[autogen] --- src/pyproject.toml.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pyproject.toml.m4 b/src/pyproject.toml.m4 index f707b6f890e..2b61ea041ea 100644 --- a/src/pyproject.toml.m4 +++ b/src/pyproject.toml.m4 @@ -1,6 +1,7 @@ [build-system] # Minimum requirements for the build system to execute. requires = [ + "sage_setup[autogen]", # Some version of sage-conf is required. # Note that PEP517/518 have no notion of optional sage_spkg dependencies: # https://github.com/pypa/pip/issues/6144 From 7da883413705c480d3ad37232b01bbc9e627fa17 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 29 Oct 2023 21:23:28 -0700 Subject: [PATCH 082/463] pkgs/sagemath-{bliss,coxeter3,...}/pyproject.toml.m4: Add pkgconfig to build-system requires --- pkgs/sagemath-bliss/pyproject.toml.m4 | 1 + pkgs/sagemath-coxeter3/pyproject.toml.m4 | 1 + pkgs/sagemath-mcqd/pyproject.toml.m4 | 1 + pkgs/sagemath-meataxe/pyproject.toml.m4 | 1 + pkgs/sagemath-sirocco/pyproject.toml.m4 | 1 + pkgs/sagemath-tdlib/pyproject.toml.m4 | 1 + 6 files changed, 6 insertions(+) diff --git a/pkgs/sagemath-bliss/pyproject.toml.m4 b/pkgs/sagemath-bliss/pyproject.toml.m4 index 1cbcdf7e162..7783c12c118 100644 --- a/pkgs/sagemath-bliss/pyproject.toml.m4 +++ b/pkgs/sagemath-bliss/pyproject.toml.m4 @@ -8,5 +8,6 @@ requires = [ SPKG_INSTALL_REQUIRES_sagemath_environment SPKG_INSTALL_REQUIRES_cython SPKG_INSTALL_REQUIRES_cysignals + SPKG_INSTALL_REQUIRES_pkgconfig ] build-backend = "setuptools.build_meta" diff --git a/pkgs/sagemath-coxeter3/pyproject.toml.m4 b/pkgs/sagemath-coxeter3/pyproject.toml.m4 index a7d65382b21..69613011371 100644 --- a/pkgs/sagemath-coxeter3/pyproject.toml.m4 +++ b/pkgs/sagemath-coxeter3/pyproject.toml.m4 @@ -7,5 +7,6 @@ requires = [ SPKG_INSTALL_REQUIRES_sagemath_environment SPKG_INSTALL_REQUIRES_cython SPKG_INSTALL_REQUIRES_cysignals + SPKG_INSTALL_REQUIRES_pkgconfig ] build-backend = "setuptools.build_meta" diff --git a/pkgs/sagemath-mcqd/pyproject.toml.m4 b/pkgs/sagemath-mcqd/pyproject.toml.m4 index 7e651119193..bb34e4c5eb9 100644 --- a/pkgs/sagemath-mcqd/pyproject.toml.m4 +++ b/pkgs/sagemath-mcqd/pyproject.toml.m4 @@ -8,5 +8,6 @@ requires = [ SPKG_INSTALL_REQUIRES_cython SPKG_INSTALL_REQUIRES_memory_allocator SPKG_INSTALL_REQUIRES_cysignals + SPKG_INSTALL_REQUIRES_pkgconfig ] build-backend = "setuptools.build_meta" diff --git a/pkgs/sagemath-meataxe/pyproject.toml.m4 b/pkgs/sagemath-meataxe/pyproject.toml.m4 index a7d65382b21..69613011371 100644 --- a/pkgs/sagemath-meataxe/pyproject.toml.m4 +++ b/pkgs/sagemath-meataxe/pyproject.toml.m4 @@ -7,5 +7,6 @@ requires = [ SPKG_INSTALL_REQUIRES_sagemath_environment SPKG_INSTALL_REQUIRES_cython SPKG_INSTALL_REQUIRES_cysignals + SPKG_INSTALL_REQUIRES_pkgconfig ] build-backend = "setuptools.build_meta" diff --git a/pkgs/sagemath-sirocco/pyproject.toml.m4 b/pkgs/sagemath-sirocco/pyproject.toml.m4 index 99894dd5e5e..684ed189d9f 100644 --- a/pkgs/sagemath-sirocco/pyproject.toml.m4 +++ b/pkgs/sagemath-sirocco/pyproject.toml.m4 @@ -8,5 +8,6 @@ requires = [ SPKG_INSTALL_REQUIRES_cython SPKG_INSTALL_REQUIRES_cypari SPKG_INSTALL_REQUIRES_cysignals + SPKG_INSTALL_REQUIRES_pkgconfig ] build-backend = "setuptools.build_meta" diff --git a/pkgs/sagemath-tdlib/pyproject.toml.m4 b/pkgs/sagemath-tdlib/pyproject.toml.m4 index a7d65382b21..69613011371 100644 --- a/pkgs/sagemath-tdlib/pyproject.toml.m4 +++ b/pkgs/sagemath-tdlib/pyproject.toml.m4 @@ -7,5 +7,6 @@ requires = [ SPKG_INSTALL_REQUIRES_sagemath_environment SPKG_INSTALL_REQUIRES_cython SPKG_INSTALL_REQUIRES_cysignals + SPKG_INSTALL_REQUIRES_pkgconfig ] build-backend = "setuptools.build_meta" From 815ce133a4ad4e937b6cc22e78528e3c44e945fc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 29 Oct 2023 21:42:04 -0700 Subject: [PATCH 083/463] pkgs/sagemath-{objects,categories}/pyproject.toml.m4: Add pkgconfig to build-system requires --- pkgs/sagemath-categories/pyproject.toml.m4 | 1 + pkgs/sagemath-objects/pyproject.toml.m4 | 1 + 2 files changed, 2 insertions(+) diff --git a/pkgs/sagemath-categories/pyproject.toml.m4 b/pkgs/sagemath-categories/pyproject.toml.m4 index cf4c97f1fd1..4049f5868a4 100644 --- a/pkgs/sagemath-categories/pyproject.toml.m4 +++ b/pkgs/sagemath-categories/pyproject.toml.m4 @@ -10,5 +10,6 @@ requires = [ SPKG_INSTALL_REQUIRES_cython SPKG_INSTALL_REQUIRES_gmpy2 SPKG_INSTALL_REQUIRES_cysignals + SPKG_INSTALL_REQUIRES_pkgconfig ] build-backend = "setuptools.build_meta" diff --git a/pkgs/sagemath-objects/pyproject.toml.m4 b/pkgs/sagemath-objects/pyproject.toml.m4 index d8fda57a8f8..ec98813d439 100644 --- a/pkgs/sagemath-objects/pyproject.toml.m4 +++ b/pkgs/sagemath-objects/pyproject.toml.m4 @@ -9,5 +9,6 @@ requires = [ SPKG_INSTALL_REQUIRES_cython SPKG_INSTALL_REQUIRES_gmpy2 SPKG_INSTALL_REQUIRES_cysignals + SPKG_INSTALL_REQUIRES_pkgconfig ] build-backend = "setuptools.build_meta" From 88f6795ebb75f3ab2ef379d523eddbdc291b3336 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Mon, 30 Oct 2023 14:36:53 +0530 Subject: [PATCH 084/463] implemented power of graph function under basic methods --- src/sage/graphs/graph.py | 56 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 2435bd815b7..b1e6573356d 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4890,6 +4890,62 @@ def independent_set_of_representatives(self, family, solver=None, verbose=0, return repr + @doc_index("Basic methods") + def power_of_graph(self, k): + r""" + Compute the kth power graph of an undirected, unweighted graph based on + shortest distances between nodes using BFS. + + INPUT: + - graph: An undirected, unweighted graph. + - k: The maximum path length for considering edges in the power graph. + + OUTPUT: + - The kth power graph based on shortest distances between nodes. + + EXAMPLE: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: k = 2 + sage: PG = power_graph_with_shortest_distances(G, k) + sage: PG.edges() + [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (5, 4), (4, 5)] + + """ + n = self.order() + all_distances = {} # Dictionary to store shortest distances between all pairs of nodes + + from collections import deque + + # Step 1: Compute shortest distances using BFS + for u in self.vertices(): + distances = {} # Dictionary to store distances from u to all other nodes + visited = {v: False for v in self.vertices()} + queue = deque() + + visited[u] = True + distances[u] = 0 + queue.append(u) + + while queue: + v = queue.popleft() + for neighbor in self.neighbors(v): + if not visited[neighbor]: + visited[neighbor] = True + distances[neighbor] = distances[v] + 1 + queue.append(neighbor) + + all_distances[u] = distances + + # Step 2: Create the kth power graph based on distances + PG = Graph() + for u in self.vertices(): + for v in self.vertices(): + if u != v and all_distances[u].get(v, float('inf')) <= k: + PG.add_edge(u, v) + + return PG + @doc_index("Algorithmically hard stuff") def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_tolerance=1e-3): r""" From 9fd89da36df7521fa85f3a787b70beef18b7d04d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 31 Oct 2023 12:38:15 -0700 Subject: [PATCH 085/463] .github/workflows: Replace always() by (success() || failure()), except for uploads of logs etc --- .github/workflows/build.yml | 20 ++++++++++---------- .github/workflows/doc-build-pdf.yml | 8 ++++---- .github/workflows/doc-build.yml | 8 ++++---- .github/workflows/lint.yml | 6 +++--- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7ac9c6154d0..ab66ec4fa95 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -96,7 +96,7 @@ jobs: SAGE_NUM_THREADS: 2 - name: Build modularized distributions - if: always() && steps.worktree.outcome == 'success' + if: (success() || failure()) && steps.worktree.outcome == 'success' run: make V=0 tox && make SAGE_CHECK=no pypi-wheels working-directory: ./worktree-image env: @@ -104,7 +104,7 @@ jobs: SAGE_NUM_THREADS: 2 - name: Static code check with pyright - if: always() && steps.worktree.outcome == 'success' + if: (success() || failure()) && steps.worktree.outcome == 'success' uses: jakebailey/pyright-action@v1 with: version: 1.1.332 @@ -116,7 +116,7 @@ jobs: NODE_OPTIONS: --max-old-space-size=8192 - name: Static code check with pyright (annotated) - if: always() && steps.worktree.outcome == 'success' + if: (success() || failure()) && steps.worktree.outcome == 'success' uses: jakebailey/pyright-action@v1 with: version: 1.1.332 @@ -130,7 +130,7 @@ jobs: - name: Clean (fallback to non-incremental) id: clean - if: always() && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' + if: (success() || failure()) && 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 @@ -143,7 +143,7 @@ jobs: # This step is needed because building the modularized distributions installs some optional packages, # so the editable install of sagelib needs to build the corresponding optional extension modules. id: build - if: always() && (steps.incremental.outcome == 'success' || steps.clean.outcome == 'success') + if: (success() || failure()) && (steps.incremental.outcome == 'success' || steps.clean.outcome == 'success') run: | make build working-directory: ./worktree-image @@ -154,7 +154,7 @@ jobs: # Testing - name: Test changed files (sage -t --new) - if: always() && steps.build.outcome == 'success' + if: (success() || failure()) && steps.build.outcome == 'success' run: | # We run tests with "sage -t --new"; this only tests the uncommitted changes. ./sage -t --new -p2 @@ -164,7 +164,7 @@ jobs: SAGE_NUM_THREADS: 2 - name: Test modularized distributions - if: always() && steps.build.outcome == 'success' + if: (success() || failure()) && steps.build.outcome == 'success' run: make V=0 tox && make pypi-wheels-check working-directory: ./worktree-image env: @@ -182,14 +182,14 @@ jobs: COLUMNS: 120 - name: Test all files (sage -t --all --long) - if: always() && steps.build.outcome == 'success' + if: (success() || failure()) && 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: ./worktree-image/src - name: Prepare coverage results - if: always() && steps.build.outcome == 'success' + if: (success() || failure()) && steps.build.outcome == 'success' run: | ./venv/bin/python3 -m coverage combine src/.coverage/ ./venv/bin/python3 -m coverage xml @@ -197,7 +197,7 @@ jobs: working-directory: ./worktree-image - name: Upload coverage to codecov - if: always() && steps.build.outcome == 'success' + if: (success() || failure()) && steps.build.outcome == 'success' uses: codecov/codecov-action@v3 with: files: ./worktree-image/coverage.xml diff --git a/.github/workflows/doc-build-pdf.yml b/.github/workflows/doc-build-pdf.yml index 2128277fbca..227ae001870 100644 --- a/.github/workflows/doc-build-pdf.yml +++ b/.github/workflows/doc-build-pdf.yml @@ -94,7 +94,7 @@ jobs: - name: Build (fallback to non-incremental) id: build - if: always() && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' + if: (success() || failure()) && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' run: | set -ex make sagelib-clean && git clean -fx src/sage && ./config.status && make build @@ -105,7 +105,7 @@ jobs: - name: Build docs (PDF) id: docbuild - if: always() && (steps.incremental.outcome == 'success' || steps.build.outcome == 'success') + if: (success() || failure()) && (steps.incremental.outcome == 'success' || steps.build.outcome == 'success') run: | make doc-clean doc-uninstall; make doc-pdf working-directory: ./worktree-image @@ -114,7 +114,7 @@ jobs: SAGE_NUM_THREADS: 2 - name: Copy docs - if: always() && steps.docbuild.outcome == 'success' + if: (success() || failure()) && steps.docbuild.outcome == 'success' run: | # For some reason the deploy step below cannot find /sage/... # So copy everything from there to local folder @@ -124,7 +124,7 @@ jobs: zip -r docs-pdf.zip docs - name: Upload docs - if: always() && steps.copy.outcome == 'success' + if: (success() || failure()) && steps.copy.outcome == 'success' uses: actions/upload-artifact@v3 with: name: docs-pdf diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 5eb3998feee..4e66cdac5f0 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -99,7 +99,7 @@ jobs: - name: Build (fallback to non-incremental) id: build - if: always() && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' + if: (success() || failure()) && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' run: | set -ex make sagelib-clean && git clean -fx src/sage && ./config.status && make sagemath_doc_html-build-deps @@ -110,7 +110,7 @@ jobs: - name: Build docs id: docbuild - if: always() && (steps.incremental.outcome == 'success' || steps.build.outcome == 'success') + if: (success() || failure()) && (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: | @@ -127,7 +127,7 @@ jobs: - name: Copy docs id: copy - if: always() && steps.docbuild.outcome == 'success' + if: (success() || failure()) && steps.docbuild.outcome == 'success' run: | set -ex mkdir -p ./docs @@ -191,7 +191,7 @@ jobs: zip -r docs.zip docs - name: Upload docs - if: always() && steps.copy.outcome == 'success' + if: (success() || failure()) && steps.copy.outcome == 'success' uses: actions/upload-artifact@v3 with: name: docs diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 41560674b49..7821ea20212 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -37,13 +37,13 @@ jobs: run: pip install tox - name: Code style check with pycodestyle - if: always() && steps.deps.outcome == 'success' + if: (success() || failure()) && steps.deps.outcome == 'success' run: tox -e pycodestyle-minimal - name: Code style check with relint - if: always() && steps.deps.outcome == 'success' + if: (success() || failure()) && steps.deps.outcome == 'success' run: tox -e relint -- src/sage/ - name: Validate docstring markup as RST - if: always() && steps.deps.outcome == 'success' + if: (success() || failure()) && steps.deps.outcome == 'success' run: tox -e rst From e939eca866393268569a2630e58257d72d666486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 1 Nov 2023 12:03:03 +0100 Subject: [PATCH 086/463] cylint cleanup in combinatorial polyhedra --- .../combinatorial_polyhedron/base.pxd | 1 + .../combinatorial_polyhedron/base.pyx | 35 ++++++-------- .../combinatorial_face.pxd | 1 + .../combinatorial_face.pyx | 46 +++++++++---------- .../combinatorial_polyhedron/conversions.pyx | 18 ++++++-- .../face_iterator.pxd | 2 + .../face_iterator.pyx | 35 +++++++------- .../face_list_data_structure.pxd | 5 +- .../face_list_data_structure.pyx | 2 +- .../list_of_faces.pxd | 1 + .../list_of_faces.pyx | 2 +- .../polyhedron_face_lattice.pxd | 1 + .../polyhedron_face_lattice.pyx | 32 ++++++------- 13 files changed, 90 insertions(+), 91 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd index 85a020df78a..8e1f3765e81 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd @@ -6,6 +6,7 @@ from .list_of_faces cimport ListOfFaces from .face_data_structure cimport face_t from .polyhedron_face_lattice cimport PolyhedronFaceLattice + @cython.final cdef class CombinatorialPolyhedron(SageObject): cdef public dict _cached_methods diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 8282fbbd1ca..33aac3d70f7 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -93,11 +93,10 @@ from sage.geometry.cone import ConvexRationalPolyhedralCone from sage.structure.element import Matrix from sage.matrix.matrix_dense cimport Matrix_dense from sage.misc.misc import is_iterator -from .conversions \ - import incidence_matrix_to_bit_rep_of_facets, \ - incidence_matrix_to_bit_rep_of_Vrep, \ - facets_tuple_to_bit_rep_of_facets, \ - facets_tuple_to_bit_rep_of_Vrep +from .conversions import (incidence_matrix_to_bit_rep_of_facets, + incidence_matrix_to_bit_rep_of_Vrep, + facets_tuple_to_bit_rep_of_facets, + facets_tuple_to_bit_rep_of_Vrep) from .conversions cimport Vrep_list_to_bit_rep from sage.misc.cachefunc import cached_method @@ -437,7 +436,7 @@ cdef class CombinatorialPolyhedron(SageObject): from sage.matrix.constructor import matrix from sage.rings.integer_ring import ZZ incidence_matrix = matrix(ZZ, data.incidence_matrix().rows() - + [[ZZ.one() for _ in range(len(data.facet_normals()))]]) + + [[ZZ.one() for _ in range(len(data.facet_normals()))]]) return self._init_from_incidence_matrix(incidence_matrix) cdef _init_facet_names(self, facets) noexcept: @@ -481,11 +480,10 @@ cdef class CombinatorialPolyhedron(SageObject): data.set_immutable() self.incidence_matrix.set_cache(data) - # Delete equations. data = data.delete_columns( [i for i in range(data.ncols()) - if all(data[j,i] for j in range(data.nrows()))], + if all(data[j, i] for j in range(data.nrows()))], check=False) # Initializing the facets in their Bit-representation. @@ -515,7 +513,7 @@ cdef class CombinatorialPolyhedron(SageObject): n_Vrepresentation = len(Vrep) if Vrep != range(len(Vrep)): self._Vrep = tuple(Vrep) - Vinv = {v: i for i,v in enumerate(self._Vrep)} + Vinv = {v: i for i, v in enumerate(self._Vrep)} else: # Assuming the user gave as correct names for the vertices # and labeled them instead by `0,...,n`. @@ -548,7 +546,7 @@ cdef class CombinatorialPolyhedron(SageObject): Initialize self from two ``ListOfFaces``. """ self._bitrep_facets = facets - self._bitrep_Vrep = Vrep + self._bitrep_Vrep = Vrep self._n_Hrepresentation = self._bitrep_facets.n_faces() self._n_Vrepresentation = self._bitrep_Vrep.n_faces() @@ -629,7 +627,7 @@ cdef class CombinatorialPolyhedron(SageObject): 'A 2-dimensional combinatorial polyhedron with 1 facet' """ desc = "A {}-dimensional combinatorial polyhedron with {} facet"\ - .format(self.dimension(), self.n_facets()) + .format(self.dimension(), self.n_facets()) if self.n_facets() != 1: desc += "s" return desc @@ -1694,7 +1692,7 @@ cdef class CombinatorialPolyhedron(SageObject): if not names: vertices = [i for i in range(n_facets + n_Vrep)] - edges = tuple((j, n_Vrep + n_facets - 1 - i) for i,facet in enumerate(facet_iter) for j in facet.ambient_V_indices()) + edges = tuple((j, n_Vrep + n_facets - 1 - i) for i, facet in enumerate(facet_iter) for j in facet.ambient_V_indices()) else: facet_names = self.facet_names() if facet_names is None: @@ -1707,7 +1705,7 @@ cdef class CombinatorialPolyhedron(SageObject): Vrep = [("V", i) for i in range(n_Vrep)] vertices = Vrep + facet_names - edges = tuple((Vrep[j], facet_names[n_facets - 1 - i]) for i,facet in enumerate(facet_iter) for j in facet.ambient_V_indices()) + edges = tuple((Vrep[j], facet_names[n_facets - 1 - i]) for i, facet in enumerate(facet_iter) for j in facet.ambient_V_indices()) return DiGraph([vertices, edges], format='vertices_and_edges', immutable=True) @cached_method @@ -2126,7 +2124,7 @@ cdef class CombinatorialPolyhedron(SageObject): cdef simpliciality = dim - 1 # For each face in the iterator, check if its a simplex. - face_iter.structure.lowest_dimension = 2 # every 1-face is a simplex + face_iter.structure.lowest_dimension = 2 # every 1-face is a simplex d = face_iter.next_dimension() while d < dim: sig_check() @@ -2237,7 +2235,7 @@ cdef class CombinatorialPolyhedron(SageObject): cdef simplicity = dim - 1 # For each coface in the iterator, check if its a simplex. - coface_iter.structure.lowest_dimension = 2 # every coface of dimension 1 is a simplex + coface_iter.structure.lowest_dimension = 2 # every coface of dimension 1 is a simplex d = coface_iter.next_dimension() while d < dim: sig_check() @@ -2623,7 +2621,6 @@ cdef class CombinatorialPolyhedron(SageObject): return (False, None) - def join_of_Vrep(self, *indices): r""" Return the smallest face containing all Vrepresentatives indicated by the indices. @@ -2793,7 +2790,6 @@ cdef class CombinatorialPolyhedron(SageObject): if 'dual' in kwds and dual == -1 and kwds['dual'] in (False, True): dual = int(kwds['dual']) - cdef FaceIterator face_iter if dual == -1: # Determine the faster way, to iterate through all faces. if not self.is_bounded() or self.n_facets() <= self.n_Vrepresentation(): @@ -3354,7 +3350,6 @@ cdef class CombinatorialPolyhedron(SageObject): and self.far_face_tuple() == other_C.far_face_tuple() and self.incidence_matrix() == other.incidence_matrix()) - # Methods to obtain a different combinatorial polyhedron. cpdef CombinatorialPolyhedron dual(self) noexcept: @@ -3484,7 +3479,6 @@ cdef class CombinatorialPolyhedron(SageObject): return CombinatorialPolyhedron((new_facets, new_Vrep), Vrep=new_Vrep_names, facets=new_facet_names) - # Internal methods. cdef int _compute_f_vector(self, size_t num_threads, size_t parallelization_depth, int dual) except -1: @@ -3497,7 +3491,6 @@ cdef class CombinatorialPolyhedron(SageObject): return 0 # There is no need to recompute the f_vector. cdef int dim = self.dimension() - cdef int d # dimension of the current face of the iterator cdef MemoryAllocator mem = MemoryAllocator() if num_threads == 0: @@ -3686,7 +3679,7 @@ cdef class CombinatorialPolyhedron(SageObject): from sage.arith.misc import binomial estimate_n_faces = self.dimension() * binomial(min(self.n_facets(), self.n_Vrepresentation()), - self.dimension() // 2) + self.dimension() // 2) # Note that the runtime per face already computes the coatoms of the next level, i.e. # the runtime for each facet suffices to compute all ridges in primal, diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd index 2169fe539f6..6dea4305ba7 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd @@ -4,6 +4,7 @@ from .list_of_faces cimport ListOfFaces from .face_data_structure cimport face_t from .face_iterator cimport FaceIterator + @cython.final cdef class CombinatorialFace(SageObject): cdef readonly bint _dual # if 1, then iterate over dual Polyhedron diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx index 541927c6c11..87ec3a1eb90 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx @@ -173,9 +173,9 @@ cdef class CombinatorialFace(SageObject): # Copy data from FaceIterator. it = data - self._dual = it.dual - self.atoms = it.atoms - self.coatoms = it.coatoms + self._dual = it.dual + self.atoms = it.atoms + self.coatoms = it.coatoms if it.structure.face_status == FaceStatus.NOT_INITIALIZED: raise LookupError("face iterator not set to a face") @@ -183,15 +183,15 @@ cdef class CombinatorialFace(SageObject): face_init(self.face, self.coatoms.n_atoms(), self.coatoms.n_coatoms()) face_copy(self.face, it.structure.face) - self._dimension = it.structure.current_dimension + self._dimension = it.structure.current_dimension self._ambient_dimension = it.structure.dimension - self._ambient_Vrep = it._Vrep - self._ambient_facets = it._facet_names - self._n_ambient_facets = it._n_facets - self._equations = it._equations - self._n_equations = it._n_equations - self._hash_index = it.structure._index - self._ambient_bounded = it._bounded + self._ambient_Vrep = it._Vrep + self._ambient_facets = it._facet_names + self._n_ambient_facets = it._n_facets + self._equations = it._equations + self._n_equations = it._n_equations + self._hash_index = it.structure._index + self._ambient_bounded = it._bounded self._initialized_from_face_lattice = False @@ -203,35 +203,35 @@ cdef class CombinatorialFace(SageObject): assert 0 <= index < all_faces.f_vector[dimension + 1], "index is out of range" # Copy data from PolyhedronFaceLattice. - self._dual = all_faces.dual - self.atoms = all_faces.atoms - self.coatoms = all_faces.coatoms + self._dual = all_faces.dual + self.atoms = all_faces.atoms + self.coatoms = all_faces.coatoms face_init(self.face, self.coatoms.n_atoms(), self.coatoms.n_coatoms()) face_copy(self.face, all_faces.faces[dimension+1].faces[index]) - self._dimension = dimension + self._dimension = dimension self._ambient_dimension = all_faces.dimension - self._ambient_Vrep = all_faces._Vrep - self._ambient_facets = all_faces._facet_names - self._equations = all_faces._equations - self._n_equations = len(self._equations) if self._equations else 0 + self._ambient_Vrep = all_faces._Vrep + self._ambient_facets = all_faces._facet_names + self._equations = all_faces._equations + self._n_equations = len(self._equations) if self._equations else 0 if self._dual: self._n_ambient_facets = self.atoms.n_faces() else: self._n_ambient_facets = self.coatoms.n_faces() - self._ambient_bounded = all_faces._bounded + self._ambient_bounded = all_faces._bounded self._initialized_from_face_lattice = True self._hash_index = index - for i in range(-1,dimension): + for i in range(-1, dimension): self._hash_index += all_faces.f_vector[i+1] # Add the complete ``f-vector`` to the hash index, # such that hash values obtained by an iterator or by the face lattice # do not collide. - for i in range(-1,self._ambient_dimension+1): + for i in range(-1, self._ambient_dimension+1): self._hash_index += all_faces.f_vector[i+1] else: raise ValueError("data must be face iterator or a list of all faces") @@ -273,7 +273,7 @@ cdef class CombinatorialFace(SageObject): 'A 3-dimensional face of a 5-dimensional combinatorial polyhedron' """ return "A {}-dimensional face of a {}-dimensional combinatorial polyhedron"\ - .format(self.dimension(), self.ambient_dimension()) + .format(self.dimension(), self.ambient_dimension()) def __reduce__(self): r""" diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx index baeb8fc4855..2f686364ac0 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx @@ -58,15 +58,15 @@ AUTHOR: - Jonathan Kliem (2019-04) """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2019 Jonathan Kliem # # 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 memory_allocator cimport MemoryAllocator @@ -94,6 +94,7 @@ def _Vrep_list_to_bit_rep_wrapper(tup): Vrep_list_to_bit_rep(tup, output.data.faces[0]) return output + cdef int Vrep_list_to_bit_rep(tuple Vrep_list, face_t output) except -1: r""" Convert a vertex list into Bit-representation. Store it in ``output``. @@ -135,6 +136,7 @@ cdef int Vrep_list_to_bit_rep(tuple Vrep_list, face_t output) except -1: for entry in Vrep_list: face_add_atom_safe(output, entry) + def _incidences_to_bit_rep_wrapper(tup): r""" A function to allow doctesting of :func:`incidences_to_bit_rep`. @@ -150,6 +152,7 @@ def _incidences_to_bit_rep_wrapper(tup): incidences_to_bit_rep(tup, output.data.faces[0]) return output + cdef int incidences_to_bit_rep(tuple incidences, face_t output) except -1: r""" Convert a tuple of incidences into Bit-representation. @@ -185,6 +188,7 @@ cdef int incidences_to_bit_rep(tuple incidences, face_t output) except -1: # Vrep ``entry`` is contained in the face, so set the corresponding bit face_add_atom_safe(output, entry) + def incidence_matrix_to_bit_rep_of_facets(Matrix_dense matrix): r""" Initialize facets in Bit-representation as :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces`. @@ -249,6 +253,7 @@ def incidence_matrix_to_bit_rep_of_facets(Matrix_dense matrix): face_add_atom_safe(output, entry) return facets + def incidence_matrix_to_bit_rep_of_Vrep(Matrix_dense matrix): r""" Initialize Vrepresentatives in Bit-representation as :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces`. @@ -307,6 +312,7 @@ def incidence_matrix_to_bit_rep_of_Vrep(Matrix_dense matrix): """ return incidence_matrix_to_bit_rep_of_facets(matrix.transpose()) + def facets_tuple_to_bit_rep_of_facets(tuple facets_input, size_t n_Vrep): r""" Initializes facets in Bit-representation as :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces`. @@ -348,6 +354,7 @@ def facets_tuple_to_bit_rep_of_facets(tuple facets_input, size_t n_Vrep): facet_set_coatom(facets.data.faces[i], i) return facets + def facets_tuple_to_bit_rep_of_Vrep(tuple facets_input, size_t n_Vrep): r""" Initialize Vrepresentatives in Bit-representation as :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces.ListOfFaces`. @@ -408,6 +415,7 @@ def facets_tuple_to_bit_rep_of_Vrep(tuple facets_input, size_t n_Vrep): face_add_atom_safe(Vrep_data[input_Vrep], input_facet) return Vrep + def _bit_rep_to_Vrep_list_wrapper(ListOfFaces faces, index=0): r""" A function to test :func:`bit_rep_to_Vrep_list`. @@ -433,10 +441,10 @@ def _bit_rep_to_Vrep_list_wrapper(ListOfFaces faces, index=0): output = mem.allocarray(faces.n_atoms(), sizeof(size_t)) - length = bit_rep_to_Vrep_list( - faces.data.faces[index], output) + length = bit_rep_to_Vrep_list(faces.data.faces[index], output) return tuple(output[i] for i in range(length)) + cdef inline size_t bit_rep_to_Vrep_list(face_t face, size_t *output) except -1: r""" Convert a bitrep-representation to a list of Vrep. Return length of representation. diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd index f148c81f7a9..8df85938e91 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd @@ -80,10 +80,12 @@ cdef class FaceIterator_base(SageObject): cdef int only_subsets(self) except -1 cdef int find_face(self, face_t face) except -1 + @cython.final cdef class FaceIterator(FaceIterator_base): pass + @cython.final cdef class FaceIterator_geom(FaceIterator_base): cdef int _trivial_faces # Whether to yield the trivial faces. diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx index d35033fc855..ea0c36eeb72 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx @@ -164,15 +164,15 @@ AUTHOR: - Jonathan Kliem (2019-04) """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2019 Jonathan Kliem # # 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 cython.parallel cimport prange, threadid from cysignals.memory cimport check_allocarray, sig_free @@ -244,7 +244,6 @@ cdef class FaceIterator_base(SageObject): if dual and not C.is_bounded(): raise ValueError("cannot iterate over dual of unbounded Polyedron") cdef int i - cdef size_t j self.dual = dual self.structure.dual = dual @@ -1189,7 +1188,7 @@ cdef class FaceIterator_base(SageObject): cdef size_t yet_to_visit = self.structure.yet_to_visit if unlikely(yet_to_visit >= faces[0].n_faces - or not faces_are_identical(faces[0].faces[yet_to_visit], self.structure.face)): + or not faces_are_identical(faces[0].faces[yet_to_visit], self.structure.face)): raise ValueError("iterator is not set to the correct face") swap_faces(faces[0].faces[yet_to_visit], faces[0].faces[faces[0].n_faces - 1]) @@ -1294,7 +1293,7 @@ cdef class FaceIterator_base(SageObject): self.structure.current_dimension = -1 return 0 - cdef int d = self.next_dimension() + self.next_dimension() while self.structure.current_dimension != self.structure.dimension: if face_issubset(face, self.structure.face): if face_issubset(self.structure.face, face): @@ -1304,7 +1303,7 @@ cdef class FaceIterator_base(SageObject): # The face is not a subface/supface of the current face. self.ignore_subsets() - d = self.next_dimension() + self.next_dimension() raise ValueError("the face appears to be incorrect") @@ -1883,7 +1882,7 @@ cdef class FaceIterator_geom(FaceIterator_base): if unlikely(self._trivial_faces): if self._trivial_faces == -1: raise StopIteration - if self._trivial_faces in (2,4): # Return the polyhedron. + if self._trivial_faces in (2, 4): # Return the polyhedron. if self._trivial_faces == 2: self._trivial_faces = 1 # Return the empty face next. else: @@ -2076,30 +2075,29 @@ cdef int parallel_f_vector(iter_t* structures, size_t num_threads, size_t parall if num_threads == 0: num_threads = 1 - cdef size_t thread_id cdef MemoryAllocator mem = MemoryAllocator() # Setting up for each thread some storage space. cdef parallel_f_t* parallel_structs = \ - mem.allocarray(num_threads, sizeof(parallel_f_t)) + mem.allocarray(num_threads, sizeof(parallel_f_t)) for i in range(num_threads): # Partial f-vectors. parallel_structs[i].f_vector = \ - mem.calloc(dim+2, sizeof(size_t)) + mem.calloc(dim+2, sizeof(size_t)) parallel_structs[i].current_job_id = \ - mem.calloc(parallelization_depth+1, sizeof(size_t)) + mem.calloc(parallelization_depth+1, sizeof(size_t)) # Keeping back of the original number of faces allows faster starting the next job. parallel_structs[i].original_n_faces = \ - mem.calloc(parallelization_depth+1, sizeof(size_t)) + mem.calloc(parallelization_depth+1, sizeof(size_t)) parallel_structs[i].original_n_faces[0] = \ - structures[0].new_faces[dim - 1].n_faces + structures[0].new_faces[dim - 1].n_faces parallel_structs[i].original_n_visited_all = \ - mem.calloc(parallelization_depth+1, sizeof(size_t)) + mem.calloc(parallelization_depth+1, sizeof(size_t)) parallel_structs[i].original_n_visited_all[0] = \ - structures[0].visited_all[dim - 1].n_faces + structures[0].visited_all[dim - 1].n_faces for i in prange(n_jobs, schedule='dynamic', chunksize=1, num_threads=num_threads, nogil=True): @@ -2155,9 +2153,9 @@ cdef inline int prepare_face_iterator_for_partial_job( # Recover all faces. structure.new_faces[d].n_faces = \ - parallel_struct.original_n_faces[current_depth -1] + parallel_struct.original_n_faces[current_depth -1] structure.visited_all[d].n_faces = \ - parallel_struct.original_n_visited_all[current_depth -1] + parallel_struct.original_n_visited_all[current_depth -1] structure.first_time[d] = True structure.yet_to_visit = 0 # just to be on the safe side @@ -2172,7 +2170,6 @@ cdef inline int prepare_face_iterator_for_partial_job( cdef size_t n_coatoms = structure.n_coatoms cdef size_t job_id_c cdef size_t i - cdef size_t diff cdef size_t new_faces_counter for current_depth in range(1, parallelization_depth + 1): diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd index 105cc81b9a4..708b176ef16 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd @@ -188,7 +188,6 @@ cdef inline size_t find_face(face_t face, face_list_t faces) noexcept: cdef face_t* faces_pt = faces.faces cdef int val - while (n_faces > 1): # In each iteration step, we will look for ``face`` in # ``faces_pt[start:start+n_faces]``. @@ -367,6 +366,6 @@ cdef inline bint face_list_check_alignment(face_list_t faces) noexcept: """ cdef size_t i for i in range(faces.n_faces): - if not face_check_alignment(faces.faces[i]): - return False + if not face_check_alignment(faces.faces[i]): + return False return True diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx index 3f33aec8ec6..34adfb092dd 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx @@ -9,7 +9,7 @@ Sorting of a list of faces. # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # https://www.gnu.org/licenses/ -#**************************************************************************** +# *************************************************************************** cdef void sort_faces_list(face_list_t faces) noexcept: r""" diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd index d50c8f85539..420afcbb7d9 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd @@ -1,6 +1,7 @@ cimport cython from .face_list_data_structure cimport face_list_t, face_t + @cython.final cdef class ListOfFaces: # ``data`` points to the raw data. diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx index 9b5f3dd4ada..ad708569ec2 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx @@ -294,7 +294,7 @@ cdef class ListOfFaces: # Calculating ``newfaces`` # such that ``newfaces`` points to all facets of ``faces[n_faces -1]``. - cdef size_t new_n_faces = get_next_level(self.data, new_faces.data, empty_forbidden) + get_next_level(self.data, new_faces.data, empty_forbidden) # Undo what ``get_next_level`` does. self.data.n_faces += 1 diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd index 438dc8de6f7..2d6f1bc996f 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd @@ -4,6 +4,7 @@ from .face_data_structure cimport face_t from .face_list_data_structure cimport face_list_t from .combinatorial_face cimport CombinatorialFace + @cython.final cdef class PolyhedronFaceLattice: cdef int dimension # dimension of Polyhedron diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx index 9f5a98c7ece..f347f5bb0f9 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx @@ -50,7 +50,7 @@ AUTHOR: - Jonathan Kliem (2019-04) """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2019 Jonathan Kliem # # This program is free software: you can redistribute it and/or modify @@ -58,11 +58,10 @@ AUTHOR: # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** -from .conversions \ - import facets_tuple_to_bit_rep_of_facets, \ - facets_tuple_to_bit_rep_of_Vrep +from .conversions import (facets_tuple_to_bit_rep_of_facets, + facets_tuple_to_bit_rep_of_Vrep) from .conversions cimport bit_rep_to_Vrep_list @@ -166,7 +165,6 @@ cdef class PolyhedronFaceLattice: self.atoms = face_iter.atoms self.coatoms = face_iter.coatoms - cdef size_t n_atoms = self.atoms.n_faces() self.atom_rep = check_allocarray(self.coatoms.n_atoms(), sizeof(size_t)) self.coatom_rep = check_allocarray(self.coatoms.n_faces(), sizeof(size_t)) @@ -361,7 +359,6 @@ cdef class PolyhedronFaceLattice: ....: face.ambient_V_indices() for face in it) True """ - cdef size_t length if self.dual: # if dual, the Vrepresentation corresponds to the coatom-representation dimension = self.dimension - 1 - dimension # if dual, the dimensions are reversed @@ -376,9 +373,9 @@ cdef class PolyhedronFaceLattice: This is a shortcut of :class:`sage.geometry.polyhedron.combinatorial_polyhedron.combinatorial_face.CombinatorialFace.set_coatom_rep` """ if unlikely(dimension < -1 or dimension > self.dimension): - raise ValueError("no face of dimension %s"%dimension) + raise ValueError("no face of dimension %s" % dimension) if unlikely(index >= self.f_vector[dimension + 1]): - raise IndexError("no %s-th face of dimension %s"%(index, dimension)) + raise IndexError("no %s-th face of dimension %s" % (index, dimension)) if unlikely(self.coatoms.n_faces() == 0): return 0 @@ -394,9 +391,9 @@ cdef class PolyhedronFaceLattice: This is a shortcut of :class:`sage.geometry.polyhedron.combinatorial_polyhedron.combinatorial_face.CombinatorialFace.set_atom_rep` """ if unlikely(dimension < -1 or dimension > self.dimension): - raise ValueError("no face of dimension %s"%dimension) + raise ValueError("no face of dimension %s" % dimension) if unlikely(index >= self.f_vector[dimension + 1]): - raise IndexError("no %s-th face of dimension %s"%(index, dimension)) + raise IndexError("no %s-th face of dimension %s" % (index, dimension)) cdef face_t face = self.faces[dimension+1].faces[index] return bit_rep_to_Vrep_list(face, self.atom_rep) @@ -412,13 +409,12 @@ cdef class PolyhedronFaceLattice: with empty and full polyhedron are implemented, which suffices for the face-lattice. """ - cdef size_t i if dimension_one == self.dimension: # The full polyhedron is incident to every face. if dimension_two < -1: - raise ValueError("no faces of dimension %s"%dimension_two) + raise ValueError("no faces of dimension %s" % dimension_two) if dimension_two > self.dimension: - raise ValueError("no faces of dimension %s"%dimension_two) + raise ValueError("no faces of dimension %s" % dimension_two) self.incidence_dim_one = dimension_one self.incidence_dim_two = dimension_two self.incidence_counter_one = 0 @@ -429,9 +425,9 @@ cdef class PolyhedronFaceLattice: if dimension_two == -1: # The empty polyhedron is incident to every face. if dimension_one < -1: - raise ValueError("no faces of dimension %s"%dimension_two) + raise ValueError("no faces of dimension %s" % dimension_two) if dimension_one > self.dimension: - raise ValueError("no faces of dimension %s"%dimension_two) + raise ValueError("no faces of dimension %s" % dimension_two) self.incidence_dim_one = dimension_one self.incidence_dim_two = dimension_two self.incidence_counter_one = 0 @@ -444,9 +440,9 @@ cdef class PolyhedronFaceLattice: # At the moment, this is not implemented. if dimension_one > self.dimension: - raise ValueError("no faces of dimension %s"%dimension_one) + raise ValueError("no faces of dimension %s" % dimension_one) if dimension_two < -1: - raise ValueError("no faces of dimension %s"%dimension_two) + raise ValueError("no faces of dimension %s" % dimension_two) self.incidence_dim_one = dimension_one self.incidence_dim_two = dimension_two From d1e90b9cf38582b6e79e640b3b568292c6f2bd19 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Thu, 2 Nov 2023 08:24:55 +0100 Subject: [PATCH 087/463] more doctests --- .../rings/polynomial/laurent_polynomial_ideal.py | 12 +++++++++--- .../rings/polynomial/laurent_polynomial_mpair.pyx | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 43f9bca511c..4cf7b8b3414 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -193,14 +193,20 @@ def __contains__(self, f): sage: I = P.ideal([x^2*y + 3*x*y^2]) sage: x + 3*y in I True + sage: P.__contains__(x + 3*y) + True sage: I.gen(0).__reduce__() (Multivariate Laurent Polynomial Ring in x, y over Rational Field, (x^2*y + 3*x*y^2, (0, 0))) - sage: P. = LaurentPolynomialRing(QQ, 1) + sage: P. = LaurentPolynomialRing(QQ) sage: I = P.ideal([x^2 + 3*x]) + sage: 1 + 3*x^-1 in I + True + sage: P.__contains__(1 + 3*x^-1) + True sage: I.gen(0).__reduce__() # Check the differences of __reduce__ for distinct Laurent polynomial rings - (Multivariate Laurent Polynomial Ring in x over Rational Field, - (x^2 + 3*x, (0,))) + (, + (Univariate Laurent Polynomial Ring in x over Rational Field, x + 3, 1)) """ if not f or f in self.gens(): return True diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index 3b2ebf177ea..9cf123b5a52 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1858,7 +1858,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): @coerce_binop def divides(self, other): """ - Check if ``self`` divides ``other`` + Check if ``self`` divides ``other``. EXAMPLES:: From 60d683e3dc2ff03376fff875652a724958ed6131 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Mon, 13 Mar 2023 15:24:34 +0800 Subject: [PATCH 088/463] add class groups of binary quadratic forms --- .../en/reference/quadratic_forms/index.rst | 1 + src/sage/quadratic_forms/all.py | 2 + src/sage/quadratic_forms/binary_qf.py | 112 ++++ src/sage/quadratic_forms/bqf_class_group.py | 593 ++++++++++++++++++ 4 files changed, 708 insertions(+) create mode 100644 src/sage/quadratic_forms/bqf_class_group.py diff --git a/src/doc/en/reference/quadratic_forms/index.rst b/src/doc/en/reference/quadratic_forms/index.rst index 7169e7ac503..e553ecd1b82 100644 --- a/src/doc/en/reference/quadratic_forms/index.rst +++ b/src/doc/en/reference/quadratic_forms/index.rst @@ -6,6 +6,7 @@ Quadratic Forms sage/quadratic_forms/quadratic_form sage/quadratic_forms/binary_qf + sage/quadratic_forms/bqf_class_group sage/quadratic_forms/constructions sage/quadratic_forms/random_quadraticform sage/quadratic_forms/special_values diff --git a/src/sage/quadratic_forms/all.py b/src/sage/quadratic_forms/all.py index 3445705978a..81d395f375c 100644 --- a/src/sage/quadratic_forms/all.py +++ b/src/sage/quadratic_forms/all.py @@ -1,5 +1,7 @@ from .binary_qf import BinaryQF, BinaryQF_reduced_representatives +from .bqf_class_group import BQFClassGroup + from .ternary_qf import TernaryQF, find_all_ternary_qf_by_level_disc, find_a_ternary_qf_by_level_disc from .quadratic_form import QuadraticForm, DiagonalQuadraticForm, quadratic_form_from_invariants diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index 6516888e3ac..14a1f0049db 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -179,6 +179,101 @@ def _pari_init_(self): """ return 'Qfb(%s,%s,%s)' % (self._a, self._b, self._c) + @staticmethod + def principal(D): + r""" + Return the principal binary quadratic form of the given discriminant. + + EXAMPLES:: + + sage: BinaryQF.principal(8) + x^2 - 2*y^2 + sage: BinaryQF.principal(5) + x^2 + x*y - y^2 + sage: BinaryQF.principal(4) + x^2 - y^2 + sage: BinaryQF.principal(1) + x^2 + x*y + sage: BinaryQF.principal(-3) + x^2 + x*y + y^2 + sage: BinaryQF.principal(-4) + x^2 + y^2 + sage: BinaryQF.principal(-7) + x^2 + x*y + 2*y^2 + sage: BinaryQF.principal(-8) + x^2 + 2*y^2 + + TESTS: + + Some randomized testing:: + + sage: D = 1 + sage: while D.is_square(): + ....: D = choice((-4,+4)) * randrange(9999) + randrange(2) + sage: Q = BinaryQF.principal(D) + sage: Q.discriminant() == D # correct discriminant + True + sage: (Q*Q).is_equivalent(Q) # idempotent (hence identity) + True + """ + D = ZZ(D) + D4 = D % 4 + if D4 not in (0,1): + raise ValueError('discriminant must be congruent to 0 or 1 modulo 4') + return BinaryQF([1, D4, (D4-D)//4]) + + @staticmethod + def random(D): + r""" + Return a somewhat random primitive binary quadratic form of the + given discriminant. + + (In the case `D < 0`, only positive definite forms are returned.) + + .. NOTE:: + + No guarantees are being made about the distribution of forms + sampled by this function. + + EXAMPLES:: + + sage: BinaryQF.random(5) # random + 448219*x^2 - 597179*x*y + 198911*y^2 + sage: BinaryQF.random(-7) # random + 10007*x^2 + 10107*x*y + 2552*y^2 + + TESTS:: + + sage: D = choice((-4,+4)) * randrange(9999) + randrange(2) or 1 + sage: Q = BinaryQF.random(D) + sage: Q.discriminant() == D + True + sage: Q.is_primitive() + True + sage: Q.is_indefinite() or Q.is_positive_definite() + True + """ + D = ZZ(D) + D4 = D % 4 + if D4 not in (0,1): + raise ValueError('discriminant must be congruent to 0 or 1 modulo 4') + + from sage.misc.prandom import randrange + from sage.misc.misc_c import prod + from sage.matrix.special import random_matrix + B = (D.abs() or 1) * 99 # kind of arbitrary + while True: + b = randrange(D4, B, 2) + ac = (b**2 - D) // 4 + if ac: + break + a = prod(l**randrange(e+1) for l,e in ac.factor()) + a = a.prime_to_m_part(gcd([a, b, ac//a])) + c = ac // a + M = random_matrix(ZZ, 2, 2, 'unimodular') + M.rescale_row(0, (-1)**randrange(2)) + return BinaryQF([a, b, c]) * M + def __mul__(self, right): """ Gauss composition or right action by a 2x2 integer matrix. @@ -1706,6 +1801,23 @@ def solve_integer(self, n, *, algorithm="general"): sol = self.__pari__().qfbsolve(n, flag) return tuple(map(ZZ, sol)) if sol else None + def form_class(self): + r""" + Return the class of this form modulo equivalence. + + EXAMPLES:: + + sage: F = BinaryQF([3, -16, 161]) + sage: cl = F.form_class(); cl + Class of 3*x^2 + 2*x*y + 140*y^2 + sage: cl.parent() + Form Class Group of Discriminant -1676 + sage: cl.parent() is BQFClassGroup(-4*419) + True + """ + from sage.quadratic_forms.bqf_class_group import BQFClassGroup + return BQFClassGroup(self.discriminant())(self) + def BinaryQF_reduced_representatives(D, primitive_only=False, proper=True): r""" diff --git a/src/sage/quadratic_forms/bqf_class_group.py b/src/sage/quadratic_forms/bqf_class_group.py new file mode 100644 index 00000000000..58cd10468bf --- /dev/null +++ b/src/sage/quadratic_forms/bqf_class_group.py @@ -0,0 +1,593 @@ +r""" +Class groups of binary quadratic forms + +EXAMPLES: + +Constructing the class of a given binary quadratic form is straightforward:: + + sage: F1 = BinaryQF([22, 91, 99]) + sage: cl1 = F1.form_class(); cl1 + Class of 5*x^2 - 3*x*y + 22*y^2 + +Every class is represented by a reduced form in it:: + + sage: cl1.form() + 5*x^2 - 3*x*y + 22*y^2 + sage: cl1.form() == F1.reduced_form() + True + +Addition of form classes and derived operations are defined by composition +of binary quadratic forms:: + + sage: F2 = BinaryQF([4, 1, 27]) + sage: cl2 = F2.form_class(); cl2 + Class of 4*x^2 + x*y + 27*y^2 + sage: cl1 + cl2 + Class of 9*x^2 + x*y + 12*y^2 + sage: cl1 + cl2 == (F1 * F2).form_class() + True + sage: -cl1 + Class of 5*x^2 + 3*x*y + 22*y^2 + sage: cl1 - cl1 + Class of x^2 + x*y + 108*y^2 + +The form class group can be constructed as an explicit parent object:: + + sage: F1.discriminant() + -431 + sage: Cl = BQFClassGroup(-431); Cl + Form Class Group of Discriminant -431 + sage: cl1.parent() is Cl + True + sage: Cl(F1) == cl1 + True + +Structural properties of the form class group, such as the class number, +the group invariants, and element orders, can be computed:: + + sage: Cl.order() + 21 + sage: cl1 * Cl.order() == Cl.zero() + True + sage: cl2 * Cl.order() == Cl.zero() + True + sage: cl2.order() + 7 + sage: cl2 * cl2.order() == Cl.zero() + True + sage: Cl.abelian_group() + Additive abelian group isomorphic to Z/21 embedded in Form Class Group of Discriminant -431 + sage: Cl.gens() # random + [Class of 5*x^2 + 3*x*y + 22*y^2] + sage: Cl.gens()[0].order() + 21 + +AUTHORS: + +- Lorenz Panny (2023) +""" + +# **************************************************************************** +# Copyright (C) 2023 Lorenz Panny +# +# 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 sage.misc.cachefunc import cached_method + +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation +from sage.structure.element import AdditiveGroupElement + +from sage.misc.prandom import randrange +from sage.rings.integer_ring import ZZ +from sage.groups.generic import order_from_multiple, multiple +from sage.groups.additive_abelian.additive_abelian_wrapper import AdditiveAbelianGroupWrapper +from sage.quadratic_forms.binary_qf import BinaryQF + +from sage.libs.pari import pari + + +class BQFClassGroup(Parent, UniqueRepresentation): + r""" + This type represents the class group for a given discriminant `D`. + + - For `D < 0`, the group is the class group of *positive definite* + binary quadratic forms. The "full" form class group is the direct + sum of two isomorphic copies of this group (one for positive + definite forms and one for negative definite forms). + + - For `D > 0`, this functionality is currently not implemented. + + EXAMPLES:: + + sage: BQFClassGroup(-4) + Form Class Group of Discriminant -4 + sage: BQFClassGroup(-6) + Traceback (most recent call last): + ... + ValueError: not a discriminant + + The discriminant need not be fundamental:: + + sage: BQFClassGroup(-22^2) + Form Class Group of Discriminant -484 + """ + + def __init__(self, D, *, check=True): + r""" + Construct the class group for a given discriminant `D`. + + TESTS: + + Check that positive discriminants are rejected until code is + written for them:: + + sage: BQFClassGroup(101) + Traceback (most recent call last): + ... + NotImplementedError: positive discriminants are not yet supported + """ + self._disc = ZZ(D) + if check: + if not self._disc or self._disc % 4 not in (0,1): + raise ValueError('not a discriminant') + if self._disc > 0: + raise NotImplementedError('positive discriminants are not yet supported') + super().__init__() + + def _element_constructor_(self, F, *, check=True): + r""" + Construct an element of this form class group as a :class:`BQFClassGroup_element`. + + EXAMPLES:: + + sage: Cl = BQFClassGroup(-999) + sage: Cl(0) # indirect doctest + Class of x^2 + x*y + 250*y^2 + sage: Cl(BinaryQF([16, 5, 16])) # indirect doctest + Class of 16*x^2 + 5*x*y + 16*y^2 + """ + if isinstance(F, BQFClassGroup_element): + if check and F.parent() is not self: # class group is unique parent + raise ValueError('quadratic form has incorrect discriminant') + return F + if F == 0: + return self.zero() + if check and not isinstance(F, BinaryQF): + raise TypeError('not a binary quadratic form') + return BQFClassGroup_element(F, parent=self, check=check) + + def zero(self): + r""" + Return the neutral element of this group, i.e., the class of the + principal binary quadratic form of the respective discriminant. + + EXAMPLES:: + + sage: Cl = BQFClassGroup(-999) + sage: cl = Cl.zero(); cl + Class of x^2 + x*y + 250*y^2 + sage: cl + cl == cl + True + """ + return self(BinaryQF.principal(self._disc)) + + def random_element(self): + r""" + Return a somewhat random element of this form class group. + + ALGORITHM: :meth:`BinaryQF.random` + + .. NOTE:: + + No guarantees are being made about the distribution of classes + sampled by this function. Heuristically, however, it should be + fairly close to uniform. + + EXAMPLES:: + + sage: Cl = BQFClassGroup(-999); Cl + Form Class Group of Discriminant -999 + sage: cl = Cl.random_element(); cl # random + Class of 10*x^2 + x*y + 25*y^2 + sage: cl.form().discriminant() + -999 + """ + return self(BinaryQF.random(self._disc)) + + def __hash__(self): + r""" + Return a hash value for this form class group. + + EXAMPLES:: + + sage: hash(BQFClassGroup(-999)) # random + -4246560339810542104 + """ + return hash(('BQFClassGroup', self._disc)) + + def _repr_(self): + r""" + Return a string describing this form class group. + + EXAMPLES:: + + sage: BQFClassGroup(-999) # indirect doctest + Form Class Group of Discriminant -999 + """ + return f'Form Class Group of Discriminant {self._disc}' + + def discriminant(self): + r""" + Return the discriminant of the forms in this form class group. + + EXAMPLES:: + + sage: BQFClassGroup(-999).discriminant() + -999 + """ + return self._disc + + @cached_method + def order(self): + r""" + Return the order of this form class group (the *class number*). + + ALGORITHM: :pari:`qfbclassno` + + EXAMPLES:: + + sage: BQFClassGroup(-4).order() + 1 + sage: BQFClassGroup(-11).order() + 1 + sage: BQFClassGroup(-67).order() + 1 + sage: BQFClassGroup(-163).order() + 1 + sage: BQFClassGroup(-999).order() + 24 + sage: BQFClassGroup(-9999).order() + 88 + sage: BQFClassGroup(-99999).order() + 224 + """ + return ZZ(pari.qfbclassno(self._disc)) + + cardinality = order + + @cached_method + def abelian_group(self): + r""" + Return the structure of this form class group as an + :class:`AdditiveAbelianGroupWrapper` object. + + ALGORITHM: :pari:`quadclassunit` + + EXAMPLES:: + + sage: Cl = BQFClassGroup(-4*777) + sage: Cl.order() + 16 + sage: G = Cl.abelian_group(); G + Additive abelian group isomorphic to Z/4 + Z/2 + Z/2 embedded in Form Class Group of Discriminant -3108 + sage: G.gens() # random + (Class of 11*x^2 + 4*x*y + 71*y^2, + Class of 6*x^2 + 6*x*y + 131*y^2, + Class of 2*x^2 + 2*x*y + 389*y^2) + sage: [g.order() for g in G.gens()] + [4, 2, 2] + sage: G.discrete_log(Cl.random_element()) # random + (3, 0, 1) + """ + h, ords, gens, reg = pari.quadclassunit(self._disc) + ords = [ZZ(o) for o in ords] + gens = [BinaryQF(g) for g in gens] + return AdditiveAbelianGroupWrapper(self, gens, ords) + + def gens(self): + r""" + Return a generating set of this form class group. + + EXAMPLES:: + + sage: Cl = BQFClassGroup(-4*419) + sage: Cl.gens() + [Class of 3*x^2 + 2*x*y + 140*y^2] + + :: + + sage: Cl = BQFClassGroup(-4*777) + sage: Cl.gens() # random + [Class of 11*x^2 + 4*x*y + 71*y^2, + Class of 6*x^2 + 6*x*y + 131*y^2, + Class of 2*x^2 + 2*x*y + 389*y^2] + """ + return [g.element() for g in self.abelian_group().gens()] + + +class BQFClassGroup_element(AdditiveGroupElement): + r""" + This type represents elements of class groups of binary quadratic forms. + + Users should not need to construct objects of this type directly; it can + be accessed via either the :class:`BQFClassGroup` parent object or the + :meth:`~BinaryQF.form_class` method associated to binary quadratic forms. + + Currently only classes of positive definite forms are supported. + + EXAMPLES:: + + sage: F = BinaryQF([22, 91, 99]) + sage: F.form_class() # implicit doctest + Class of 5*x^2 - 3*x*y + 22*y^2 + + :: + + sage: Cl = BQFClassGroup(-4*419) + sage: Cl.zero() + Class of x^2 + 419*y^2 + sage: Cl.gens()[0] # implicit doctest + Class of 3*x^2 + 2*x*y + 140*y^2 + """ + + def __init__(self, F, parent, *, check=True, reduce=True): + r""" + Constructor for classes of binary quadratic forms. + + EXAMPLES:: + + sage: Cl = BQFClassGroup(-431) + sage: F = BinaryQF([22, 91, 99]) + sage: from sage.quadratic_forms.bqf_class_group import BQFClassGroup_element + sage: BQFClassGroup_element(F, parent=Cl) + Class of 5*x^2 - 3*x*y + 22*y^2 + """ + if check: + if not isinstance(F, BinaryQF): + raise TypeError('not a binary quadratic form') + if F.discriminant() != parent.discriminant(): + raise ValueError('given quadratic form has wrong discriminant') + if not F.is_primitive(): + raise ValueError('given quadratic form is not primitive') + if not F.is_positive_definite(): + raise NotImplemented('only positive definite forms are currently supported') + if reduce: + F = F.reduced_form() + self._form = F + super().__init__(parent=parent) + + def form(self): + r""" + Return a reduced quadratic form in this class. + + (For `D < 0`, each class contains a *unique* reduced form.) + + EXAMPLES:: + + sage: F = BinaryQF([3221, 2114, 350]) + sage: cl = F.form_class() + sage: cl.form() + 29*x^2 + 14*x*y + 350*y^2 + sage: cl.form() == F.reduced_form() + True + """ + return self._form + + def _neg_(self): + r""" + Return the inverse of this form class. + + The inverse class of a form `[a,b,c]` is represented by `[a,-b,c]`. + + EXAMPLES:: + + sage: F = BinaryQF([11,21,31]) + sage: cl = F.form_class(); cl + Class of 11*x^2 - x*y + 21*y^2 + sage: -cl # indirect doctest + Class of 11*x^2 + x*y + 21*y^2 + sage: cl + (-cl) == cl.parent().zero() # indirect doctest + True + """ + a,b,c = self._form + F = BinaryQF([a,-b,c]) + return BQFClassGroup_element(F, parent=self.parent()) + + def _add_(self, other): + r""" + Return the composition of two form classes. + + EXAMPLES:: + + sage: cl1 = BinaryQF([11,21,31]).form_class(); cl1 + Class of 11*x^2 - x*y + 21*y^2 + sage: cl2 = BinaryQF([7,55,141]).form_class(); cl2 + Class of 7*x^2 - x*y + 33*y^2 + sage: cl1 + cl2 # indirect doctest + Class of 3*x^2 + x*y + 77*y^2 + """ + F = self._form * other._form + return BQFClassGroup_element(F, parent=self.parent()) + + def _sub_(self, other): + r""" + Return the composition of a form class with the inverse of another. + + EXAMPLES:: + + sage: cl1 = BinaryQF([11,21,31]).form_class(); cl1 + Class of 11*x^2 - x*y + 21*y^2 + sage: cl2 = BinaryQF([7,55,141]).form_class(); cl2 + Class of 7*x^2 - x*y + 33*y^2 + sage: cl1 - cl2 # indirect doctest + Class of 9*x^2 - 7*x*y + 27*y^2 + sage: cl1 - cl2 == cl1 + (-cl2) # indirect doctest + True + """ + return self + (-other) + + def __mul__(self, other): + r""" + Return an integer multiple of this form class with respect to + repeated composition. + + ALGORITHM: :func:`multiple` + + EXAMPLES:: + + sage: F = BinaryQF([11,21,31]) + sage: cl = F.form_class(); cl + Class of 11*x^2 - x*y + 21*y^2 + sage: cl*0 == cl.parent().zero() # indirect doctest + True + sage: cl*1 == cl # indirect doctest + True + sage: cl*(-1) == -cl # indirect doctest + True + sage: cl*2 == cl + cl # indirect doctest + True + sage: cl*5 == cl + cl + cl + cl + cl # indirect doctest + True + sage: 5*cl == cl*5 # indirect doctest + True + sage: cl*(-5) == -(5*cl) # indirect doctest + True + """ + return multiple(self, other, operation='+') + + __rmul__ = __mul__ + + def __eq__(self, other): + r""" + Test two form classes for equality. + + EXAMPLES:: + + sage: F = BinaryQF([11,21,31]) + sage: cl = F.form_class(); cl + Class of 11*x^2 - x*y + 21*y^2 + sage: cl == cl # indirect doctest + True + sage: -cl == cl # indirect doctest + False + """ + # When generalizing to positive discriminants in the future, keep + # in mind that for indefinite forms there can be multiple reduced + # forms per class. This also affects the other comparison methods + # as well as hashing. + return self._form == other._form + + def __ne__(self, other): + r""" + Test two form classes for inequality. + + EXAMPLES:: + + sage: F = BinaryQF([11,21,31]) + sage: cl = F.form_class(); cl + Class of 11*x^2 - x*y + 21*y^2 + sage: cl != cl # indirect doctest + False + sage: -cl != cl # indirect doctest + True + """ + return self._form != other._form + + def __lt__(self, other): + r""" + Compare two form classes according to the lexicographic ordering + on their coefficient lists. + + EXAMPLES:: + + sage: cl1 = BinaryQF([7,55,141]).form_class(); cl1 + Class of 7*x^2 - x*y + 33*y^2 + sage: cl2 = BinaryQF([11,21,31]).form_class(); cl2 + Class of 11*x^2 - x*y + 21*y^2 + sage: cl1 < cl2 # indirect doctest + True + sage: cl1 > cl2 # indirect doctest + False + """ + return self._form < other._form + + def __bool__(self): + r""" + Return ``True`` if this form class is *not* the principal class + and ``False`` otherwise. + + EXAMPLES:: + + sage: cl = BinaryQF([11,21,31]).form_class() + sage: bool(cl) + True + sage: bool(0*cl) + False + """ + return self != self.parent().zero() + + def is_zero(self): + r""" + Return ``True`` if this form class is the principal class and + ``False`` otherwise. + + EXAMPLES:: + + sage: cl = BinaryQF([11,21,31]).form_class() + sage: cl.is_zero() + False + sage: (0*cl).is_zero() + True + """ + return not self + + def __repr__(self): + r""" + Return a string representation of this form class. + + EXAMPLES:: + + sage: F = BinaryQF([11,21,31]) + sage: F.form_class() # indirect doctest + Class of 11*x^2 - x*y + 21*y^2 + """ + return f'Class of {self._form}' + + def __hash__(self): + r""" + Return a hash value for this form class. + + EXAMPLES:: + + sage: cl = BinaryQF([11,21,31]).form_class() + sage: hash(cl) # random + -7760578299759721732 + """ + return hash(('BQFClassGroup_element', self._form)) + + @cached_method + def order(self): + r""" + Return the order of this form class in its class group. + + ALGORITHM: :meth:`BQFClassGroup.order` and :func:`order_from_multiple` + + EXAMPLES:: + + sage: cl = BinaryQF([11,21,31]).form_class() + sage: cl.order() + 10 + sage: (cl+cl).order() + 5 + sage: (cl+cl+cl).order() + 10 + sage: (5*cl).order() + 2 + """ + return order_from_multiple(self, self.parent().cardinality()) From 7c0a6c7e976fa5436c246842b20a9b5c5bbc5698 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Mon, 4 Sep 2023 19:35:26 +0200 Subject: [PATCH 089/463] remove BinaryQF.random() since its distribution was far from uniform on classes --- src/sage/quadratic_forms/binary_qf.py | 52 --------------------- src/sage/quadratic_forms/bqf_class_group.py | 25 ++++++++-- 2 files changed, 20 insertions(+), 57 deletions(-) diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index 14a1f0049db..ade5cf1561e 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -222,58 +222,6 @@ def principal(D): raise ValueError('discriminant must be congruent to 0 or 1 modulo 4') return BinaryQF([1, D4, (D4-D)//4]) - @staticmethod - def random(D): - r""" - Return a somewhat random primitive binary quadratic form of the - given discriminant. - - (In the case `D < 0`, only positive definite forms are returned.) - - .. NOTE:: - - No guarantees are being made about the distribution of forms - sampled by this function. - - EXAMPLES:: - - sage: BinaryQF.random(5) # random - 448219*x^2 - 597179*x*y + 198911*y^2 - sage: BinaryQF.random(-7) # random - 10007*x^2 + 10107*x*y + 2552*y^2 - - TESTS:: - - sage: D = choice((-4,+4)) * randrange(9999) + randrange(2) or 1 - sage: Q = BinaryQF.random(D) - sage: Q.discriminant() == D - True - sage: Q.is_primitive() - True - sage: Q.is_indefinite() or Q.is_positive_definite() - True - """ - D = ZZ(D) - D4 = D % 4 - if D4 not in (0,1): - raise ValueError('discriminant must be congruent to 0 or 1 modulo 4') - - from sage.misc.prandom import randrange - from sage.misc.misc_c import prod - from sage.matrix.special import random_matrix - B = (D.abs() or 1) * 99 # kind of arbitrary - while True: - b = randrange(D4, B, 2) - ac = (b**2 - D) // 4 - if ac: - break - a = prod(l**randrange(e+1) for l,e in ac.factor()) - a = a.prime_to_m_part(gcd([a, b, ac//a])) - c = ac // a - M = random_matrix(ZZ, 2, 2, 'unimodular') - M.rescale_row(0, (-1)**randrange(2)) - return BinaryQF([a, b, c]) * M - def __mul__(self, right): """ Gauss composition or right action by a 2x2 integer matrix. diff --git a/src/sage/quadratic_forms/bqf_class_group.py b/src/sage/quadratic_forms/bqf_class_group.py index 58cd10468bf..185a869b8b2 100644 --- a/src/sage/quadratic_forms/bqf_class_group.py +++ b/src/sage/quadratic_forms/bqf_class_group.py @@ -85,6 +85,8 @@ from sage.misc.prandom import randrange from sage.rings.integer_ring import ZZ +from sage.rings.finite_rings.integer_mod import Mod +from sage.arith.misc import random_prime from sage.groups.generic import order_from_multiple, multiple from sage.groups.additive_abelian.additive_abelian_wrapper import AdditiveAbelianGroupWrapper from sage.quadratic_forms.binary_qf import BinaryQF @@ -181,13 +183,17 @@ def random_element(self): r""" Return a somewhat random element of this form class group. - ALGORITHM: :meth:`BinaryQF.random` + ALGORITHM: + + Sample random odd primes `a` until `b^2 = D \pmod{4a}` has a + solution `b \in \ZZ` and set `c = (b^2-D)/(4a)`. Flip a coin + to choose the sign of `b`. Then return the class of `[a,b,c]`. .. NOTE:: - No guarantees are being made about the distribution of classes - sampled by this function. Heuristically, however, it should be - fairly close to uniform. + No strict guarantees are being made about the distribution of + classes sampled by this function. Heuristically, however, it + should be fairly close to uniform. EXAMPLES:: @@ -198,7 +204,16 @@ def random_element(self): sage: cl.form().discriminant() -999 """ - return self(BinaryQF.random(self._disc)) + B = self._disc.abs() * 100 + 9999 + while True: + a = random_prime(B, proof=False, lbound=3) + if self._disc.kronecker(a) == 1: + break + b = ZZ(Mod(self._disc, 4*a).sqrt()) + c = (b**2 - self._disc) // (4*a) + if randrange(2): + b = -b + return self(BinaryQF([a,b,c])) def __hash__(self): r""" From d47aebf2854e65a70a6c0d6bc1c4559bb9122644 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 2 Nov 2023 14:25:59 +0100 Subject: [PATCH 090/463] reviewer comments --- src/sage/schemes/elliptic_curves/mod_poly.py | 35 +++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/mod_poly.py b/src/sage/schemes/elliptic_curves/mod_poly.py index c034bed50aa..50fd1108e91 100644 --- a/src/sage/schemes/elliptic_curves/mod_poly.py +++ b/src/sage/schemes/elliptic_curves/mod_poly.py @@ -21,6 +21,7 @@ from sage.databases.db_modular_polynomials import ClassicalModularPolynomialDatabase _db = ClassicalModularPolynomialDatabase() +_cache_bound = 100 _cache = dict() def classical_modular_polynomial(l, j=None): @@ -32,16 +33,17 @@ def classical_modular_polynomial(l, j=None): Generic polynomials are cached up to a certain size of `\ell`, which significantly accelerates subsequent invocations with the - same `\ell`. The default bound is `\ell \leq 150`, which can be - adjusted by setting ``classical_modular_polynomial.cache_bound`` - to a different value. Beware that modular polynomials are very - large and the amount of memory consumed by the cache will grow - rapidly when the bound is set to a large value. + same `\ell`. The default bound is `\ell \leq 100`, which can be + adjusted using ``classical_modular_polynomial.set_cache_bound()`` + with a different value. Beware that modular polynomials are very + big objects and the amount of memory consumed by the cache will + grow rapidly when the bound is set to a large value. INPUT: - ``l`` -- positive integer. - ``j`` -- either ``None`` or a ring element: + * if ``None`` is given, the original modular polynomial is returned as an element of `\ZZ[X,Y]` * if a ring element `j \in R` is given, the evaluation @@ -62,6 +64,20 @@ def classical_modular_polynomial(l, j=None): sage: classical_modular_polynomial(3, j) Y^4 + 230*Y^3 + 84*Y^2 + 118*Y + 329 + Increasing the cache size can be useful for repeated invocations:: + + sage: %timeit classical_modular_polynomial(101) # random + 6.11 s ± 1.21 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) + sage: %timeit classical_modular_polynomial(101, GF(65537).random_element()) # random + 5.43 s ± 2.71 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) + + sage: classical_modular_polynomial.set_cache_bound(150) + sage: %timeit classical_modular_polynomial(101) # random + The slowest run took 10.35 times longer than the fastest. This could mean that an intermediate result is being cached. + 1.84 µs ± 1.84 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) + sage: %timeit classical_modular_polynomial(101, GF(65537).random_element()) # random + 59.8 ms ± 29.4 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) + TESTS:: sage: q = random_prime(50)^randrange(1,4) @@ -92,7 +108,7 @@ def classical_modular_polynomial(l, j=None): d = {(i, j): c for i,f in enumerate(pari_Phi) for j, c in enumerate(f)} Phi = ZZ['X,Y'](d) - if l <= classical_modular_polynomial.cache_bound: + if l <= _cache_bound: _cache[l] = Phi return Phi @@ -109,7 +125,7 @@ def classical_modular_polynomial(l, j=None): except ValueError: pass else: - if l <= classical_modular_polynomial.cache_bound: + if l <= _cache_bound: _cache[l] = ZZ['X,Y'](Phi) return Phi(j, Y) @@ -127,4 +143,7 @@ def classical_modular_polynomial(l, j=None): # and simply evaluating it. return classical_modular_polynomial(l)(j, Y) -classical_modular_polynomial.cache_bound = 150 +def _set_cache_bound(bnd): + global _cache_bound + _cache_bound = bnd +classical_modular_polynomial.set_cache_bound = _set_cache_bound From 4ef28839c726a495332aca4d254a6c5925a58ee6 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Thu, 2 Nov 2023 17:16:46 +0100 Subject: [PATCH 091/463] doctests for change_ring in ideal_py and __contains_ in laurent_polynomial_ideal --- src/sage/rings/polynomial/ideal.py | 10 +++---- .../polynomial/laurent_polynomial_ideal.py | 26 ++++++++----------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/sage/rings/polynomial/ideal.py b/src/sage/rings/polynomial/ideal.py index e61b6de3f39..9719c81ba41 100644 --- a/src/sage/rings/polynomial/ideal.py +++ b/src/sage/rings/polynomial/ideal.py @@ -92,11 +92,9 @@ def change_ring(self, R): EXAMPLES:: - sage: P. = LaurentPolynomialRing(QQ, 2) - sage: I = P.ideal([x + y]) - sage: Q. = LaurentPolynomialRing(QQ, 3) - sage: I.change_ring(Q) - Ideal (x + y) of Multivariate Laurent Polynomial Ring in x, y, z - over Rational Field + sage: R. = QQ[] + sage: I = R.ideal([q^2+q-1]) + sage: I.change_ring(RR['q']) + Principal ideal (q^2 + q - 1.00000000000000) of Univariate Polynomial Ring in q over Real Field with 53 bits of precision """ return R.ideal(self.gens()) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 4cf7b8b3414..924ce7ed7d3 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -23,6 +23,7 @@ # **************************************************************************** from sage.rings.ideal import Ideal_generic +from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing_univariate from sage.structure.richcmp import op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE from sage.arith.misc import GCD @@ -193,28 +194,23 @@ def __contains__(self, f): sage: I = P.ideal([x^2*y + 3*x*y^2]) sage: x + 3*y in I True - sage: P.__contains__(x + 3*y) - True - sage: I.gen(0).__reduce__() - (Multivariate Laurent Polynomial Ring in x, y over Rational Field, - (x^2*y + 3*x*y^2, (0, 0))) + + We test that these changes allow to use this method in the inivariate case. + + TESTS:: + sage: P. = LaurentPolynomialRing(QQ) sage: I = P.ideal([x^2 + 3*x]) sage: 1 + 3*x^-1 in I True - sage: P.__contains__(1 + 3*x^-1) - True - sage: I.gen(0).__reduce__() # Check the differences of __reduce__ for distinct Laurent polynomial rings - (, - (Univariate Laurent Polynomial Ring in x over Rational Field, x + 3, 1)) """ if not f or f in self.gens(): return True f = self.ring()(f) - if self.ring().ngens() > 1: - g = f.__reduce__()[1][0] - else: + if isinstance(self.ring(), LaurentPolynomialRing_univariate): g = f.__reduce__()[1][1] + else: + g = f.__reduce__()[1][0] return (g in self.polynomial_ideal()) def gens_reduced(self): @@ -356,7 +352,7 @@ def toric_coordinate_change(self, M, forward_hint=True): """ if forward_hint: R = self.ring() - apply_to_hint = lambda x, M=M, R=R: R(x).toric_coordinate_change(M).__reduce__()[1][0] + apply_to_hint = lambda x, M=M, R=R: R(x).toric_coordinate_change(M).monomial_reduction()[0] else: apply_to_hint = None return self.apply_map(lambda x, M=M: x.toric_coordinate_change(M), @@ -443,7 +439,7 @@ def polynomial_ideal(self, saturate=True): """ P = self.ring() Q = self._poly_ring - if len(P.gens()) == 1: + if isinstance(self.ring(), LaurentPolynomialRing_univariate): a = [Q(p.polynomial_construction()[0]) for p in self.gens()] if P.base_ring().is_field(): a = GCD(a) From 7030a05215a9178259241cae21ece3288e1acbc3 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Thu, 2 Nov 2023 19:05:01 +0100 Subject: [PATCH 092/463] change in monomial_reduction --- src/sage/rings/polynomial/laurent_polynomial_mpair.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index 9cf123b5a52..c0fd659591f 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1534,17 +1534,17 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: R. = LaurentPolynomialRing(QQ) sage: f = y / x + x^2 / y + 3 * x^4 * y^-2 sage: f.monomial_reduction() - (3*x^5 + x^3*y + y^3, 1/(x*y^2)) + (3*x^5 + x^3*y + y^3, x^-1*y^-2) sage: f = y * x + x^2 / y + 3 * x^4 * y^-2 sage: f.monomial_reduction() - (3*x^3 + y^3 + x*y, x/y^2) + (3*x^3 + y^3 + x*y, x*y^-2) sage: x.monomial_reduction() (1, x) sage: (y^-1).monomial_reduction() - (1, 1/y) + (1, y^-1) """ self._normalize() - ring = self._parent._R + ring = self._parent g = ring.gens() mon = ring.prod(g[i] ** j for i, j in enumerate(self._mon)) return (self._poly, mon) From 650e0606748e57db9773a0f3e8201082771aae5d Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Fri, 3 Nov 2023 11:52:18 +0100 Subject: [PATCH 093/463] some cases missing in characteristic varieties --- src/sage/groups/finitely_presented.py | 35 +++++++++++++++++++++------ 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index a961df9a4c5..a351e544ce7 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -1703,12 +1703,18 @@ def abelian_alexander_matrix(self, ring=QQ, simplified=True): sage: g = FreeGroup(1) / [] sage: g.abelian_alexander_matrix() ([], []) + sage: g.abelian_alexander_matrix()[0].base_ring() + Univariate Laurent Polynomial Ring in f1 over Rational Field sage: g = FreeGroup(0) / [] - sage: g.abelian_alexander_matrix() - ([], []) + sage: A, ideal = g.abelian_alexander_matrix(); A + [] + sage: A.base_ring() + Rational Field """ ab, R, ideal, images = self.abelianization_to_algebra(ring=ring) A = self.alexander_matrix(im_gens=images) + if A.base_ring() != R: + A = A.change_ring(R) if simplified: n, m = A.dimensions() if n == 0 or m == 0: @@ -1794,8 +1800,7 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): sage: G.characteristic_varieties() {0: Ideal (0) of Univariate Laurent Polynomial Ring in f2 over Rational Field, 1: Ideal (-1 + 2*f2 - 2*f2^2 + f2^3) of Univariate Laurent Polynomial Ring in f2 over Rational Field, - 2: Ideal (1) of Univariate Laurent Polynomial Ring in f2 over Rational Field, - 3: Ideal (1) of Univariate Laurent Polynomial Ring in f2 over Rational Field} + 2: Ideal (1) of Univariate Laurent Polynomial Ring in f2 over Rational Field} sage: G.characteristic_varieties(groebner=True) {0: [0], 1: [-1 + f2, 1 - f2 + f2^2], 2: []} sage: G = FreeGroup(2)/[3 * (1, ), 2 * (2, )] @@ -1804,7 +1809,17 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): sage: G = FreeGroup(2)/[2 * (2, )] sage: G.characteristic_varieties(groebner=True) {0: [(f1 + 1,), (f1 - 1,)], 1: [(f1 + 1,), (f1 - 1, f2 - 1)], 2: []} + sage: G = (FreeGroup(0) / []) + sage: G.characteristic_varieties() + {0: Principal ideal (0) of Rational Field, + 1: Principal ideal (1) of Rational Field} + sage: G.characteristic_varieties(groebner=True) + {0: [(0,)], 1: [(1,)]} """ + if self.ngens() == 0: + if groebner: + return {j: [(ring(j),)] for j in (0, 1)} + return {j: ring.ideal(j) for j in (0, 1)} A, rels = self.abelian_alexander_matrix(ring=ring, simplified=True) R = A.base_ring() eval_1 = {x: ring(1) for x in R.gens()} @@ -1816,7 +1831,8 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): K = R.base_ring() id_rels = R.ideal(rels) res = dict() - for j in range(n + 2): + bound = n + 1 + for j in range(bound + 1): J = id_rels + A.fitting_ideal(j) # J = R.ideal(id_rels.gens() + A.fitting_ideal(j).gens()) if j <= n1: @@ -1824,14 +1840,17 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): if J1: J *= ideal_1 res[j] = R.ideal(J.gens_reduced()) + if R(1) in res[j].gens(): + bound = j + break if not groebner or not ring.is_field(): return res if R.ngens() == 1: - res = {j: gcd(S(p) for p in res[j].gens()) for j in range(n + 2)} + res = {j: gcd(S(p) for p in res[j].gens()) for j in range(bound + 1)} char_var = dict() strict = True j = 0 - while strict and j <= n + 1: + while strict and j <= bound: if res[j] == 0: char_var[j] = [R(0)] else: @@ -1846,7 +1865,7 @@ def characteristic_varieties(self, ring=QQ, matrix_ideal=None, groebner=False): char_var = dict() strict = True j = 0 - while strict and j <= n + 1: + while strict and j <= bound: LJ = res[j].minimal_associated_primes() fct = [id.groebner_basis() for id in LJ] char_var[j] = fct From a508ff91840b6bf4ca69ec82c96541741a1c62ff Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sat, 30 Sep 2023 08:21:59 +0200 Subject: [PATCH 094/463] always return .scaling_factor() in base field for EllipticCurveIsogeny --- src/sage/schemes/elliptic_curves/ell_curve_isogeny.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index cccfce646b3..192334f73ba 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -2838,11 +2838,18 @@ def scaling_factor(self): sage: phi.dual().scaling_factor() 43 + TESTS: + + Check for :issue:`36638`:: + + sage: phi.scaling_factor().parent() # needs sage.rings.finite_rings + Finite Field in z2 of size 257^2 + ALGORITHM: The "inner" isogeny is normalized by construction, so we only need to account for the scaling factors of a pre- and post-isomorphism. """ - sc = Integer(1) + sc = self.__base_field.one() if self.__pre_isomorphism is not None: sc *= self.__pre_isomorphism.scaling_factor() if self.__post_isomorphism is not None: From 372ed15b03b92f273c8fab6d56f585926ee6207a Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 3 Nov 2023 13:52:55 +0100 Subject: [PATCH 095/463] add and fix doctests --- src/sage/schemes/elliptic_curves/mod_poly.py | 27 ++++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/mod_poly.py b/src/sage/schemes/elliptic_curves/mod_poly.py index 50fd1108e91..88af6185a7b 100644 --- a/src/sage/schemes/elliptic_curves/mod_poly.py +++ b/src/sage/schemes/elliptic_curves/mod_poly.py @@ -66,16 +66,16 @@ def classical_modular_polynomial(l, j=None): Increasing the cache size can be useful for repeated invocations:: - sage: %timeit classical_modular_polynomial(101) # random + sage: %timeit classical_modular_polynomial(101) # not tested 6.11 s ± 1.21 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) - sage: %timeit classical_modular_polynomial(101, GF(65537).random_element()) # random + sage: %timeit classical_modular_polynomial(101, GF(65537).random_element()) # not tested 5.43 s ± 2.71 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) - sage: classical_modular_polynomial.set_cache_bound(150) - sage: %timeit classical_modular_polynomial(101) # random + sage: classical_modular_polynomial.set_cache_bound(150) # not tested + sage: %timeit classical_modular_polynomial(101) # not tested The slowest run took 10.35 times longer than the fastest. This could mean that an intermediate result is being cached. 1.84 µs ± 1.84 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) - sage: %timeit classical_modular_polynomial(101, GF(65537).random_element()) # random + sage: %timeit classical_modular_polynomial(101, GF(65537).random_element()) # not tested 59.8 ms ± 29.4 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) TESTS:: @@ -144,6 +144,23 @@ def classical_modular_polynomial(l, j=None): return classical_modular_polynomial(l)(j, Y) def _set_cache_bound(bnd): + r""" + Internal helper function to allow setting the caching cutoff for + :func:`classical_modular_polynomial`. + + Exposed as ``classical_modular_polynomial.set_cache_bound()``. + + EXAMPLES:: + + sage: import sage.schemes.elliptic_curves.mod_poly as m + sage: m._cache_bound + 100 + sage: m._set_cache_bound(123) + sage: m._cache_bound + 123 + sage: classical_modular_polynomial.set_cache_bound is m._set_cache_bound + True + """ global _cache_bound _cache_bound = bnd classical_modular_polynomial.set_cache_bound = _set_cache_bound From 5de7eb67e15ddfa193ab78b1ae3c6c0956c257b7 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Mon, 10 Jul 2023 11:28:49 +0200 Subject: [PATCH 096/463] implement sums of elliptic-curve morphisms --- .../en/reference/arithmetic_curves/index.rst | 3 +- src/sage/schemes/elliptic_curves/ell_field.py | 41 +- src/sage/schemes/elliptic_curves/ell_point.py | 7 +- src/sage/schemes/elliptic_curves/hom.py | 58 +- src/sage/schemes/elliptic_curves/hom_sum.py | 644 ++++++++++++++++++ 5 files changed, 737 insertions(+), 16 deletions(-) create mode 100644 src/sage/schemes/elliptic_curves/hom_sum.py diff --git a/src/doc/en/reference/arithmetic_curves/index.rst b/src/doc/en/reference/arithmetic_curves/index.rst index 6ab10dcf1c0..669a05b02a9 100644 --- a/src/doc/en/reference/arithmetic_curves/index.rst +++ b/src/doc/en/reference/arithmetic_curves/index.rst @@ -18,10 +18,11 @@ Maps between them :maxdepth: 1 sage/schemes/elliptic_curves/hom + sage/schemes/elliptic_curves/hom_composite + sage/schemes/elliptic_curves/hom_sum sage/schemes/elliptic_curves/weierstrass_morphism sage/schemes/elliptic_curves/ell_curve_isogeny sage/schemes/elliptic_curves/hom_velusqrt - sage/schemes/elliptic_curves/hom_composite sage/schemes/elliptic_curves/hom_scalar sage/schemes/elliptic_curves/hom_frobenius sage/schemes/elliptic_curves/isogeny_small_degree diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 7dd65c95749..064aeeed78b 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -2049,13 +2049,13 @@ def compute_model(E, name): raise NotImplementedError(f'cannot compute {name} model') -def point_of_order(E, l): +def point_of_order(E, n): r""" Given an elliptic curve `E` over a finite field or a number field - and an integer `\ell \geq 1`, construct a point of order `\ell` on `E`, + and an integer `n \geq 1`, construct a point of order `n` on `E`, possibly defined over an extension of the base field of `E`. - Currently only prime values of `\ell` are supported. + Currently only prime powers `n` are supported. EXAMPLES:: @@ -2070,6 +2070,13 @@ def point_of_order(E, l): sage: P.curve().a_invariants() (1, 2, 3, 4, 5) + :: + + sage: Q = point_of_order(E, 8); Q + (69*x^5 + 24*x^4 + 100*x^3 + 65*x^2 + 88*x + 97 : 65*x^5 + 28*x^4 + 5*x^3 + 45*x^2 + 42*x + 18 : 1) + sage: 8*Q == 0 and 4*Q != 0 + True + :: sage: from sage.schemes.elliptic_curves.ell_field import point_of_order @@ -2078,10 +2085,23 @@ def point_of_order(E, l): (x : -Y : 1) sage: P.base_ring() Number Field in Y with defining polynomial Y^2 - x^3 - 7*x - 7 over its base field + sage: P.base_ring().base_field() + Number Field in x with defining polynomial x^4 + 14*x^2 + 28*x - 49/3 sage: P.order() 3 sage: P.curve().a_invariants() (0, 0, 0, 7, 7) + + :: + + sage: Q = point_of_order(E, 4); Q # random + (x : Y : 1) + sage: Q.base_ring() + Number Field in Y with defining polynomial Y^2 - x^3 - 7*x - 7 over its base field + sage: Q.base_ring().base_field() + Number Field in x with defining polynomial x^6 + 35*x^4 + 140*x^3 - 245*x^2 - 196*x - 735 + sage: Q.order() + 4 """ # Construct the field extension defined by the given polynomial, # in such a way that the result is recognized by Sage as a field. @@ -2094,14 +2114,15 @@ def ffext(poly): return poly.splitting_field(rng.variable_name()) return fld.extension(poly, rng.variable_name()) - l = ZZ(l) - if l == 1: + n = ZZ(n) + if n == 1: return E(0) - if not l.is_prime(): - raise NotImplementedError('composite orders are currently unsupported') + l,m = n.is_prime_power(get_data=True) + if not m: + raise NotImplementedError('only prime-power orders are currently supported') - xpoly = E.division_polynomial(l) + xpoly = E.division_polynomial(n) // E.division_polynomial(n//l) if xpoly.degree() < 1: # supersingular and l == p raise ValueError('curve does not have any points of the specified order') @@ -2116,4 +2137,6 @@ def ffext(poly): xx = FF(xx) EE = E.change_ring(FF) - return EE.lift_x(xx) + pt = EE.lift_x(xx) + pt.set_order(n, check=False) + return pt diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index 24908b9743e..db3b8ae52d1 100644 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -1359,9 +1359,10 @@ def set_order(self, value=None, *, multiple=None, check=True): raise ValueError('Value %s illegal for point order' % value) E = self.curve() q = E.base_ring().cardinality() - low, hi = Hasse_bounds(q) - if value > hi: - raise ValueError('Value %s illegal: outside max Hasse bound' % value) + if q < oo: + _, hi = Hasse_bounds(q) + if value > hi: + raise ValueError('Value %s illegal: outside max Hasse bound' % value) if value * self != E(0): raise ValueError('Value %s illegal: %s * %s is not the identity' % (value, value, self)) if hasattr(self, '_order') and self._order != value: # already known diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 995420ae438..fe95bb7e2b3 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -10,6 +10,7 @@ - :class:`~sage.schemes.elliptic_curves.ell_curve_isogeny.EllipticCurveIsogeny` - :class:`~sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism` - :class:`~sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite` +- :class:`~sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_sum` - :class:`~sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar` - :class:`~sage.schemes.elliptic_curves.hom_frobenius.EllipticCurveHom_frobenius` - :class:`~sage.schemes.elliptic_curves.hom_velusqrt.EllipticCurveHom_velusqrt` @@ -134,6 +135,51 @@ def _composition_(self, other, homset): from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite return EllipticCurveHom_composite.from_factors([other, self]) + def _add_(self, other): + r""" + Add two :class:`EllipticCurveHom` objects by constructing a + formal :class:`EllipticCurveHom_sum`. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: phi + phi # indirect doctest + Sum morphism: + From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 + To: Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 + Via: (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101) + """ + from sage.schemes.elliptic_curves.hom_sum import EllipticCurveHom_sum + phis = [] + if isinstance(self, EllipticCurveHom_sum): + phis += self.summands() + else: + phis.append(self) + if isinstance(other, EllipticCurveHom_sum): + phis += other.summands() + else: + phis.append(other) + #TODO should probably try to simplify some more? + return EllipticCurveHom_sum(phis) + + def _sub_(self, other): + r""" + Subtract two :class:`EllipticCurveHom` objects by negating + and constructing a formal :class:`EllipticCurveHom_sum`. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: phi - phi # indirect doctest + Sum morphism: + From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 + To: Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 + Via: (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101) + """ + return self + (-other) + @staticmethod def _comparison_impl(left, right, op): r""" @@ -384,6 +430,7 @@ def kernel_polynomial(self): - :meth:`EllipticCurveIsogeny.kernel_polynomial` - :meth:`sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism.kernel_polynomial` - :meth:`sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite.kernel_polynomial` + - :meth:`sage.schemes.elliptic_curves.hom_sum.EllipticCurveHom_sum.kernel_polynomial` - :meth:`sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar.kernel_polynomial` - :meth:`sage.schemes.elliptic_curves.hom_frobenius.EllipticCurveHom_frobenius.kernel_polynomial` @@ -406,6 +453,7 @@ def dual(self): - :meth:`EllipticCurveIsogeny.dual` - :meth:`sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism.dual` - :meth:`sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite.dual` + - :meth:`sage.schemes.elliptic_curves.hom_sum.EllipticCurveHom_sum.dual` - :meth:`sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar.dual` - :meth:`sage.schemes.elliptic_curves.hom_frobenius.EllipticCurveHom_frobenius.dual` @@ -430,6 +478,7 @@ def rational_maps(self): - :meth:`EllipticCurveIsogeny.rational_maps` - :meth:`sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism.rational_maps` - :meth:`sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite.rational_maps` + - :meth:`sage.schemes.elliptic_curves.hom_sum.EllipticCurveHom_sum.rational_maps` - :meth:`sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar.rational_maps` - :meth:`sage.schemes.elliptic_curves.hom_frobenius.EllipticCurveHom_frobenius.rational_maps` @@ -453,6 +502,7 @@ def x_rational_map(self): - :meth:`EllipticCurveIsogeny.x_rational_map` - :meth:`sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism.x_rational_map` - :meth:`sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite.x_rational_map` + - :meth:`sage.schemes.elliptic_curves.hom_sum.EllipticCurveHom_sum.x_rational_map` - :meth:`sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar.x_rational_map` - :meth:`sage.schemes.elliptic_curves.hom_frobenius.EllipticCurveHom_frobenius.x_rational_map` @@ -484,6 +534,7 @@ def scaling_factor(self): - :meth:`EllipticCurveIsogeny.scaling_factor` - :meth:`sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism.scaling_factor` - :meth:`sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite.scaling_factor` + - :meth:`sage.schemes.elliptic_curves.hom_sum.EllipticCurveHom_sum.scaling_factor` - :meth:`sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar.scaling_factor` TESTS:: @@ -634,6 +685,7 @@ def is_separable(self): - :meth:`EllipticCurveIsogeny.is_separable` - :meth:`sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism.is_separable` - :meth:`sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite.is_separable` + - :meth:`sage.schemes.elliptic_curves.hom_sum.EllipticCurveHom_sum.is_separable` - :meth:`sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar.is_separable` - :meth:`sage.schemes.elliptic_curves.hom_frobenius.EllipticCurveHom_frobenius.is_separable` @@ -926,11 +978,11 @@ def matrix_on_subgroup(self, domain_gens, codomain_gens=None): if R.weil_pairing(S, n).multiplicative_order() != n: raise ValueError('generator points on codomain are not independent') - imP = self(P) - imQ = self(Q) + imP = self._eval(P) + imQ = self._eval(Q) from sage.groups.additive_abelian.additive_abelian_wrapper import AdditiveAbelianGroupWrapper - H = AdditiveAbelianGroupWrapper(self.codomain().point_homset(), [R,S], [n,n]) + H = AdditiveAbelianGroupWrapper(R.parent(), [R,S], [n,n]) vecP = H.discrete_log(imP) vecQ = H.discrete_log(imQ) diff --git a/src/sage/schemes/elliptic_curves/hom_sum.py b/src/sage/schemes/elliptic_curves/hom_sum.py new file mode 100644 index 00000000000..cfe6a7e85a6 --- /dev/null +++ b/src/sage/schemes/elliptic_curves/hom_sum.py @@ -0,0 +1,644 @@ +r""" +Sums of morphisms of elliptic curves + +The set `\mathrm{Hom}(E,E')` of morphisms between two elliptic curves +forms an abelian group under pointwise addition. An important special +case is the endomorphism ring `\mathrm{End}(E) = \mathrm{Hom}(E,E)`. +However, it is not immediately obvious how to compute some properties +of the sum `\varphi+\psi` of two isogenies, even when both are given +explicitly. This class provides functionality for representing sums of +elliptic-curve morphisms (in particular, isogenies and endomorphisms) +formally, and explicitly computing important properties (such as the +degree or the kernel polynomial) from the formal representation. + +EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: phi + phi + Sum morphism: + From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 + To: Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 + Via: (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101) + sage: phi + phi == phi * E.scalar_multiplication(2) + True + sage: phi + phi + phi == phi * E.scalar_multiplication(3) + True + +An example of computing with a supersingular endomorphism ring:: + + sage: E = EllipticCurve(GF(419^2), [1,0]) + sage: i = E.automorphisms()[-1] + sage: j = E.frobenius_isogeny() + sage: i * j == - j * i # i,j anticommute + True + sage: (i + j) * i == i^2 - i*j # distributive law + True + sage: (j - E.scalar_multiplication(1)).degree() # point counting! + 420 + +AUTHORS: + +- Lorenz Panny (2023) +""" + +from sage.misc.cachefunc import cached_method +from sage.structure.sequence import Sequence + +from sage.arith.misc import integer_floor, gcd +from sage.functions.other import sqrt + +from sage.rings.integer_ring import ZZ +from sage.rings.polynomial.polynomial_ring import polygen + +from sage.sets.primes import Primes + +from sage.schemes.elliptic_curves.ell_field import point_of_order +from sage.groups.generic import discrete_log, order_from_multiple + +from sage.schemes.elliptic_curves.hom import EllipticCurveHom, compare_via_evaluation + + +class EllipticCurveHom_sum(EllipticCurveHom): + + _degree = None + _phis = None + + def __init__(self, phis, domain=None, codomain=None): + r""" + Construct a sum morphism of elliptic curves from its summands. + (For empty sums, the domain and codomain curves must be given.) + + EXAMPLES:: + + sage: from sage.schemes.elliptic_curves.hom_sum import EllipticCurveHom_sum + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: EllipticCurveHom_sum([phi, phi]) + Sum morphism: + From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 + To: Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 + Via: (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101) + + The zero morphism can be constructed even between non-isogenous curves:: + + sage: E1 = EllipticCurve(GF(101), [5,5]) + sage: E2 = EllipticCurve(GF(101), [7,7]) + sage: E1.is_isogenous(E2) + False + sage: EllipticCurveHom_sum([], E1, E2) + Sum morphism: + From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 + To: Elliptic Curve defined by y^2 = x^3 + 7*x + 7 over Finite Field of size 101 + Via: () + """ + phis = tuple(phis) + + if not phis and (domain is None or codomain is None): + raise ValueError('need either phis or both domain and codomain') + + for phi in phis: + if not isinstance(phi, EllipticCurveHom): + raise ValueError(f'not an elliptic-curve morphism: {phi}') + + if domain is None: + domain = phis[0].domain() + if codomain is None: + codomain = phis[0].codomain() + for phi in phis: + if phi.domain() != domain: + raise ValueError(f'summand {phi} has incorrect domain (need {domain})') + if phi.codomain() != codomain: + raise ValueError(f'summand {phi} has incorrect codomain (need {codomain})') + + self._phis = phis + self._domain = domain + self._codomain = codomain + + # We temporarily overwrite the _degree attribute here to prevent the + # EllipticCurveHom constructor from attempting to compute the degree. + self._degree = 0 + EllipticCurveHom.__init__(self, self._domain, self._codomain) + self._degree = None + + def _call_(self, P): + r""" + Evaluate this sum morphism at a point. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: P = E.lift_x(0) + sage: (phi + phi)(P) + (72 : 56 : 1) + sage: (phi - phi)(P) + (0 : 1 : 0) + """ + return sum((phi(P) for phi in self._phis), self._codomain(0)) + + def _eval(self, P): + r""" + Less strict evaluation method for internal use. + + In particular, this can be used to evaluate ``self`` at a + point defined over an extension field. + + INPUT: a sequence of 3 coordinates defining a point on ``self`` + + OUTPUT: the result of evaluating ``self`` at the given point + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: P = E.change_ring(GF(101^2)).lift_x(1) + sage: (phi + phi)._eval(P) + (11 : 15*z2 + 71 : 1) + sage: (phi - phi)._eval(P) + (0 : 1 : 0) + """ + if self._domain.defining_polynomial()(*P): + raise ValueError(f'{P} not on {self._domain}') + k = Sequence(P).universe() + return sum((phi._eval(P) for phi in self._phis), self._codomain.base_extend(k)(0)) + + def _repr_(self): + r""" + Return basic facts about this sum morphism as a string. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: phi + phi # indirect doctest + Sum morphism: + From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 + To: Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 + Via: (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101) + """ + return f'Sum morphism:' \ + f'\n From: {self._domain}' \ + f'\n To: {self._codomain}' \ + f'\n Via: {self._phis}' + + def summands(self): + r""" + Return the individual summands making up this sum morphism. + + EXAMPLES:: + + sage: E = EllipticCurve(j=5) + sage: m2 = E.scalar_multiplication(2) + sage: m3 = E.scalar_multiplication(3) + sage: m2 + m3 + Sum morphism: + From: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field + To: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field + Via: (Scalar-multiplication endomorphism [2] of Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field, Scalar-multiplication endomorphism [3] of Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field) + """ + return self._phis + + @cached_method + def to_isogeny_chain(self): + r""" + Convert this formal sum of elliptic-curve morphisms into a + :class:`EllipticCurveHom_composite` object representing the + same morphism. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: (phi + phi).to_isogeny_chain() + Composite morphism of degree 28 = 4*1*7: + From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 + To: Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 + + :: + + sage: p = 419 + sage: E = EllipticCurve(GF(p^2), [1,0]) + sage: iota = E.automorphisms()[2] # sqrt(-1) + sage: pi = E.frobenius_isogeny() # sqrt(-p) + sage: endo = iota + pi + sage: endo.degree() + 420 + sage: endo.to_isogeny_chain() + Composite morphism of degree 420 = 4*1*3*5*7: + From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2 + To: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2 + + The decomposition is impossible for the constant zero map:: + + sage: endo = iota*pi + pi*iota + sage: endo.degree() + 0 + sage: endo.to_isogeny_chain() + Traceback (most recent call last): + ... + ValueError: zero morphism cannot be written as a composition of isogenies + + Isomorphisms are supported as well:: + + sage: E = EllipticCurve(j=5); E + Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field + sage: m2 = E.scalar_multiplication(2) + sage: m3 = E.scalar_multiplication(3) + sage: (m2 - m3).to_isogeny_chain() + Composite morphism of degree 1 = 1^2: + From: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field + To: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field + sage: (m2 - m3).rational_maps() + (x, -x - y) + """ + deg = self.degree() + if deg.is_zero(): + raise ValueError('zero morphism cannot be written as a composition of isogenies') + + p = self.base_ring().characteristic() + insep = 0 + scalar = 1 #TODO Can we detect scalar factors earlier to save some extensions below? + + ker = [] + for l,m in deg.factor(): + if l == p: # possibly inseparable + try: + P = point_of_order(self.domain(), l**m) + except ValueError: + # supersingular; every p-isogeny is purely inseparable + insep = m + continue + Q = self._eval(P) + u = order_from_multiple(Q, l**m).valuation(l) + if u < m: + pt = l**u * P + pt.set_order(l**(m-u)) + ker.append(pt) + insep = u + continue + +# F = self.domain().division_field(l**m) #FIXME this can be used once #35936 is done; workaround below + F = self.domain().division_polynomial(l**m).splitting_field('X').extension(2,'Y') + + P,Q = self.domain().change_ring(F).torsion_basis(l**m) + if self.is_endomorphism(): + R,S = P,Q + else: + R,S = self.codomain().change_ring(F).torsion_basis(l**m) + M = self.matrix_on_subgroup((P,Q), (R,S)) + g = ZZ(gcd(M.list())).p_primary_part(l) + if g > 1: + scalar *= g + M = (M.change_ring(ZZ) / g).change_ring(M.base_ring()) + K = M.left_kernel_matrix() + for row in K: + u,v = map(ZZ, row) + pt = u*P + v*Q + pt.set_order(row.additive_order()) + ker.append(pt) + + from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite + phi = EllipticCurveHom_composite(self.domain(), []) + + if scalar != 1: + phi *= phi.codomain().scalar_multiplication(scalar) + + while ker: + K = ker.pop(0) + + (l,e), = K.order().factor() + for i in reversed(range(e)): + Kl = l**i * K + Kl.set_order(l) + + from sage.groups.generic import multiples + from sage.misc.misc_c import prod + x = polygen(Kl.base_ring()) + poly = prod(x - T.xy()[0] for T in multiples(Kl, l//2, Kl)) + poly = poly.change_ring(self.base_ring()) + + psi = phi.codomain().isogeny(poly) + phi = psi * phi + K = psi._eval(K) + ker = [psi._eval(P) for P in ker] + + if insep: + frob = phi.codomain().frobenius_isogeny(insep) + phi = frob * phi + + from sage.schemes.elliptic_curves.hom import find_post_isomorphism + iso = find_post_isomorphism(phi, self) + return iso * phi + + # EllipticCurveHom methods + + def _degree_bound(self): + r""" + Return an upper bound on the degree of this sum morphism. + + ALGORITHM: Induction using the bound + `|\deg(f+g) - \deg(f) - \deg(g)| \leq 2\sqrt{\deg(f)\cdot\deg(g)}`; + see for instance Lemma V.1.2 of [Sil2009]_. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: (phi + phi)._degree_bound() + 28 + sage: (phi + phi).degree() + 28 + sage: (phi - phi)._degree_bound() + 28 + sage: (phi - phi).degree() + 0 + + :: + + sage: E = EllipticCurve(GF(443), [1,1]) + sage: pi = E.frobenius_endomorphism() + sage: m1 = E.scalar_multiplication(1) + sage: (pi - m1)._degree_bound() + 486 + sage: (pi - m1).degree() + 433 + """ + B = ZZ(0) + for phi in self._phis: + B += phi.degree() + 2*sqrt(B * phi.degree()) + return integer_floor(B) + + def _compute_degree(self): + r""" + Internal method to compute and cache the degree of this sum morphism + (and its dual). + + ALGORITHM: Evaluate the composition with the dual on points of small + order and solve logarithms to eventually recover the degree using CRT. + (This is essentially Schoof's algorithm, applied to a scalar.) + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: isog = phi + phi + sage: print(isog._degree) + None + sage: isog._compute_degree() + sage: isog._degree + 28 + + :: + + sage: E = EllipticCurve(GF(443), [1,1]) + sage: pi = E.frobenius_endomorphism() + sage: m1 = E.scalar_multiplication(1) + sage: endo = pi - m1 + sage: print(endo._degree) + None + sage: endo._compute_degree() + sage: endo._degree + 433 + sage: endo.dual()._degree + 433 + """ + if self._degree is not None: + return + if len(self._phis) == 0: + self._degree = 0 + elif len(self._phis) == 1: + self._degree = self._phis[0].degree() + else: + #TODO In some cases it would probably be faster to simply + # compute the kernel polynomial using the addition formulas? + from sage.rings.finite_rings.integer_mod import Mod + + M = self._degree_bound() + 1 + deg = Mod(0,1) + for l in Primes(): + if deg.modulus() >= M: + break + try: + P = point_of_order(self._domain, l) + except ValueError: + continue # supersingular and l == p + + Q = self.dual()._eval(self._eval(P)) + d = discrete_log(Q, P, ord=l, operation='+') + deg = deg.crt(Mod(d, l)) + + self._degree = ZZ(deg) + self.dual()._degree = self._degree + + @staticmethod + def _comparison_impl(left, right, op): + r""" + Compare a sum morphism to another elliptic-curve morphism. + + Called by :meth:`EllipticCurveHom._richcmp_`. + + If possible, we use + :func:`~sage.schemes.elliptic_curves.hom.compare_via_evaluation`. + The complexity in that case is polynomial in the logarithm of + the degree. + + TESTS:: + + sage: from sage.schemes.elliptic_curves.hom_sum import EllipticCurveHom_sum + sage: E = EllipticCurve(GF(419^2), [1,0]) + sage: i = E.automorphisms()[-1] + sage: j = E.frobenius_isogeny() + sage: i + j == j + i + True + """ + from sage.structure.richcmp import op_EQ + if op != op_EQ: + return NotImplemented + try: + return compare_via_evaluation(left, right) + except NotImplementedError: + return NotImplemented + + def degree(self): + r""" + Return the degree of this sum morphism. + + EXAMPLES: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: (phi + phi).degree() + 28 + + This method yields a simple toy point-counting algorithm:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: m1 = E.scalar_multiplication(1) + sage: pi = E.frobenius_endomorphism() + sage: (pi - m1).degree() + 119 + sage: E.count_points() + 119 + + ALGORITHM: Essentially Schoof's algorithm; see :meth:`_compute_degree`. + """ + if self._degree is None: + self._compute_degree() + return self._degree + + def rational_maps(self): + r""" + Return the rational maps of this sum morphism. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: (phi + phi).rational_maps() + ((5*x^28 + 43*x^27 + 26*x^26 - ... + 7*x^2 - 23*x + 38)/(23*x^27 + 16*x^26 + 9*x^25 + ... - 43*x^2 - 22*x + 37), + (42*x^42*y - 44*x^41*y - 22*x^40*y + ... - 26*x^2*y - 50*x*y - 18*y)/(-24*x^42 - 47*x^41 - 12*x^40 + ... + 18*x^2 - 48*x + 18)) + + ALGORITHM: :meth:`to_isogeny_chain`. + """ + #TODO In some cases it would probably be faster to compute this + # directly using the addition formulas? + return self.to_isogeny_chain().rational_maps() + + def x_rational_map(self): + r""" + Return the `x`-coordinate rational map of this sum morphism. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: (phi + phi).x_rational_map() + (9*x^28 + 37*x^27 + 67*x^26 + ... + 53*x^2 + 100*x + 28)/(x^27 + 49*x^26 + 97*x^25 + ... + 64*x^2 + 21*x + 6) + + ALGORITHM: :meth:`to_isogeny_chain`. + """ + #TODO In some cases it would probably be faster to compute this + # directly using the addition formulas? + return self.to_isogeny_chain().x_rational_map() + + def kernel_polynomial(self): + r""" + Return the kernel polynomial of this sum morphism. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: (phi + phi).kernel_polynomial() + x^15 + 75*x^14 + 16*x^13 + 59*x^12 + 28*x^11 + 60*x^10 + 69*x^9 + 79*x^8 + 79*x^7 + 52*x^6 + 35*x^5 + 11*x^4 + 37*x^3 + 69*x^2 + 66*x + 63 + + :: + + sage: E = EllipticCurve(GF(11), [5,5]) + sage: pi = E.frobenius_endomorphism() + sage: m1 = E.scalar_multiplication(1) + sage: (pi - m1).kernel_polynomial() + x^9 + 7*x^8 + 2*x^7 + 4*x^6 + 10*x^4 + 4*x^3 + 9*x^2 + 7*x + + ALGORITHM: :meth:`to_isogeny_chain`. + """ + #TODO In some cases it would probably be faster to compute this + # directly using the addition formulas? + return self.to_isogeny_chain().kernel_polynomial() + + def scaling_factor(self): + r""" + Return the Weierstrass scaling factor associated to this + sum morphism. + + The scaling factor is the constant `u` (in the base field) + such that `\varphi^* \omega_2 = u \omega_1`, where + `\varphi: E_1\to E_2` is this morphism and `\omega_i` are + the standard Weierstrass differentials on `E_i` defined by + `\mathrm dx/(2y+a_1x+a_3)`. + + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: phi.scaling_factor() + 84 + sage: (phi + phi).scaling_factor() + 67 + + ALGORITHM: The scaling factor is additive under addition + of elliptic-curve morphisms, so we simply add together the + scaling factors of the :meth:`summands`. + """ + return sum(phi.scaling_factor() for phi in self._phis) + + @cached_method + def dual(self): + r""" + Return the dual of this sum morphism. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101), [5,5]) + sage: phi = E.isogenies_prime_degree(7)[0] + sage: (phi + phi).dual() + Sum morphism: + From: Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 + To: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 + Via: (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101) + sage: (phi + phi).dual() == phi.dual() + phi.dual() + True + + :: + + sage: E = EllipticCurve(GF(431^2), [1,0]) + sage: iota = E.automorphisms()[2] + sage: m2 = E.scalar_multiplication(2) + sage: endo = m2 + iota + sage: endo.dual() + Sum morphism: + From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2 + To: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2 + Via: (Scalar-multiplication endomorphism [2] of Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2, Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2 + Via: (u,r,s,t) = (8*z2 + 427, 0, 0, 0)) + sage: endo.dual() == (m2 - iota) + True + + ALGORITHM: Taking the dual distributes over addition. + """ + psi = EllipticCurveHom_sum((phi.dual() for phi in self._phis), + domain=self._codomain, codomain=self._domain) + psi._degree = self._degree + if self.trace.is_in_cache(): + psi.trace.set_cache(-self.trace.cache) + psi.dual.set_cache(self) + return psi + + def is_separable(self): + r""" + Test whether this sum morphism is a separable isogeny. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(5^2), [0,1]) + sage: m2 = E.scalar_multiplication(2) + sage: m3 = E.scalar_multiplication(3) + sage: m2.is_separable() + True + sage: E.frobenius() + -5 + sage: (m2 + m3).is_separable() + False + sage: (m2 - m2).is_separable() + Traceback (most recent call last): + ... + ValueError: zero morphism is not an isogeny + """ + deg = self.degree() + if deg.is_zero(): + raise ValueError('zero morphism is not an isogeny') + if not self.domain().base_field().characteristic().divides(deg): + return True + return self.to_isogeny_chain().is_separable() From e348fd91a5b042bbdc9e440840beae7cc154f185 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 3 Nov 2023 11:35:29 -0700 Subject: [PATCH 097/463] src/sage/groups/perm_gps/permgroup_element.pyx: use a standard python-style loop --- src/sage/groups/perm_gps/permgroup_element.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index cb47bf05033..a459451bd6d 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -1322,7 +1322,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): return self cdef PermutationGroupElement prod = self._new_c() cdef int i - for i from 0 <= i < self.n: + for i in range(self.n): prod.perm[i] = self.perm[i] if not self._parent._has_natural_domain(): convert_dict = self._parent._domain_to_gap From 8469a642f1bcc9def53f57874345af014d786abd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 3 Nov 2023 12:03:24 -0700 Subject: [PATCH 098/463] src/sage/geometry/polyhedron/base_ZZ.py: Add more tests --- src/sage/geometry/polyhedron/base_ZZ.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/sage/geometry/polyhedron/base_ZZ.py b/src/sage/geometry/polyhedron/base_ZZ.py index 14eadcc7ae9..20b3c95bbcc 100644 --- a/src/sage/geometry/polyhedron/base_ZZ.py +++ b/src/sage/geometry/polyhedron/base_ZZ.py @@ -875,6 +875,11 @@ def normal_form(self, algorithm="palp_native", permutation=False): M(-1, 0) in 2-d lattice M + Using ``permutation=True``:: + + sage: d.normal_form(permutation=True) # needs sage.groups + ([(1, 0), (0, 1), (0, -1), (-1, 0)], ()) + It is not possible to compute normal forms for polytopes which do not span the space:: @@ -895,6 +900,13 @@ def normal_form(self, algorithm="palp_native", permutation=False): A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex and 2 rays See :issue:`15280` for proposed extensions to these cases. + + TESTS:: + + sage: d.normal_form(algorithm="palp_fiction") + Traceback (most recent call last): + ... + ValueError: algorithm must be 'palp_native' """ from sage.geometry.palp_normal_form import _palp_PM_max, _palp_canonical_order From 4797a51839b2d9215ffb3a5d61d47fed4b6a9f0c Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 3 Nov 2023 21:26:25 +0100 Subject: [PATCH 099/463] switch from qfbclassno() to quadclassunit() for large discriminants --- src/sage/quadratic_forms/bqf_class_group.py | 9 ++++++-- src/sage/rings/number_field/order.py | 25 ++++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/sage/quadratic_forms/bqf_class_group.py b/src/sage/quadratic_forms/bqf_class_group.py index 185a869b8b2..30c9bd7782a 100644 --- a/src/sage/quadratic_forms/bqf_class_group.py +++ b/src/sage/quadratic_forms/bqf_class_group.py @@ -253,7 +253,7 @@ def order(self): r""" Return the order of this form class group (the *class number*). - ALGORITHM: :pari:`qfbclassno` + ALGORITHM: :func:`sage.rings.number_field.order.quadratic_order_class_number`. EXAMPLES:: @@ -272,7 +272,12 @@ def order(self): sage: BQFClassGroup(-99999).order() 224 """ - return ZZ(pari.qfbclassno(self._disc)) + # Beware: If this code is ever generalized to positive + # discriminants, care must be taken to use the correct + # notion of class number. We may need the *narrow* class + # number here; see PARI's documentation for qfbclassno(). + from sage.rings.number_field.order import quadratic_order_class_number + return quadratic_order_class_number(self._disc) cardinality = order diff --git a/src/sage/rings/number_field/order.py b/src/sage/rings/number_field/order.py index f0b24b74630..857f33ffc4d 100644 --- a/src/sage/rings/number_field/order.py +++ b/src/sage/rings/number_field/order.py @@ -92,6 +92,29 @@ from sage.libs.pari.all import pari +def quadratic_order_class_number(disc): + r""" + Return the class number of the quadratic order of given discriminant. + + EXAMPLES:: + + sage: from sage.rings.number_field.order import quadratic_order_class_number + sage: quadratic_order_class_number(-419) + 9 + sage: quadratic_order_class_number(60) + 2 + + ALGORITHM: Either :pari:`qfbclassno` or :pari:`quadclassunit`, + depending on the size of the discriminant. + """ + # cutoffs from PARI documentation + if disc < -10**25 or disc > 10**10: + h = pari.quadclassunit(disc)[0] + else: + h = pari.qfbclassno(disc) + return ZZ(h) + + class OrderFactory(UniqueFactory): r""" Abstract base class for factories creating orders, such as @@ -1096,7 +1119,7 @@ def class_number(self, proof=None): K = self.number_field() if K.degree() != 2: raise NotImplementedError("computation of class numbers of non-maximal orders not in quadratic fields is not implemented") - return ZZ(pari.qfbclassno(self.discriminant())) + return quadratic_order_class_number(self.discriminant()) return self.number_field().class_number(proof=proof) def class_group(self, proof=None, names='c'): From 4ac814afde928dba62809984e3a0680f78e28369 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 15 May 2023 14:10:59 -0700 Subject: [PATCH 100/463] sage.algebras: Add # optional --- src/sage/algebras/clifford_algebra.py | 8 +++---- src/sage/algebras/lie_algebras/morphism.py | 4 ++-- src/sage/algebras/lie_algebras/quotient.py | 8 +++---- .../lie_algebras/structure_coefficients.py | 4 ++-- src/sage/algebras/lie_algebras/subalgebra.py | 24 +++++++++---------- .../algebras/quaternion_algebra_element.py | 8 +++---- src/sage/algebras/weyl_algebra.py | 8 +++---- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/sage/algebras/clifford_algebra.py b/src/sage/algebras/clifford_algebra.py index 220a2eb27a5..adb065e31b7 100644 --- a/src/sage/algebras/clifford_algebra.py +++ b/src/sage/algebras/clifford_algebra.py @@ -1770,11 +1770,11 @@ def interior_product_on_basis(self, a, b): Check :trac:`34694`:: - sage: E = ExteriorAlgebra(SR,'e',3) - sage: E.inject_variables() + sage: E = ExteriorAlgebra(SR,'e',3) # optional - sage.symbolic + sage: E.inject_variables() # optional - sage.symbolic Defining e0, e1, e2 - sage: a = (e0*e1).interior_product(e0) - sage: a * e0 + sage: a = (e0*e1).interior_product(e0) # optional - sage.symbolic + sage: a * e0 # optional - sage.symbolic -e0*e1 """ sgn = True diff --git a/src/sage/algebras/lie_algebras/morphism.py b/src/sage/algebras/lie_algebras/morphism.py index f71001ce98f..a4c03e22104 100644 --- a/src/sage/algebras/lie_algebras/morphism.py +++ b/src/sage/algebras/lie_algebras/morphism.py @@ -461,8 +461,8 @@ class LieAlgebraMorphism_from_generators(LieAlgebraHomomorphism_im_gens): A quotient type Lie algebra morphism:: - sage: K. = LieAlgebra(SR, abelian=True) - sage: L.morphism({X: A, Y: B}) + sage: K. = LieAlgebra(SR, abelian=True) # optional - sage.symbolic + sage: L.morphism({X: A, Y: B}) # optional - sage.symbolic Lie algebra morphism: From: Lie algebra on 4 generators (X, Y, Z, W) over Rational Field To: Abelian Lie algebra on 2 generators (A, B) over Symbolic Ring diff --git a/src/sage/algebras/lie_algebras/quotient.py b/src/sage/algebras/lie_algebras/quotient.py index 7fe6b29677f..a0400221af6 100644 --- a/src/sage/algebras/lie_algebras/quotient.py +++ b/src/sage/algebras/lie_algebras/quotient.py @@ -242,11 +242,11 @@ def __init__(self, I, L, names, index_set, category=None): TESTS:: - sage: L. = LieAlgebra(SR, {('x','y'): {'x':1}}) - sage: K = L.quotient(y) - sage: K.dimension() + sage: L. = LieAlgebra(SR, {('x','y'): {'x':1}}) # optional - sage.symbolic + sage: K = L.quotient(y) # optional - sage.symbolic + sage: K.dimension() # optional - sage.symbolic 1 - sage: TestSuite(K).run() + sage: TestSuite(K).run() # optional - sage.symbolic """ B = L.basis() sm = L.module().submodule_with_basis([I.reduce(B[i]).to_vector() diff --git a/src/sage/algebras/lie_algebras/structure_coefficients.py b/src/sage/algebras/lie_algebras/structure_coefficients.py index 16c2cf51029..48b1bbecf41 100644 --- a/src/sage/algebras/lie_algebras/structure_coefficients.py +++ b/src/sage/algebras/lie_algebras/structure_coefficients.py @@ -411,8 +411,8 @@ def change_ring(self, R): sage: LQQ = L.change_ring(QQ) sage: LQQ.structure_coefficients() Finite family {('x', 'y'): z} - sage: LSR = LQQ.change_ring(SR) - sage: LSR.structure_coefficients() + sage: LSR = LQQ.change_ring(SR) # optional - sage.symbolic + sage: LSR.structure_coefficients() # optional - sage.symbolic Finite family {('x', 'y'): z} """ return LieAlgebraWithStructureCoefficients( diff --git a/src/sage/algebras/lie_algebras/subalgebra.py b/src/sage/algebras/lie_algebras/subalgebra.py index 90779eb91fc..ab7b6922083 100644 --- a/src/sage/algebras/lie_algebras/subalgebra.py +++ b/src/sage/algebras/lie_algebras/subalgebra.py @@ -75,32 +75,32 @@ class LieSubalgebra_finite_dimensional_with_basis(Parent, UniqueRepresentation): Elements of the ambient Lie algebra can be reduced modulo an ideal or subalgebra:: - sage: L. = LieAlgebra(SR, {('X','Y'): {'Z': 1}}) - sage: I = L.ideal(Y) - sage: I.reduce(X + 2*Y + 3*Z) + sage: L. = LieAlgebra(SR, {('X','Y'): {'Z': 1}}) # optional - sage.symbolic + sage: I = L.ideal(Y) # optional - sage.symbolic + sage: I.reduce(X + 2*Y + 3*Z) # optional - sage.symbolic X - sage: S = L.subalgebra(Y) - sage: S.reduce(X + 2*Y + 3*Z) + sage: S = L.subalgebra(Y) # optional - sage.symbolic + sage: S.reduce(X + 2*Y + 3*Z) # optional - sage.symbolic X + 3*Z The reduction gives elements in a fixed complementary subspace. When the base ring is a field, the complementary subspace is spanned by those basis elements which are not leading supports of the basis:: - sage: I = L.ideal(X + Y) - sage: I.basis() + sage: I = L.ideal(X + Y) # optional - sage.symbolic + sage: I.basis() # optional - sage.symbolic Family (X + Y, Z) - sage: el = var('x')*X + var('y')*Y + var('z')*Z; el + sage: el = var('x')*X + var('y')*Y + var('z')*Z; el # optional - sage.symbolic x*X + y*Y + z*Z - sage: I.reduce(el) + sage: I.reduce(el) # optional - sage.symbolic (x-y)*X Giving a different ``order`` may change the reduction of elements:: - sage: I = L.ideal(X + Y, order=lambda s: ['Z','Y','X'].index(s)) - sage: I.basis() + sage: I = L.ideal(X + Y, order=lambda s: ['Z','Y','X'].index(s)) # optional - sage.symbolic + sage: I.basis() # optional - sage.symbolic Family (Z, X + Y) - sage: I.reduce(el) + sage: I.reduce(el) # optional - sage.symbolic (-x+y)*Y A subalgebra of a subalgebra is a subalgebra of the original:: diff --git a/src/sage/algebras/quaternion_algebra_element.py b/src/sage/algebras/quaternion_algebra_element.py index ef527e2f269..48c1c9871ec 100644 --- a/src/sage/algebras/quaternion_algebra_element.py +++ b/src/sage/algebras/quaternion_algebra_element.py @@ -37,12 +37,12 @@ def unpickle_QuaternionAlgebraElement_number_field_v0(*args): """ EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a); z = i + j - sage: f, t = z.__reduce__() + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a); z = i + j # optional - sage.symbolic + sage: f, t = z.__reduce__() # optional - sage.symbolic sage: import sage.algebras.quaternion_algebra_element - sage: sage.algebras.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) + sage: sage.algebras.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) # optional - sage.symbolic i + j - sage: sage.algebras.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) == z + sage: sage.algebras.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) == z # optional - sage.symbolic True """ return QuaternionAlgebraElement_number_field(*args) diff --git a/src/sage/algebras/weyl_algebra.py b/src/sage/algebras/weyl_algebra.py index 13604578430..48b1dee6075 100644 --- a/src/sage/algebras/weyl_algebra.py +++ b/src/sage/algebras/weyl_algebra.py @@ -53,12 +53,12 @@ def repr_from_monomials(monomials, term_repr, use_latex=False): sage: from sage.algebras.weyl_algebra import repr_from_monomials sage: R. = QQ[] - sage: d = [(z, 4/7), (y, sqrt(2)), (x, -5)] - sage: repr_from_monomials(d, lambda m: repr(m)) + sage: d = [(z, 4/7), (y, sqrt(2)), (x, -5)] # optional - sage.symbolic + sage: repr_from_monomials(d, lambda m: repr(m)) # optional - sage.symbolic '4/7*z + sqrt(2)*y - 5*x' - sage: a = repr_from_monomials(d, lambda m: latex(m), True); a + sage: a = repr_from_monomials(d, lambda m: latex(m), True); a # optional - sage.symbolic \frac{4}{7} z + \sqrt{2} y - 5 x - sage: type(a) + sage: type(a) # optional - sage.symbolic The zero element:: From ce226276941f66b5c8c2187caccd2ebee71fbaf5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 17 May 2023 13:20:30 -0700 Subject: [PATCH 101/463] Massive modularization fixes --- src/sage/algebras/commutative_dga.py | 18 +- src/sage/algebras/lie_algebras/morphism.py | 14 +- .../algebras/quatalg/quaternion_algebra.py | 155 ++++++++++++------ .../quatalg/quaternion_algebra_element.pyx | 82 ++++----- src/sage/algebras/weyl_algebra.py | 8 +- 5 files changed, 164 insertions(+), 113 deletions(-) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index 953364d6813..2b5f2ccffd1 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -3925,8 +3925,8 @@ class CohomologyClass(SageObject, CachedRepresentation): sage: from sage.algebras.commutative_dga import CohomologyClass sage: CohomologyClass(3) [3] - sage: A. = GradedCommutativeAlgebra(QQ, degrees = (2,2,3,3)) - sage: CohomologyClass(x^2+2*y*z, A) + sage: A. = GradedCommutativeAlgebra(QQ, degrees=(2,2,3,3)) + sage: CohomologyClass(x^2 + 2*y*z, A) [2*y*z + x^2] TESTS: @@ -3978,7 +3978,7 @@ def __init__(self, x, cdga=None): EXAMPLES:: sage: from sage.algebras.commutative_dga import CohomologyClass - sage: CohomologyClass(x-2) + sage: CohomologyClass(x - 2) # optional - sage.symbolic [x - 2] """ self._x = x @@ -3989,7 +3989,7 @@ def __hash__(self): TESTS:: sage: from sage.algebras.commutative_dga import CohomologyClass - sage: hash(CohomologyClass(sin)) == hash(sin) + sage: hash(CohomologyClass(sin)) == hash(sin) # optional - sage.symbolic True """ return hash(self._x) @@ -3999,7 +3999,7 @@ def _repr_(self): EXAMPLES:: sage: from sage.algebras.commutative_dga import CohomologyClass - sage: CohomologyClass(sin) + sage: CohomologyClass(sin) # optional - sage.symbolic [sin] """ return '[{}]'.format(self._x) @@ -4009,9 +4009,9 @@ def _latex_(self): EXAMPLES:: sage: from sage.algebras.commutative_dga import CohomologyClass - sage: latex(CohomologyClass(sin)) + sage: latex(CohomologyClass(sin)) # optional - sage.symbolic \left[ \sin \right] - sage: latex(CohomologyClass(x^2)) + sage: latex(CohomologyClass(x^2)) # optional - sage.symbolic \left[ x^{2} \right] """ from sage.misc.latex import latex @@ -4024,8 +4024,8 @@ def representative(self): EXAMPLES:: sage: from sage.algebras.commutative_dga import CohomologyClass - sage: x = CohomologyClass(sin) - sage: x.representative() == sin + sage: x = CohomologyClass(sin) # optional - sage.symbolic + sage: x.representative() == sin # optional - sage.symbolic True """ return self._x diff --git a/src/sage/algebras/lie_algebras/morphism.py b/src/sage/algebras/lie_algebras/morphism.py index a4c03e22104..2d04a5e6b65 100644 --- a/src/sage/algebras/lie_algebras/morphism.py +++ b/src/sage/algebras/lie_algebras/morphism.py @@ -623,17 +623,17 @@ def _call_(self, x): EXAMPLES:: sage: L. = LieAlgebra(QQ, {('X','Y'): {'Z':1}, ('X','Z'): {'W':1}}) - sage: K. = LieAlgebra(SR, abelian=True) - sage: phi = L.morphism({X: A, Y: B}) - sage: phi(X) + sage: K. = LieAlgebra(SR, abelian=True) # optional - sage.symbolic + sage: phi = L.morphism({X: A, Y: B}) # optional - sage.symbolic + sage: phi(X) # optional - sage.symbolic A - sage: phi(Y) + sage: phi(Y) # optional - sage.symbolic B - sage: phi(Z) + sage: phi(Z) # optional - sage.symbolic 0 - sage: phi(W) + sage: phi(W) # optional - sage.symbolic 0 - sage: phi(-X + 3*Y) + sage: phi(-X + 3*Y) # optional - sage.symbolic -A + 3*B sage: K. = LieAlgebra(QQ, {('A','B'): {'C':2}}) diff --git a/src/sage/algebras/quatalg/quaternion_algebra.py b/src/sage/algebras/quatalg/quaternion_algebra.py index 1b6001209a0..f0a31dca349 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra.py +++ b/src/sage/algebras/quatalg/quaternion_algebra.py @@ -119,15 +119,17 @@ class QuaternionAlgebraFactory(UniqueFactory): Quaternion Algebra (2, 3) with base ring Finite Field of size 5 sage: QuaternionAlgebra(2, GF(5)(3)) Quaternion Algebra (2, 3) with base ring Finite Field of size 5 - sage: QuaternionAlgebra(QQ[sqrt(2)](-1), -5) - Quaternion Algebra (-1, -5) with base ring Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? - sage: QuaternionAlgebra(sqrt(-1), sqrt(-3)) + sage: QuaternionAlgebra(QQ[sqrt(2)](-1), -5) # optional - sage.symbolic + Quaternion Algebra (-1, -5) with base ring Number Field in sqrt2 + with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? + sage: QuaternionAlgebra(sqrt(-1), sqrt(-3)) # optional - sage.symbolic Quaternion Algebra (I, sqrt(-3)) with base ring Symbolic Ring sage: QuaternionAlgebra(1r,1) Quaternion Algebra (1, 1) with base ring Rational Field sage: A. = ZZ[] sage: QuaternionAlgebra(-1, t) - Quaternion Algebra (-1, t) with base ring Fraction Field of Univariate Polynomial Ring in t over Integer Ring + Quaternion Algebra (-1, t) with base ring + Fraction Field of Univariate Polynomial Ring in t over Integer Ring Python ints and floats may be passed to the ``QuaternionAlgebra(a, b)`` constructor, as may all pairs of @@ -138,11 +140,13 @@ class QuaternionAlgebraFactory(UniqueFactory): sage: QuaternionAlgebra(1r,1) Quaternion Algebra (1, 1) with base ring Rational Field sage: QuaternionAlgebra(1,1.0r) - Quaternion Algebra (1.00000000000000, 1.00000000000000) with base ring Real Field with 53 bits of precision + Quaternion Algebra (1.00000000000000, 1.00000000000000) with base ring + Real Field with 53 bits of precision sage: QuaternionAlgebra(0,0) Traceback (most recent call last): ... - ValueError: defining elements of quaternion algebra (0, 0) are not invertible in Rational Field + ValueError: defining elements of quaternion algebra (0, 0) + are not invertible in Rational Field sage: QuaternionAlgebra(GF(2)(1),1) Traceback (most recent call last): ... @@ -158,8 +162,9 @@ class QuaternionAlgebraFactory(UniqueFactory): sage: QuaternionAlgebra(QQ, -7, -21) Quaternion Algebra (-7, -21) with base ring Rational Field - sage: QuaternionAlgebra(QQ[sqrt(2)], -2,-3) - Quaternion Algebra (-2, -3) with base ring Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? + sage: QuaternionAlgebra(QQ[sqrt(2)], -2,-3) # optional - sage.symbolic + Quaternion Algebra (-2, -3) with base ring Number Field in sqrt2 + with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? ``QuaternionAlgebra(D)`` -- `D` is a squarefree integer; return a rational quaternion algebra of discriminant `D`:: @@ -540,8 +545,8 @@ def random_element(self, *args, **kwds): EXAMPLES:: - sage: g = QuaternionAlgebra(QQ[sqrt(2)], -3, 7).random_element() - sage: g.parent() is QuaternionAlgebra(QQ[sqrt(2)], -3, 7) + sage: g = QuaternionAlgebra(QQ[sqrt(2)], -3, 7).random_element() # optional - sage.symbolic + sage: g.parent() is QuaternionAlgebra(QQ[sqrt(2)], -3, 7) # optional - sage.symbolic True sage: g = QuaternionAlgebra(-3, 19).random_element() sage: g.parent() is QuaternionAlgebra(-3, 19) @@ -576,12 +581,13 @@ def free_module(self): sage: A. = LaurentPolynomialRing(GF(3)) sage: B = QuaternionAlgebra(A, -1, t) sage: B.free_module() - Ambient free quadratic module of rank 4 over the principal ideal domain Univariate Laurent Polynomial Ring in t over Finite Field of size 3 - Inner product matrix: - [2 0 0 0] - [0 2 0 0] - [0 0 t 0] - [0 0 0 t] + Ambient free quadratic module of rank 4 over the principal ideal domain + Univariate Laurent Polynomial Ring in t over Finite Field of size 3 + Inner product matrix: + [2 0 0 0] + [0 2 0 0] + [0 0 t 0] + [0 0 0 t] """ return FreeModule(self.base_ring(), 4, inner_product_matrix=self.inner_product_matrix()) @@ -594,10 +600,10 @@ def vector_space(self): sage: QuaternionAlgebra(-3,19).vector_space() Ambient quadratic space of dimension 4 over Rational Field Inner product matrix: - [ 2 0 0 0] - [ 0 6 0 0] - [ 0 0 -38 0] - [ 0 0 0 -114] + [ 2 0 0 0] + [ 0 6 0 0] + [ 0 0 -38 0] + [ 0 0 0 -114] """ return self.free_module() @@ -697,7 +703,8 @@ def maximal_order(self, take_shortcuts=True): EXAMPLES:: sage: QuaternionAlgebra(-1,-7).maximal_order() - Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k) + Order of Quaternion Algebra (-1, -7) with base ring Rational Field + with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k) sage: QuaternionAlgebra(-1,-1).maximal_order().basis() (1/2 + 1/2*i + 1/2*j + 1/2*k, i, j, k) @@ -732,13 +739,16 @@ def maximal_order(self, take_shortcuts=True): If you want bases containing 1, switch off ``take_shortcuts``:: sage: QuaternionAlgebra(-3,-89).maximal_order(take_shortcuts=False) - Order of Quaternion Algebra (-3, -89) with base ring Rational Field with basis (1, 1/2 + 1/2*i, j, 1/2 + 1/6*i + 1/2*j + 1/6*k) + Order of Quaternion Algebra (-3, -89) with base ring Rational Field + with basis (1, 1/2 + 1/2*i, j, 1/2 + 1/6*i + 1/2*j + 1/6*k) sage: QuaternionAlgebra(1,1).maximal_order(take_shortcuts=False) # Matrix ring - Order of Quaternion Algebra (1, 1) with base ring Rational Field with basis (1, 1/2 + 1/2*i, j, 1/2*j + 1/2*k) + Order of Quaternion Algebra (1, 1) with base ring Rational Field + with basis (1, 1/2 + 1/2*i, j, 1/2*j + 1/2*k) sage: QuaternionAlgebra(-22,210).maximal_order(take_shortcuts=False) - Order of Quaternion Algebra (-22, 210) with base ring Rational Field with basis (1, i, 1/2*i + 1/2*j, 1/2 + 17/22*i + 1/44*k) + Order of Quaternion Algebra (-22, 210) with base ring Rational Field + with basis (1, i, 1/2*i + 1/2*j, 1/2 + 17/22*i + 1/44*k) sage: for d in ( m for m in range(1, 750) if is_squarefree(m) ): # long time (3s) ....: A = QuaternionAlgebra(d) @@ -751,7 +761,8 @@ def maximal_order(self, take_shortcuts=True): sage: QuaternionAlgebra(K,-1,-1).maximal_order() Traceback (most recent call last): ... - NotImplementedError: maximal order only implemented for rational quaternion algebras + NotImplementedError: maximal order only implemented + for rational quaternion algebras """ if self.base_ring() != QQ: raise NotImplementedError("maximal order only implemented for rational quaternion algebras") @@ -1037,7 +1048,7 @@ def discriminant(self): sage: B.discriminant() Fractional ideal (2) - sage: QuaternionAlgebra(QQ[sqrt(2)],3,19).discriminant() + sage: QuaternionAlgebra(QQ[sqrt(2)], 3, 19).discriminant() # optional - sage.symbolic Fractional ideal (1) """ if not is_RationalField(self.base_ring()): @@ -1082,11 +1093,13 @@ def _magma_init_(self, magma): A more complicated example involving a quaternion algebra over a number field:: - sage: K. = QQ[sqrt(2)]; Q = QuaternionAlgebra(K,-1,a); Q - Quaternion Algebra (-1, sqrt2) with base ring Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? - sage: magma(Q) # optional - magma - Quaternion Algebra with base ring Number Field with defining polynomial x^2 - 2 over the Rational Field, defined by i^2 = -1, j^2 = sqrt2 - sage: Q._magma_init_(magma) # optional - magma + sage: K. = QQ[sqrt(2)]; Q = QuaternionAlgebra(K,-1,a); Q # optional - sage.symbolic + Quaternion Algebra (-1, sqrt2) with base ring Number Field in sqrt2 + with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? + sage: magma(Q) # optional - magma sage.symbolic + Quaternion Algebra with base ring Number Field with defining polynomial + x^2 - 2 over the Rational Field, defined by i^2 = -1, j^2 = sqrt2 + sage: Q._magma_init_(magma) # optional - magma sage.symbolic 'QuaternionAlgebra(_sage_[...],(_sage_[...]![-1, 0]),(_sage_[...]![0, 1]))' """ R = magma(self.base_ring()) @@ -1107,14 +1120,17 @@ def quaternion_order(self, basis, check=True): sage: Q. = QuaternionAlgebra(-11,-1) sage: Q.quaternion_order([1,i,j,k]) - Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1, i, j, k) + Order of Quaternion Algebra (-11, -1) with base ring Rational Field + with basis (1, i, j, k) We test out ``check=False``:: sage: Q.quaternion_order([1,i,j,k], check=False) - Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1, i, j, k) + Order of Quaternion Algebra (-11, -1) with base ring Rational Field + with basis (1, i, j, k) sage: Q.quaternion_order([i,j,k], check=False) - Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (i, j, k) + Order of Quaternion Algebra (-11, -1) with base ring Rational Field + with basis (i, j, k) """ return QuaternionOrder(self, basis, check=check) @@ -1210,7 +1226,9 @@ def modp_splitting_data(self, p): sage: Q.modp_splitting_data(5) Traceback (most recent call last): ... - NotImplementedError: algorithm for computing local splittings not implemented in general (currently require the first invariant to be coprime to p) + NotImplementedError: algorithm for computing local splittings + not implemented in general (currently require the first invariant + to be coprime to p) sage: Q.modp_splitting_data(2) Traceback (most recent call last): @@ -1363,7 +1381,8 @@ def __init__(self, A, basis, check=True): sage: K = QuadraticField(10) sage: A. = QuaternionAlgebra(K,-1,-1) sage: A.quaternion_order([1,i,j,k]) - Order of Quaternion Algebra (-1, -1) with base ring Number Field in a with defining polynomial x^2 - 10 with a = 3.162277660168380? with basis (1, i, j, k) + Order of Quaternion Algebra (-1, -1) with base ring Number Field in a + with defining polynomial x^2 - 10 with a = 3.162277660168380? with basis (1, i, j, k) sage: A.quaternion_order([1,i/2,j,k]) Traceback (most recent call last): ... @@ -1508,7 +1527,8 @@ def gen(self, n): EXAMPLES:: sage: R = QuaternionAlgebra(-11,-1).maximal_order(); R - Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k) + Order of Quaternion Algebra (-11, -1) with base ring Rational Field + with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k) sage: R.gen(0) 1/2 + 1/2*i sage: R.gen(1) @@ -1649,20 +1669,23 @@ def intersection(self, other): sage: R = QuaternionAlgebra(-11,-1).maximal_order() sage: R.intersection(R) - Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1/2 + 1/2*i, i, 1/2*j + 1/2*k, k) + Order of Quaternion Algebra (-11, -1) with base ring Rational Field + with basis (1/2 + 1/2*i, i, 1/2*j + 1/2*k, k) We intersect various orders in the quaternion algebra ramified at 11:: sage: B = BrandtModule(11,3) sage: R = B.maximal_order(); S = B.order_of_level_N() sage: R.intersection(S) - Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 5/2*k, j, 3*k) + Order of Quaternion Algebra (-1, -11) with base ring Rational Field + with basis (1/2 + 1/2*j, 1/2*i + 5/2*k, j, 3*k) sage: R.intersection(S) == S True sage: B = BrandtModule(11,5) sage: T = B.order_of_level_N() sage: S.intersection(T) - Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 23/2*k, j, 15*k) + Order of Quaternion Algebra (-1, -11) with base ring Rational Field + with basis (1/2 + 1/2*j, 1/2*i + 23/2*k, j, 15*k) """ if not isinstance(other, QuaternionOrder): raise TypeError("other must be a QuaternionOrder") @@ -2021,7 +2044,8 @@ def scale(self, alpha, left=False): EXAMPLES:: - sage: B = BrandtModule(5,37); I = B.right_ideals()[0]; i,j,k = B.quaternion_algebra().gens(); I + sage: B = BrandtModule(5,37); I = B.right_ideals()[0] + sage: i,j,k = B.quaternion_algebra().gens(); I Fractional ideal (2 + 2*j + 106*k, i + 2*j + 105*k, 4*j + 64*k, 148*k) sage: I.scale(i) Fractional ideal (2*i + 212*j - 2*k, -2 + 210*j - 2*k, 128*j - 4*k, 296*j) @@ -2101,9 +2125,11 @@ def _compute_order(self, side='left'): sage: R. = QuaternionAlgebra(-1,-11) sage: I = R.ideal([2 + 2*j + 140*k, 2*i + 4*j + 150*k, 8*j + 104*k, 152*k]) sage: Ol = I._compute_order('left'); Ol - Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis (1/2 + 1/2*j + 35*k, 1/4*i + 1/2*j + 75/4*k, j + 32*k, 38*k) + Order of Quaternion Algebra (-1, -11) with base ring Rational Field + with basis (1/2 + 1/2*j + 35*k, 1/4*i + 1/2*j + 75/4*k, j + 32*k, 38*k) sage: Or = I._compute_order('right'); Or - Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis (1/2 + 1/2*j + 16*k, 1/2*i + 11/2*k, j + 13*k, 19*k) + Order of Quaternion Algebra (-1, -11) with base ring Rational Field + with basis (1/2 + 1/2*j + 16*k, 1/2*i + 11/2*k, j + 13*k, 19*k) sage: Ol.discriminant() 209 sage: Or.discriminant() @@ -2163,7 +2189,8 @@ def left_order(self): sage: R = B.maximal_order() sage: I = R.unit_ideal() sage: I.left_order() - Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k) + Order of Quaternion Algebra (-1, -11) with base ring Rational Field + with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k) We do a consistency check:: @@ -2186,9 +2213,11 @@ def right_order(self): sage: I = BrandtModule(389).right_ideals()[1]; I Fractional ideal (2 + 6*j + 2*k, i + 2*j + k, 8*j, 8*k) sage: I.right_order() - Order of Quaternion Algebra (-2, -389) with base ring Rational Field with basis (1/2 + 1/2*j + 1/2*k, 1/4*i + 1/2*j + 1/4*k, j, k) + Order of Quaternion Algebra (-2, -389) with base ring Rational Field + with basis (1/2 + 1/2*j + 1/2*k, 1/4*i + 1/2*j + 1/4*k, j, k) sage: I.left_order() - Order of Quaternion Algebra (-2, -389) with base ring Rational Field with basis (1/2 + 1/2*j + 3/2*k, 1/8*i + 1/4*j + 9/8*k, j + k, 2*k) + Order of Quaternion Algebra (-2, -389) with base ring Rational Field + with basis (1/2 + 1/2*j + 3/2*k, 1/8*i + 1/4*j + 9/8*k, j + k, 2*k) The following is a big consistency check. We take reps for all the right ideal classes of a certain order, take the @@ -2238,7 +2267,8 @@ def quaternion_order(self): sage: R = QuaternionAlgebra(-11,-1).maximal_order() sage: R.unit_ideal().quaternion_order() is R - doctest:...: DeprecationWarning: quaternion_order() is deprecated, please use left_order() or right_order() + doctest:...: DeprecationWarning: quaternion_order() is deprecated, + please use left_order() or right_order() See https://github.com/sagemath/sage/issues/31583 for details. True """ @@ -2838,31 +2868,47 @@ def cyclic_right_subideals(self, p, alpha=None): sage: B = BrandtModule(2,37); I = B.right_ideals()[0] sage: I.cyclic_right_subideals(3) - [Fractional ideal (2 + 2*i + 10*j + 90*k, 4*i + 4*j + 152*k, 12*j + 132*k, 444*k), Fractional ideal (2 + 2*i + 2*j + 150*k, 4*i + 8*j + 196*k, 12*j + 132*k, 444*k), Fractional ideal (2 + 2*i + 6*j + 194*k, 4*i + 8*j + 344*k, 12*j + 132*k, 444*k), Fractional ideal (2 + 2*i + 6*j + 46*k, 4*i + 4*j + 4*k, 12*j + 132*k, 444*k)] + [Fractional ideal (2 + 2*i + 10*j + 90*k, 4*i + 4*j + 152*k, 12*j + 132*k, 444*k), + Fractional ideal (2 + 2*i + 2*j + 150*k, 4*i + 8*j + 196*k, 12*j + 132*k, 444*k), + Fractional ideal (2 + 2*i + 6*j + 194*k, 4*i + 8*j + 344*k, 12*j + 132*k, 444*k), + Fractional ideal (2 + 2*i + 6*j + 46*k, 4*i + 4*j + 4*k, 12*j + 132*k, 444*k)] sage: B = BrandtModule(5,389); I = B.right_ideals()[0] sage: C = I.cyclic_right_subideals(3); C - [Fractional ideal (2 + 10*j + 546*k, i + 6*j + 133*k, 12*j + 3456*k, 4668*k), Fractional ideal (2 + 2*j + 2910*k, i + 6*j + 3245*k, 12*j + 3456*k, 4668*k), Fractional ideal (2 + i + 2295*k, 3*i + 2*j + 3571*k, 4*j + 2708*k, 4668*k), Fractional ideal (2 + 2*i + 2*j + 4388*k, 3*i + 2*j + 2015*k, 4*j + 4264*k, 4668*k)] + [Fractional ideal (2 + 10*j + 546*k, i + 6*j + 133*k, 12*j + 3456*k, 4668*k), + Fractional ideal (2 + 2*j + 2910*k, i + 6*j + 3245*k, 12*j + 3456*k, 4668*k), + Fractional ideal (2 + i + 2295*k, 3*i + 2*j + 3571*k, 4*j + 2708*k, 4668*k), + Fractional ideal (2 + 2*i + 2*j + 4388*k, 3*i + 2*j + 2015*k, 4*j + 4264*k, 4668*k)] sage: [(I.free_module()/J.free_module()).invariants() for J in C] [(3, 3), (3, 3), (3, 3), (3, 3)] sage: I.scale(3).cyclic_right_subideals(3) - [Fractional ideal (6 + 30*j + 1638*k, 3*i + 18*j + 399*k, 36*j + 10368*k, 14004*k), Fractional ideal (6 + 6*j + 8730*k, 3*i + 18*j + 9735*k, 36*j + 10368*k, 14004*k), Fractional ideal (6 + 3*i + 6885*k, 9*i + 6*j + 10713*k, 12*j + 8124*k, 14004*k), Fractional ideal (6 + 6*i + 6*j + 13164*k, 9*i + 6*j + 6045*k, 12*j + 12792*k, 14004*k)] + [Fractional ideal (6 + 30*j + 1638*k, 3*i + 18*j + 399*k, 36*j + 10368*k, 14004*k), + Fractional ideal (6 + 6*j + 8730*k, 3*i + 18*j + 9735*k, 36*j + 10368*k, 14004*k), + Fractional ideal (6 + 3*i + 6885*k, 9*i + 6*j + 10713*k, 12*j + 8124*k, 14004*k), + Fractional ideal (6 + 6*i + 6*j + 13164*k, 9*i + 6*j + 6045*k, 12*j + 12792*k, 14004*k)] sage: C = I.scale(1/9).cyclic_right_subideals(3); C - [Fractional ideal (2/9 + 10/9*j + 182/3*k, 1/9*i + 2/3*j + 133/9*k, 4/3*j + 384*k, 1556/3*k), Fractional ideal (2/9 + 2/9*j + 970/3*k, 1/9*i + 2/3*j + 3245/9*k, 4/3*j + 384*k, 1556/3*k), Fractional ideal (2/9 + 1/9*i + 255*k, 1/3*i + 2/9*j + 3571/9*k, 4/9*j + 2708/9*k, 1556/3*k), Fractional ideal (2/9 + 2/9*i + 2/9*j + 4388/9*k, 1/3*i + 2/9*j + 2015/9*k, 4/9*j + 4264/9*k, 1556/3*k)] + [Fractional ideal (2/9 + 10/9*j + 182/3*k, 1/9*i + 2/3*j + 133/9*k, 4/3*j + 384*k, 1556/3*k), + Fractional ideal (2/9 + 2/9*j + 970/3*k, 1/9*i + 2/3*j + 3245/9*k, 4/3*j + 384*k, 1556/3*k), + Fractional ideal (2/9 + 1/9*i + 255*k, 1/3*i + 2/9*j + 3571/9*k, 4/9*j + 2708/9*k, 1556/3*k), + Fractional ideal (2/9 + 2/9*i + 2/9*j + 4388/9*k, 1/3*i + 2/9*j + 2015/9*k, 4/9*j + 4264/9*k, 1556/3*k)] sage: [(I.scale(1/9).free_module()/J.free_module()).invariants() for J in C] [(3, 3), (3, 3), (3, 3), (3, 3)] sage: Q. = QuaternionAlgebra(-2,-5) sage: I = Q.ideal([Q(1),i,j,k]) sage: I.cyclic_right_subideals(3) - [Fractional ideal (1 + 2*j, i + k, 3*j, 3*k), Fractional ideal (1 + j, i + 2*k, 3*j, 3*k), Fractional ideal (1 + 2*i, 3*i, j + 2*k, 3*k), Fractional ideal (1 + i, 3*i, j + k, 3*k)] + [Fractional ideal (1 + 2*j, i + k, 3*j, 3*k), + Fractional ideal (1 + j, i + 2*k, 3*j, 3*k), + Fractional ideal (1 + 2*i, 3*i, j + 2*k, 3*k), + Fractional ideal (1 + i, 3*i, j + k, 3*k)] The general algorithm is not yet implemented here:: sage: I.cyclic_right_subideals(3)[0].cyclic_right_subideals(3) Traceback (most recent call last): ... - NotImplementedError: general algorithm not implemented (The given basis vectors must be linearly independent.) + NotImplementedError: general algorithm not implemented + (The given basis vectors must be linearly independent.) """ R = self.right_order() Q = self.quaternion_algebra() @@ -3075,7 +3121,8 @@ def normalize_basis_at_p(e, p, B=QuaternionAlgebraElement_abstract.pair): sage: A. = QuaternionAlgebra(-1,-7) sage: e = [A(1), k, j, 1/2 + 1/2*i + 1/2*j + 1/2*k] sage: normalize_basis_at_p(e, 2) - [(1, 0), (1/2 + 1/2*i + 1/2*j + 1/2*k, 0), (-34/105*i - 463/735*j + 71/105*k, 1), (-34/105*i - 463/735*j + 71/105*k, 1)] + [(1, 0), (1/2 + 1/2*i + 1/2*j + 1/2*k, 0), (-34/105*i - 463/735*j + 71/105*k, 1), + (-34/105*i - 463/735*j + 71/105*k, 1)] """ N = len(e) diff --git a/src/sage/algebras/quatalg/quaternion_algebra_element.pyx b/src/sage/algebras/quatalg/quaternion_algebra_element.pyx index a1dd86a224c..71188038aa9 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra_element.pyx +++ b/src/sage/algebras/quatalg/quaternion_algebra_element.pyx @@ -1658,8 +1658,8 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra EXAMPLES:: - sage: K. = QQ[2^(1/5)]; Q. = QuaternionAlgebra(K,-a,a*17/3) - sage: Q([a,-2/3,a^2-1/2,a*2]) # implicit doctest + sage: K. = QQ[2^(1/5)]; Q. = QuaternionAlgebra(K,-a,a*17/3) # optional - sage.symbolic + sage: Q([a,-2/3,a^2-1/2,a*2]) # implicit doctest # optional - sage.symbolic a + (-2/3)*i + (a^2 - 1/2)*j + 2*a*k """ fmpz_poly_init(self.x) @@ -1688,8 +1688,8 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra """ EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K,-a,a+1) - sage: Q([a,-2/3,a^2-1/2,a*2]) # implicit doctest + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K,-a,a+1) # optional - sage.symbolic + sage: Q([a,-2/3,a^2-1/2,a*2]) # implicit doctest # optional - sage.symbolic a + (-2/3)*i + (a^2 - 1/2)*j + 2*a*k """ self._parent = parent @@ -1732,21 +1732,21 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra """ EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K,-a,a+1) - sage: Q([a,-2/3,a^2-1/2,a*2]) + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K,-a,a+1) # optional - sage.symbolic + sage: Q([a,-2/3,a^2-1/2,a*2]) # optional - sage.symbolic a + (-2/3)*i + (a^2 - 1/2)*j + 2*a*k - sage: x = Q([a,-2/3,a^2-1/2,a*2]) - sage: type(x) + sage: x = Q([a,-2/3,a^2-1/2,a*2]) # optional - sage.symbolic + sage: type(x) # optional - sage.symbolic - sage: x[0] + sage: x[0] # optional - sage.symbolic a - sage: x[1] + sage: x[1] # optional - sage.symbolic -2/3 - sage: x[2] + sage: x[2] # optional - sage.symbolic a^2 - 1/2 - sage: x[3] + sage: x[3] # optional - sage.symbolic 2*a - sage: list(x) + sage: list(x) # optional - sage.symbolic [a, -2/3, a^2 - 1/2, 2*a] """ # general number -- this code assumes that the number field is not quadratic!! @@ -1773,13 +1773,13 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra """ EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) - sage: z = (i+j+k+a)^2; z + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) # optional - sage.symbolic + sage: z = (i+j+k+a)^2; z # optional - sage.symbolic a^2 + 4*a - 3 + 2*a*i + 2*a*j + 2*a*k - sage: f, t = z.__reduce__() - sage: f(*t) + sage: f, t = z.__reduce__() # optional - sage.symbolic + sage: f(*t) # optional - sage.symbolic a^2 + 4*a - 3 + 2*a*i + 2*a*j + 2*a*k - sage: loads(dumps(z)) == z + sage: loads(dumps(z)) == z # optional - sage.symbolic True """ return (unpickle_QuaternionAlgebraElement_number_field_v0, @@ -1791,11 +1791,12 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) - sage: z = a + i + (2/3)*a^3*j + (1+a)*k; w = a - i - (2/3)*a^3*j + (1/3+a)*k - sage: type(z) + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) # optional - sage.symbolic + sage: z = a + i + (2/3)*a^3*j + (1+a)*k # optional - sage.symbolic + sage: w = a - i - (2/3)*a^3*j + (1/3+a)*k # optional - sage.symbolic + sage: type(z) # optional - sage.symbolic - sage: z._add_(w) + sage: z._add_(w) # optional - sage.symbolic 2*a + (2*a + 4/3)*k Check that the fix in :trac:`17099` is correct:: @@ -1863,11 +1864,12 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) - sage: z = a + i + (2/3)*a^3*j + (1+a)*k; w = a - i - (2/3)*a^3*j + (1/3+a)*k - sage: type(z) + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) # optional - sage.symbolic + sage: z = a + i + (2/3)*a^3*j + (1+a)*k # optional - sage.symbolic + sage: w = a - i - (2/3)*a^3*j + (1/3+a)*k # optional - sage.symbolic + sage: type(z) # optional - sage.symbolic - sage: z._sub_(w) + sage: z._sub_(w) # optional - sage.symbolic 2*i + 8/3*j + 2/3*k """ # Implementation Note: To obtain _sub_, we simply replace every occurrence of @@ -1912,11 +1914,12 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) - sage: z = a + i + (2/3)*a^3*j + (1+a)*k; w = a - i - (2/3)*a^3*j + (1/3+a)*k - sage: type(z) + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) # optional - sage.symbolic + sage: z = a + i + (2/3)*a^3*j + (1+a)*k # optional - sage.symbolic + sage: w = a - i - (2/3)*a^3*j + (1/3+a)*k # optional - sage.symbolic + sage: type(z) # optional - sage.symbolic - sage: z._mul_(w) + sage: z._mul_(w) # optional - sage.symbolic 5*a^2 - 7/9*a + 9 + (-8/3*a^2 - 16/9*a)*i + (-6*a - 4)*j + (2*a^2 + 4/3*a)*k """ # We use the following formula for multiplication: @@ -2060,11 +2063,12 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra TESTS:: - sage: F = QQ[3^(1/3)] - sage: a = F.gen() - sage: K. = QuaternionAlgebra(F, -10 + a, -7 - a) - sage: ((1/4 + 1/2 * i + a^3/7 * j + a/28 * k)*14*i)^3 # implicit doctest - 34503/2*a^2 + 132195/2*a + 791399/4 + (203/8*a^2 - 10591*a + 169225/4)*i + (-84695/4*a^2 + 483413/8*a + 18591/4)*j + (-87/2*a^2 + 18156*a - 72525)*k + sage: F = QQ[3^(1/3)] # optional - sage.symbolic + sage: a = F.gen() # optional - sage.symbolic + sage: K. = QuaternionAlgebra(F, -10 + a, -7 - a) # optional - sage.symbolic + sage: ((1/4 + 1/2 * i + a^3/7 * j + a/28 * k)*14*i)^3 # implicit doctest # optional - sage.symbolic + 34503/2*a^2 + 132195/2*a + 791399/4 + (203/8*a^2 - 10591*a + 169225/4)*i + + (-84695/4*a^2 + 483413/8*a + 18591/4)*j + (-87/2*a^2 + 18156*a - 72525)*k """ # Note: this function changes the module-level global variables @@ -2137,11 +2141,11 @@ def unpickle_QuaternionAlgebraElement_number_field_v0(*args): """ EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a); z = i + j - sage: f, t = z.__reduce__() - sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a); z = i + j # optional - sage.symbolic + sage: f, t = z.__reduce__() # optional - sage.symbolic + sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) # optional - sage.symbolic i + j - sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) == z + sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) == z # optional - sage.symbolic True """ return QuaternionAlgebraElement_number_field(*args, check=False) diff --git a/src/sage/algebras/weyl_algebra.py b/src/sage/algebras/weyl_algebra.py index 48b1dee6075..efb148bb5b3 100644 --- a/src/sage/algebras/weyl_algebra.py +++ b/src/sage/algebras/weyl_algebra.py @@ -90,12 +90,12 @@ def repr_from_monomials(monomials, term_repr, use_latex=False): Leading minus signs are dealt with appropriately:: - sage: d = [(z, -4/7), (y, -sqrt(2)), (x, -5)] - sage: repr_from_monomials(d, lambda m: repr(m)) + sage: d = [(z, -4/7), (y, -sqrt(2)), (x, -5)] # optional - sage.symbolic + sage: repr_from_monomials(d, lambda m: repr(m)) # optional - sage.symbolic '-4/7*z - sqrt(2)*y - 5*x' - sage: a = repr_from_monomials(d, lambda m: latex(m), True); a + sage: a = repr_from_monomials(d, lambda m: latex(m), True); a # optional - sage.symbolic -\frac{4}{7} z - \sqrt{2} y - 5 x - sage: type(a) + sage: type(a) # optional - sage.symbolic Indirect doctests using a class that uses this function:: From c6b3d5719c0908ee7c102cff3d79403143a97cff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 1 Jun 2023 23:00:42 -0700 Subject: [PATCH 102/463] sage.algebras: Add # optional --- .../finite_dimensional_algebra.py | 321 +++++++++++------- .../finite_dimensional_algebra_element.pyx | 137 +++++--- .../finite_dimensional_algebra_morphism.py | 32 +- 3 files changed, 313 insertions(+), 177 deletions(-) diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py index af2b5e7dd3c..67625148ecd 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py @@ -57,22 +57,28 @@ class FiniteDimensionalAlgebra(UniqueRepresentation, Algebra): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]); A Finite-dimensional algebra of degree 2 over Finite Field of size 3 - sage: TestSuite(A).run() + sage: TestSuite(A).run() # optional - sage.rings.finite_rings - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B Finite-dimensional algebra of degree 3 over Rational Field TESTS:: - sage: A.category() - Category of finite dimensional magmatic algebras with basis over Finite Field of size 3 - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])], assume_associative=True) - sage: A.category() - Category of finite dimensional associative algebras with basis over Finite Field of size 3 + sage: A.category() # optional - sage.rings.finite_rings + Category of finite dimensional magmatic algebras with basis + over Finite Field of size 3 + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])], + ....: assume_associative=True) + sage: A.category() # optional - sage.rings.finite_rings + Category of finite dimensional associative algebras with basis + over Finite Field of size 3 """ @staticmethod def __classcall_private__(cls, k, table, names='e', assume_associative=False, @@ -83,46 +89,47 @@ def __classcall_private__(cls, k, table, names='e', assume_associative=False, TESTS:: sage: table = [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])] - sage: A1 = FiniteDimensionalAlgebra(GF(3), table) - sage: A2 = FiniteDimensionalAlgebra(GF(3), table, names='e') - sage: A3 = FiniteDimensionalAlgebra(GF(3), table, names=['e0', 'e1']) - sage: A1 is A2 and A2 is A3 + sage: A1 = FiniteDimensionalAlgebra(GF(3), table) # optional - sage.rings.finite_rings + sage: A2 = FiniteDimensionalAlgebra(GF(3), table, names='e') # optional - sage.rings.finite_rings + sage: A3 = FiniteDimensionalAlgebra(GF(3), table, names=['e0', 'e1']) # optional - sage.rings.finite_rings + sage: A1 is A2 and A2 is A3 # optional - sage.rings.finite_rings True The ``assume_associative`` keyword is built into the category:: sage: from sage.categories.magmatic_algebras import MagmaticAlgebras - sage: cat = MagmaticAlgebras(GF(3)).FiniteDimensional().WithBasis() - sage: A1 = FiniteDimensionalAlgebra(GF(3), table, category=cat.Associative()) - sage: A2 = FiniteDimensionalAlgebra(GF(3), table, assume_associative=True) - sage: A1 is A2 + sage: cat = MagmaticAlgebras(GF(3)).FiniteDimensional().WithBasis() # optional - sage.rings.finite_rings + sage: A1 = FiniteDimensionalAlgebra(GF(3), table, # optional - sage.rings.finite_rings + ....: category=cat.Associative()) + sage: A2 = FiniteDimensionalAlgebra(GF(3), table, assume_associative=True) # optional - sage.rings.finite_rings + sage: A1 is A2 # optional - sage.rings.finite_rings True Uniqueness depends on the category:: - sage: cat = Algebras(GF(3)).FiniteDimensional().WithBasis() - sage: A1 = FiniteDimensionalAlgebra(GF(3), table) - sage: A2 = FiniteDimensionalAlgebra(GF(3), table, category=cat) - sage: A1 == A2 + sage: cat = Algebras(GF(3)).FiniteDimensional().WithBasis() # optional - sage.rings.finite_rings + sage: A1 = FiniteDimensionalAlgebra(GF(3), table) # optional - sage.rings.finite_rings + sage: A2 = FiniteDimensionalAlgebra(GF(3), table, category=cat) # optional - sage.rings.finite_rings + sage: A1 == A2 # optional - sage.rings.finite_rings False - sage: A1 is A2 + sage: A1 is A2 # optional - sage.rings.finite_rings False Checking that equality is still as expected:: - sage: A = FiniteDimensionalAlgebra(GF(3), table) - sage: B = FiniteDimensionalAlgebra(GF(5), [Matrix([0])]) - sage: A == A + sage: A = FiniteDimensionalAlgebra(GF(3), table) # optional - sage.rings.finite_rings + sage: B = FiniteDimensionalAlgebra(GF(5), [Matrix([0])]) # optional - sage.rings.finite_rings + sage: A == A # optional - sage.rings.finite_rings True - sage: B == B + sage: B == B # optional - sage.rings.finite_rings True - sage: A == B + sage: A == B # optional - sage.rings.finite_rings False - sage: A != A + sage: A != A # optional - sage.rings.finite_rings False - sage: B != B + sage: B != B # optional - sage.rings.finite_rings False - sage: A != B + sage: A != B # optional - sage.rings.finite_rings True """ n = len(table) @@ -154,17 +161,17 @@ def __init__(self, k, table, names='e', category=None): sage: TestSuite(A).run() - sage: B = FiniteDimensionalAlgebra(GF(7), [Matrix([1])]) - sage: B + sage: B = FiniteDimensionalAlgebra(GF(7), [Matrix([1])]) # optional - sage.rings.finite_rings + sage: B # optional - sage.rings.finite_rings Finite-dimensional algebra of degree 1 over Finite Field of size 7 - sage: TestSuite(B).run() + sage: TestSuite(B).run() # optional - sage.rings.finite_rings sage: C = FiniteDimensionalAlgebra(CC, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: C Finite-dimensional algebra of degree 2 over Complex Field with 53 bits of precision sage: TestSuite(C).run() - sage: FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]])]) + sage: FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]])]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: input is not a multiplication table @@ -197,14 +204,15 @@ def _coerce_map_from_(self, S): """ TESTS:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.has_coerce_map_from(ZZ) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: A.has_coerce_map_from(ZZ) # optional - sage.rings.finite_rings True - sage: A.has_coerce_map_from(GF(3)) + sage: A.has_coerce_map_from(GF(3)) # optional - sage.rings.finite_rings True - sage: A.has_coerce_map_from(GF(5)) + sage: A.has_coerce_map_from(GF(5)) # optional - sage.rings.finite_rings False - sage: A.has_coerce_map_from(QQ) + sage: A.has_coerce_map_from(QQ) # optional - sage.rings.finite_rings False """ return S == self or (self.base_ring().has_coerce_map_from(S) and self.is_unitary()) @@ -224,7 +232,9 @@ def _element_constructor_(self, x): ... TypeError: algebra is not unitary - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(17) 17*e0 + 17*e2 """ @@ -243,7 +253,9 @@ def _Hom_(self, B, category): sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: A._Hom_(B, A.category()) - Set of Homomorphisms from Finite-dimensional algebra of degree 1 over Rational Field to Finite-dimensional algebra of degree 2 over Rational Field + Set of Homomorphisms + from Finite-dimensional algebra of degree 1 over Rational Field + to Finite-dimensional algebra of degree 2 over Rational Field """ cat = MagmaticAlgebras(self.base_ring()).FiniteDimensional().WithBasis() if category.is_subcategory(cat): @@ -258,8 +270,9 @@ def ngens(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.ngens() + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: A.ngens() # optional - sage.rings.finite_rings 2 """ return len(self._table) @@ -273,8 +286,9 @@ def gen(self, i): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.gen(0) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: A.gen(0) # optional - sage.rings.finite_rings e0 """ return self.element_class(self, [j == i for j in range(self.ngens())]) @@ -286,8 +300,9 @@ def basis(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.basis() + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: A.basis() # optional - sage.rings.finite_rings Family (e0, e1) """ from sage.sets.family import Family @@ -299,8 +314,9 @@ def __iter__(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: list(A) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: list(A) # optional - sage.rings.finite_rings [0, e0, 2*e0, e1, e0 + e1, 2*e0 + e1, 2*e1, e0 + 2*e1, 2*e0 + 2*e1] This is used in the :class:`Testsuite`'s when ``self`` is @@ -319,8 +335,9 @@ def _ideal_class_(self, n=0): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A._ideal_class_() + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: A._ideal_class_() # optional - sage.rings.finite_rings """ return FiniteDimensionalAlgebraIdeal @@ -332,8 +349,9 @@ def table(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.table() + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: A.table() # optional - sage.rings.finite_rings ( [1 0] [0 1] [0 1], [0 0] @@ -349,7 +367,8 @@ def left_table(self): EXAMPLES:: - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1],[-1,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [-1,0]])]) sage: T = B.left_table(); T ( [1 0] [ 0 1] @@ -381,9 +400,9 @@ def base_extend(self, F): EXAMPLES:: - sage: C = FiniteDimensionalAlgebra(GF(2), [Matrix([1])]) - sage: k. = GF(4) - sage: C.base_extend(k) + sage: C = FiniteDimensionalAlgebra(GF(2), [Matrix([1])]) # optional - sage.rings.finite_rings + sage: k. = GF(4) # optional - sage.rings.finite_rings + sage: C.base_extend(k) # optional - sage.rings.finite_rings Finite-dimensional algebra of degree 1 over Finite Field in y of size 2^2 """ # Base extension of the multiplication table is done by __classcall_private__. @@ -395,11 +414,13 @@ def cardinality(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) - sage: A.cardinality() + sage: A = FiniteDimensionalAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [2, 3]])]) + sage: A.cardinality() # optional - sage.rings.finite_rings 49 - sage: B = FiniteDimensionalAlgebra(RR, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) + sage: B = FiniteDimensionalAlgebra(RR, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [2, 3]])]) sage: B.cardinality() +Infinity @@ -431,9 +452,11 @@ def ideal(self, gens=None, given_by_matrix=False, side=None): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.ideal(A([1,1])) - Ideal (e0 + e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3 + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: A.ideal(A([1,1])) # optional - sage.rings.finite_rings + Ideal (e0 + e1) of + Finite-dimensional algebra of degree 2 over Finite Field of size 3 """ return self._ideal_class_()(self, gens=gens, given_by_matrix=given_by_matrix) @@ -445,11 +468,14 @@ def is_associative(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1],[-1,0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [-1,0]])]) sage: A.is_associative() True - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,1], [0,0,0], [1,0,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,1], [0,0,0], [1,0,0]])]) sage: B.is_associative() False @@ -473,11 +499,15 @@ def is_commutative(self): EXAMPLES:: - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B.is_commutative() True - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: C.is_commutative() False """ @@ -495,11 +525,13 @@ def is_finite(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) - sage: A.is_finite() + sage: A = FiniteDimensionalAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [2, 3]])]) + sage: A.is_finite() # optional - sage.rings.finite_rings True - sage: B = FiniteDimensionalAlgebra(RR, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [2, 3]])]) + sage: B = FiniteDimensionalAlgebra(RR, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [2, 3]])]) sage: B.is_finite() False @@ -526,27 +558,35 @@ def is_unitary(self): sage: A.is_unitary() True - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [-1,0]])]) sage: B.is_unitary() True - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[0,0], [0,0]]), Matrix([[0,0], [0,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[0,0], [0,0]]), + ....: Matrix([[0,0], [0,0]])]) sage: C.is_unitary() False - sage: D = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[1,0], [0,1]])]) + sage: D = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[1,0], [0,1]])]) sage: D.is_unitary() False - sage: E = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0],[1,0]]), Matrix([[0,1],[0,1]])]) + sage: E = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0],[1,0]]), + ....: Matrix([[0,1],[0,1]])]) sage: E.is_unitary() False - sage: F = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,1], [0,0,0], [1,0,0]])]) + sage: F = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,1], [0,0,0], [1,0,0]])]) sage: F.is_unitary() True - sage: G = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [1,0,0]])]) + sage: G = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [1,0,0]])]) sage: G.is_unitary() # Unique right identity, but no left identity. False """ @@ -583,8 +623,8 @@ def is_zero(self): sage: A.is_zero() True - sage: B = FiniteDimensionalAlgebra(GF(7), [Matrix([0])]) - sage: B.is_zero() + sage: B = FiniteDimensionalAlgebra(GF(7), [Matrix([0])]) # optional - sage.rings.finite_rings + sage: B.is_zero() # optional - sage.rings.finite_rings False """ return self.degree() == 0 @@ -600,21 +640,27 @@ def one(self): sage: A.one() 0 - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [-1,0]])]) sage: B.one() e0 - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[0,0], [0,0]]), Matrix([[0,0], [0,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[0,0], [0,0]]), + ....: Matrix([[0,0], [0,0]])]) sage: C.one() Traceback (most recent call last): ... TypeError: algebra is not unitary - sage: D = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,1], [0,0,0], [1,0,0]])]) + sage: D = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,1], [0,0,0], [1,0,0]])]) sage: D.one() e0 - sage: E = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [1,0,0]])]) + sage: E = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,1]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [1,0,0]])]) sage: E.one() Traceback (most recent call last): ... @@ -634,11 +680,14 @@ def random_element(self, *args, **kwargs): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.random_element() # random + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: A.random_element() # random # optional - sage.rings.finite_rings e0 + 2*e1 - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B.random_element(num_bound=1000) # random 215/981*e0 + 709/953*e1 + 931/264*e2 """ @@ -648,32 +697,39 @@ def _is_valid_homomorphism_(self, other, im_gens, base_map=None): """ TESTS:: - sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [0, 0]])]) sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) sage: Hom(A, B)(Matrix([[1], [0]])) - Morphism from Finite-dimensional algebra of degree 2 over Rational Field to Finite-dimensional algebra of degree 1 over Rational Field given by matrix + Morphism from Finite-dimensional algebra of degree 2 over Rational Field + to Finite-dimensional algebra of degree 1 over Rational Field given by matrix [1] [0] sage: Hom(B, A)(Matrix([[1, 0]])) - Morphism from Finite-dimensional algebra of degree 1 over Rational Field to Finite-dimensional algebra of degree 2 over Rational Field given by matrix + Morphism from Finite-dimensional algebra of degree 1 over Rational Field + to Finite-dimensional algebra of degree 2 over Rational Field given by matrix [1 0] sage: H = Hom(A, A) sage: H(Matrix.identity(QQ, 2)) - Morphism from Finite-dimensional algebra of degree 2 over Rational Field to Finite-dimensional algebra of degree 2 over Rational Field given by matrix + Morphism from Finite-dimensional algebra of degree 2 over Rational Field + to Finite-dimensional algebra of degree 2 over Rational Field given by matrix [1 0] [0 1] sage: H(Matrix([[1, 0], [0, 0]])) - Morphism from Finite-dimensional algebra of degree 2 over Rational Field to Finite-dimensional algebra of degree 2 over Rational Field given by matrix + Morphism from Finite-dimensional algebra of degree 2 over Rational Field + to Finite-dimensional algebra of degree 2 over Rational Field given by matrix [1 0] [0 0] sage: H(Matrix([[1, 0], [1, 1]])) 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: Hom(B, B)(Matrix([[2]])) 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 """ assert len(im_gens) == self.degree() @@ -694,7 +750,7 @@ def quotient_map(self, ideal): INPUT: - - ``ideal`` -- a ``FiniteDimensionalAlgebraIdeal`` + - ``ideal`` -- a :class:`FiniteDimensionalAlgebraIdeal` OUTPUT: @@ -703,17 +759,22 @@ def quotient_map(self, ideal): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: q0 = A.quotient_map(A.zero_ideal()) - sage: q0 - Morphism from Finite-dimensional algebra of degree 2 over Finite Field of size 3 to Finite-dimensional algebra of degree 2 over Finite Field of size 3 given by matrix - [1 0] - [0 1] - sage: q1 = A.quotient_map(A.ideal(A.gen(1))) - sage: q1 - Morphism from Finite-dimensional algebra of degree 2 over Finite Field of size 3 to Finite-dimensional algebra of degree 1 over Finite Field of size 3 given by matrix - [1] - [0] + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: q0 = A.quotient_map(A.zero_ideal()); q0 # optional - sage.rings.finite_rings + Morphism + from Finite-dimensional algebra of degree 2 over Finite Field of size 3 + to Finite-dimensional algebra of degree 2 over Finite Field of size 3 + given by matrix + [1 0] + [0 1] + sage: q1 = A.quotient_map(A.ideal(A.gen(1))); q1 # optional - sage.rings.finite_rings + Morphism + from Finite-dimensional algebra of degree 2 over Finite Field of size 3 + to Finite-dimensional algebra of degree 1 over Finite Field of size 3 + given by matrix + [1] + [0] """ k = self.base_ring() f = ideal.basis_matrix().transpose().kernel().basis_matrix().echelon_form().transpose() @@ -744,11 +805,15 @@ def maximal_ideal(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.maximal_ideal() - Ideal (0, e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3 + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: A.maximal_ideal() # optional - sage.rings.finite_rings + Ideal (0, e1) of + Finite-dimensional algebra of degree 2 over Finite Field of size 3 - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B.maximal_ideal() Traceback (most recent call last): ... @@ -783,18 +848,31 @@ def primary_decomposition(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.primary_decomposition() - [Morphism from Finite-dimensional algebra of degree 2 over Finite Field of size 3 to Finite-dimensional algebra of degree 2 over Finite Field of size 3 given by matrix [1 0] - [0 1]] - - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: A.primary_decomposition() # optional - sage.rings.finite_rings + [Morphism + from Finite-dimensional algebra of degree 2 over Finite Field of size 3 + to Finite-dimensional algebra of degree 2 over Finite Field of size 3 + given by matrix [1 0] + [0 1]] + + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B.primary_decomposition() - [Morphism from Finite-dimensional algebra of degree 3 over Rational Field to Finite-dimensional algebra of degree 1 over Rational Field given by matrix [0] - [0] - [1], Morphism from Finite-dimensional algebra of degree 3 over Rational Field to Finite-dimensional algebra of degree 2 over Rational Field given by matrix [1 0] - [0 1] - [0 0]] + [Morphism + from Finite-dimensional algebra of degree 3 over Rational Field + to Finite-dimensional algebra of degree 1 over Rational Field + given by matrix [0] + [0] + [1], + Morphism + from Finite-dimensional algebra of degree 3 over Rational Field + to Finite-dimensional algebra of degree 2 over Rational Field + given by matrix [1 0] + [0 1] + [0 0]] """ k = self.base_ring() n = self.degree() @@ -838,8 +916,9 @@ def maximal_ideals(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) - sage: A.maximal_ideals() + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0, 1], [0, 0]])]) + sage: A.maximal_ideals() # optional - sage.rings.finite_rings [Ideal (e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3] sage: B = FiniteDimensionalAlgebra(QQ, []) diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx index e4901439e19..d0724bca028 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx @@ -26,7 +26,9 @@ cpdef FiniteDimensionalAlgebraElement unpickle_FiniteDimensionalAlgebraElement(A TESTS:: - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[1,1,0], [0,1,1], [0,1,1]]), Matrix([[0,0,1], [0,1,0], [1,0,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[1,1,0], [0,1,1], [0,1,1]]), + ....: Matrix([[0,0,1], [0,1,0], [1,0,0]])]) sage: x = B([1,2,3]) sage: loads(dumps(x)) == x # indirect doctest True @@ -59,23 +61,26 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) - sage: A(17) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0,1], [0,0]])]) + sage: A(17) # optional - sage.rings.finite_rings 2*e0 - sage: A([1,1]) + sage: A([1,1]) # optional - sage.rings.finite_rings e0 + e1 """ def __init__(self, A, elt=None, check=True): """ TESTS:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) - sage: A(QQ(4)) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0,1], [0,0]])]) + sage: A(QQ(4)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: elt should be a vector, a matrix, or an element of the base field - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [-1,0]])]) sage: elt = B(Matrix([[1,1], [-1,1]])); elt e0 + e1 sage: TestSuite(elt).run() @@ -133,7 +138,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ TESTS:: - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[1,1,0], [0,1,1], [0,1,1]]), Matrix([[0,0,1], [0,1,0], [1,0,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[1,1,0], [0,1,1], [0,1,1]]), + ....: Matrix([[0,0,1], [0,1,0], [1,0,0]])]) sage: x = B([1,2,3]) sage: loads(dumps(x)) == x # indirect doctest True @@ -149,7 +156,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): TESTS:: - sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: x = A.element_class.__new__(A.element_class) sage: x.__setstate__((A, {'_vector':vector([1,1,1]), '_matrix':matrix(QQ,3,[1,1,0, 0,1,0, 0,0,1])})) sage: x @@ -183,7 +192,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ TESTS:: - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[1,1,0], [0,1,1], [0,1,1]]), Matrix([[0,0,1], [0,1,0], [1,0,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[1,1,0], [0,1,1], [0,1,1]]), + ....: Matrix([[0,0,1], [0,1,0], [1,0,0]])]) sage: x = B([1,2,3]) sage: x._matrix [3 2 3] @@ -205,7 +216,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(5).vector() (5, 0, 5) """ @@ -220,7 +233,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(5).matrix() [5 0 0] [0 5 0] @@ -240,7 +255,8 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [-1,0]])]) sage: elt = B(Matrix([[1,1], [-1,1]])) sage: elt.monomial_coefficients() {0: 1, 1: 1} @@ -254,7 +270,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: C([1,2,0]).left_matrix() [1 0 0] [0 1 0] @@ -272,8 +290,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) - sage: A(1) + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0,1], [0,0]])]) + sage: A(1) # optional - sage.rings.finite_rings e0 """ s = " " @@ -308,8 +327,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) - sage: latex(A(1)) # indirect doctest + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0,1], [0,0]])]) + sage: latex(A(1)) # indirect doctest # optional - sage.rings.finite_rings \left(\begin{array}{rr} 1 & 0 \\ 0 & 1 @@ -324,7 +344,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: A([2,1/4,3])[2] 3 """ @@ -334,7 +356,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: len(A([2,1/4,3])) 3 """ @@ -345,15 +369,18 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) - sage: A(2) == 2 + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0,1], [0,0]])]) + sage: A(2) == 2 # optional - sage.rings.finite_rings True - sage: A(2) == 3 + sage: A(2) == 3 # optional - sage.rings.finite_rings False - sage: A(2) == GF(5)(2) + sage: A(2) == GF(5)(2) # optional - sage.rings.finite_rings False - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(1) != 0 True @@ -362,13 +389,13 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): the algebra corresponds to the standard monomials of the relation ideal, when the algebra is considered as a quotient of a path algebra. :: - sage: A(1) > 0 + sage: A(1) > 0 # optional - sage.rings.finite_rings True - sage: A(1) < 0 + sage: A(1) < 0 # optional - sage.rings.finite_rings False - sage: A(1) >= 0 + sage: A(1) >= 0 # optional - sage.rings.finite_rings True - sage: A(1) <= 0 + sage: A(1) <= 0 # optional - sage.rings.finite_rings False """ return richcmp(self._vector, right._vector, op) @@ -377,8 +404,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) - sage: A.basis()[0] + A.basis()[1] + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0,1], [0,0]])]) + sage: A.basis()[0] + A.basis()[1] # optional - sage.rings.finite_rings e0 + e1 """ return self._parent.element_class(self._parent, self._vector + other._vector) @@ -387,8 +415,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) - sage: A.basis()[0] - A.basis()[1] + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + ....: Matrix([[0,1], [0,0]])]) + sage: A.basis()[0] - A.basis()[1] # optional - sage.rings.finite_rings e0 + 2*e1 """ return self._parent.element_class(self._parent, self._vector - other._vector) @@ -397,7 +426,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ EXAMPLES:: - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: C.basis()[1] * C.basis()[2] e1 """ @@ -407,7 +438,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ TESTS:: - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: c = C.random_element() sage: c * 2 == c + c True @@ -421,7 +454,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ TESTS:: - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,1,0], [0,0,1]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,1,0], [0,0,1]])]) sage: c = C.random_element() sage: 2 * c == c + c True @@ -438,7 +473,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: b = B([2,3,4]) sage: b^6 64*e0 + 576*e1 + 4096*e2 @@ -459,7 +496,8 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ TESTS:: - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [-1,0]])]) sage: x = C([1,2]) sage: y = ~x; y # indirect doctest 1/5*e0 - 2/5*e1 @@ -486,7 +524,8 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [-1,0]])]) sage: C([1,2]).is_invertible() True sage: C(0).is_invertible() @@ -505,7 +544,8 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [-1,0]])]) sage: C([1,2])._inverse 1/5*e0 - 2/5*e1 sage: C(0)._inverse is None @@ -543,7 +583,8 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [-1,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [-1,0]])]) sage: C([1,2]).inverse() 1/5*e0 - 2/5*e1 """ @@ -561,7 +602,8 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [0,0]])]) sage: C([1,0]).is_zerodivisor() False sage: C([0,1]).is_zerodivisor() @@ -575,7 +617,8 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), Matrix([[0,1], [0,0]])]) + sage: C = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]), + ....: Matrix([[0,1], [0,0]])]) sage: C([1,0]).is_nilpotent() False sage: C([0,1]).is_nilpotent() @@ -596,7 +639,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(0).minimal_polynomial() x sage: b = B.random_element() @@ -625,7 +670,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), Matrix([[0,1,0], [0,0,0], [0,0,0]]), Matrix([[0,0,0], [0,0,0], [0,0,1]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), + ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), + ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) sage: B(0).characteristic_polynomial() x^3 sage: b = B.random_element() diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py index 22f12ce6bb5..eea375c01d0 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py @@ -41,7 +41,8 @@ class FiniteDimensionalAlgebraMorphism(RingHomomorphism_im_gens): EXAMPLES:: sage: from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_morphism import FiniteDimensionalAlgebraMorphism - sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [0, 0]])]) sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) sage: H = Hom(A, B) sage: f = H(Matrix([[1], [0]])) @@ -62,7 +63,8 @@ def __init__(self, parent, f, check=True, unitary=True): sage: from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_morphism import FiniteDimensionalAlgebraMorphism sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: phi = FiniteDimensionalAlgebraMorphism(H, Matrix([[1, 0]])) sage: TestSuite(phi).run(skip="_test_category") @@ -82,7 +84,8 @@ def _repr_(self): r""" TESTS:: - sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [0, 0]])]) sage: I = A.maximal_ideal() sage: q = A.quotient_map(I) sage: q._repr_() @@ -95,7 +98,8 @@ def __call__(self, x): """ TESTS:: - sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [0, 0]])]) sage: I = A.maximal_ideal() sage: q = A.quotient_map(I) sage: q(0) == 0 and q(1) == 1 @@ -112,7 +116,8 @@ def __eq__(self, other): TESTS:: sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: phi = H(Matrix([[1, 0]])) sage: psi = H(Matrix([[1, 0]])) @@ -132,7 +137,8 @@ def __ne__(self, other): TESTS:: sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: phi = H(Matrix([[1, 0]])) sage: psi = H(Matrix([[1, 0]])) @@ -149,7 +155,8 @@ def matrix(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [0, 0]])]) sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) sage: M = Matrix([[1], [0]]) sage: H = Hom(A, B) @@ -169,11 +176,12 @@ def inverse_image(self, I): OUTPUT: - -- ``FiniteDimensionalAlgebraIdeal``, the inverse image of `I` under ``self``. + :class:`FiniteDimensionalAlgebraIdeal`, the inverse image of `I` under ``self``. EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [0, 0]])]) sage: I = A.maximal_ideal() sage: q = A.quotient_map(I) sage: B = q.codomain() @@ -195,7 +203,8 @@ def zero(self): EXAMPLES:: sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: H.zero() Morphism from Finite-dimensional algebra of degree 1 over Rational Field to @@ -218,7 +227,8 @@ def __call__(self, f, check=True, unitary=True): EXAMPLES:: sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([1])]) - sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) + sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), + ....: Matrix([[0, 1], [0, 0]])]) sage: H = Hom(A, B) sage: H(Matrix([[1, 0]])) Morphism from Finite-dimensional algebra of degree 1 over Rational Field to From 6b25b45e0e3df18a37a9f12b610f3d0b1273992e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 3 Jun 2023 17:00:52 -0700 Subject: [PATCH 103/463] sage.algebras: Modularization fixes --- .../algebras/affine_nil_temperley_lieb.py | 1 + src/sage/algebras/algebra.py | 1 + src/sage/algebras/askey_wilson.py | 1 + src/sage/algebras/associated_graded.py | 1 + src/sage/algebras/catalog.py | 21 +- src/sage/algebras/cellular_basis.py | 1 + src/sage/algebras/clifford_algebra.py | 1 + .../algebras/clifford_algebra_element.pyx | 1 + src/sage/algebras/cluster_algebra.py | 8 +- src/sage/algebras/commutative_dga.py | 363 +++++++++++------- src/sage/algebras/down_up_algebra.py | 1 + .../algebras/exterior_algebra_groebner.pyx | 1 + src/sage/algebras/finite_gca.py | 1 + src/sage/algebras/free_algebra.py | 197 +++++----- src/sage/algebras/free_algebra_element.py | 2 +- src/sage/algebras/free_algebra_quotient.py | 31 +- .../algebras/free_algebra_quotient_element.py | 1 + src/sage/algebras/free_zinbiel_algebra.py | 27 +- src/sage/algebras/group_algebra.py | 1 + src/sage/algebras/hall_algebra.py | 1 + src/sage/algebras/iwahori_hecke_algebra.py | 1 + src/sage/algebras/nil_coxeter_algebra.py | 1 + src/sage/algebras/octonion_algebra.pyx | 1 + src/sage/algebras/orlik_solomon.py | 119 +++--- src/sage/algebras/orlik_terao.py | 1 + src/sage/algebras/q_commuting_polynomials.py | 1 + src/sage/algebras/q_system.py | 2 +- src/sage/algebras/quantum_clifford.py | 1 + .../algebras/quantum_groups/fock_space.py | 2 +- .../quantum_matrix_coordinate_algebra.py | 1 + src/sage/algebras/quaternion_algebra.py | 2 + .../algebras/quaternion_algebra_element.py | 2 + .../algebras/rational_cherednik_algebra.py | 1 + src/sage/algebras/schur_algebra.py | 1 + src/sage/algebras/shuffle_algebra.py | 2 +- src/sage/algebras/splitting_algebra.py | 2 +- .../algebras/steenrod/steenrod_algebra.py | 2 +- .../steenrod/steenrod_algebra_bases.py | 22 +- src/sage/algebras/tensor_algebra.py | 1 + src/sage/algebras/weyl_algebra.py | 1 + src/sage/algebras/yangian.py | 1 + src/sage/algebras/yokonuma_hecke_algebra.py | 1 + 42 files changed, 478 insertions(+), 352 deletions(-) diff --git a/src/sage/algebras/affine_nil_temperley_lieb.py b/src/sage/algebras/affine_nil_temperley_lieb.py index 720c5f481cd..8f88e2bb3b7 100644 --- a/src/sage/algebras/affine_nil_temperley_lieb.py +++ b/src/sage/algebras/affine_nil_temperley_lieb.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Affine nilTemperley Lieb Algebra of type A """ diff --git a/src/sage/algebras/algebra.py b/src/sage/algebras/algebra.py index 5aac6f22b9a..547eee6c699 100644 --- a/src/sage/algebras/algebra.py +++ b/src/sage/algebras/algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Abstract base class for algebras """ diff --git a/src/sage/algebras/askey_wilson.py b/src/sage/algebras/askey_wilson.py index 37303e030c3..1d597987c60 100644 --- a/src/sage/algebras/askey_wilson.py +++ b/src/sage/algebras/askey_wilson.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Askey-Wilson Algebras diff --git a/src/sage/algebras/associated_graded.py b/src/sage/algebras/associated_graded.py index 5e9d7b1f6b9..9afb563923b 100644 --- a/src/sage/algebras/associated_graded.py +++ b/src/sage/algebras/associated_graded.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Associated Graded Algebras To Filtered Algebras diff --git a/src/sage/algebras/catalog.py b/src/sage/algebras/catalog.py index efda74ed00e..ec48a6debed 100644 --- a/src/sage/algebras/catalog.py +++ b/src/sage/algebras/catalog.py @@ -84,17 +84,18 @@ ` """ -from sage.algebras.free_algebra import FreeAlgebra as Free -from sage.algebras.quatalg.quaternion_algebra import QuaternionAlgebra as Quaternion -from sage.algebras.steenrod.steenrod_algebra import SteenrodAlgebra as Steenrod -from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra import FiniteDimensionalAlgebra as FiniteDimensional -from sage.algebras.group_algebra import GroupAlgebra as Group -from sage.algebras.clifford_algebra import CliffordAlgebra as Clifford -from sage.algebras.clifford_algebra import ExteriorAlgebra as Exterior -from sage.algebras.weyl_algebra import DifferentialWeylAlgebra as DifferentialWeyl -from sage.algebras.lie_algebras.lie_algebra import LieAlgebra as Lie - from sage.misc.lazy_import import lazy_import +lazy_import('sage.algebras.free_algebra', 'FreeAlgebra', as_='Free') +lazy_import('sage.algebras.quatalg.quaternion_algebra', 'QuaternionAlgebra', as_='Quaternion') +lazy_import('sage.algebras.steenrod.steenrod_algebra', 'SteenrodAlgebra', as_='Steenrod') +lazy_import('sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra', + 'FiniteDimensionalAlgebra', as_='FiniteDimensional') +lazy_import('sage.algebras.group_algebra', 'GroupAlgebra', as_='Group') +lazy_import('sage.algebras.clifford_algebra', 'CliffordAlgebra', as_='Clifford') +lazy_import('sage.algebras.clifford_algebra', 'ExteriorAlgebra', as_='Exterior') +lazy_import('sage.algebras.weyl_algebra', 'DifferentialWeylAlgebra', as_='DifferentialWeyl') +lazy_import('sage.algebras.lie_algebras.lie_algebra', 'LieAlgebra', as_='Lie') + lazy_import('sage.algebras.iwahori_hecke_algebra', 'IwahoriHeckeAlgebra', 'IwahoriHecke') lazy_import('sage.algebras.nil_coxeter_algebra', 'NilCoxeterAlgebra', 'NilCoxeter') lazy_import('sage.algebras.free_zinbiel_algebra', 'FreeZinbielAlgebra', 'FreeZinbiel') diff --git a/src/sage/algebras/cellular_basis.py b/src/sage/algebras/cellular_basis.py index 873bd899b3e..62aeaa03bdd 100644 --- a/src/sage/algebras/cellular_basis.py +++ b/src/sage/algebras/cellular_basis.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Cellular Basis ============== diff --git a/src/sage/algebras/clifford_algebra.py b/src/sage/algebras/clifford_algebra.py index adb065e31b7..7d517534792 100644 --- a/src/sage/algebras/clifford_algebra.py +++ b/src/sage/algebras/clifford_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Clifford Algebras diff --git a/src/sage/algebras/clifford_algebra_element.pyx b/src/sage/algebras/clifford_algebra_element.pyx index 0a1a4adb681..fc70360dab3 100644 --- a/src/sage/algebras/clifford_algebra_element.pyx +++ b/src/sage/algebras/clifford_algebra_element.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules """ Clifford algebra elements diff --git a/src/sage/algebras/cluster_algebra.py b/src/sage/algebras/cluster_algebra.py index 14669dfed5c..8a468dad0e1 100644 --- a/src/sage/algebras/cluster_algebra.py +++ b/src/sage/algebras/cluster_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.graphs sage.modules r""" Cluster algebras @@ -360,12 +361,11 @@ from sage.categories.rings import Rings from sage.combinat.cluster_algebra_quiver.quiver import ClusterQuiver from sage.combinat.permutation import Permutation -from sage.geometry.cone import Cone -from sage.geometry.fan import Fan from sage.graphs.digraph import DiGraph from sage.matrix.constructor import identity_matrix, matrix from sage.matrix.special import block_matrix from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.misc.misc_c import prod from sage.modules.free_module_element import vector from sage.rings.infinity import infinity @@ -380,6 +380,8 @@ from sage.structure.sage_object import SageObject from sage.structure.unique_representation import UniqueRepresentation +lazy_import('sage.geometry.cone', 'Cone') +lazy_import('sage.geometry.fan', 'Fan') ############################################################################## # Elements of a cluster algebra @@ -2371,7 +2373,7 @@ def cluster_fan(self, depth=infinity): EXAMPLES:: sage: A = ClusterAlgebra(['A', 2]) - sage: A.cluster_fan() + sage: A.cluster_fan() # optional - sage.geometry.polyhedron Rational polyhedral fan in 2-d lattice N """ seeds = self.seeds(depth=depth, mutating_F=False) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index 2b5f2ccffd1..39da2cd3772 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Commutative Differential Graded Algebras @@ -42,7 +43,8 @@ sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,1,2)) sage: B = A.cdg_algebra({x: x*y, y: -x*y}) sage: B - Commutative Differential Graded Algebra with generators ('x', 'y', 'z') in degrees (1, 1, 2) over Rational Field with differential: + Commutative Differential Graded Algebra with generators ('x', 'y', 'z') + in degrees (1, 1, 2) over Rational Field with differential: x --> x*y y --> -x*y z --> 0 @@ -116,7 +118,7 @@ def sorting_keys(element): OUTPUT: - Its coordinates in the corresponding cohomology_raw quotient vector space + Its coordinates in the corresponding ``cohomology_raw`` quotient vector space EXAMPLES:: @@ -155,7 +157,8 @@ class Differential(UniqueRepresentation, Morphism, sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1, 1, 2, 3)) sage: B = A.cdg_algebra({x: x*y, y: -x*y , z: t}) sage: B - Commutative Differential Graded Algebra with generators ('x', 'y', 'z', 't') in degrees (1, 1, 2, 3) over Rational Field with differential: + Commutative Differential Graded Algebra with generators ('x', 'y', 'z', 't') + in degrees (1, 1, 2, 3) over Rational Field with differential: x --> x*y y --> -x*y z --> t @@ -181,7 +184,9 @@ def __classcall__(cls, A, im_gens): sage: A. = GradedCommutativeAlgebra(QQ,degrees=(2,2,3,3)) sage: A = A.quotient(A.ideal([a*u,b*u,x*u])) sage: A.cdg_algebra({x:a*b,a:u}) - Commutative Differential Graded Algebra with generators ('a', 'b', 'x', 'u') in degrees (2, 2, 3, 3) with relations [a*u, b*u, x*u] over Rational Field with differential: + Commutative Differential Graded Algebra with generators ('a', 'b', 'x', 'u') + in degrees (2, 2, 3, 3) with relations [a*u, b*u, x*u] over Rational Field + with differential: a --> u b --> 0 x --> a*b @@ -910,7 +915,8 @@ class GCAlgebra(UniqueRepresentation, QuotientRing_nc): 2 sage: B = A.quotient(A.ideal(a**2*b)) sage: B - Graded Commutative Algebra with generators ('a', 'b') in degrees (2, 3) with relations [a^2*b] over Rational Field + Graded Commutative Algebra with generators ('a', 'b') in degrees (2, 3) + with relations [a^2*b] over Rational Field sage: A.basis(7) [a^2*b] sage: B.basis(7) @@ -943,8 +949,8 @@ def __classcall__(cls, base, names=None, degrees=None, R=None, I=None, category= TESTS:: - sage: A1 = GradedCommutativeAlgebra(GF(2), 'x,y', (3, 6)) - sage: A2 = GradedCommutativeAlgebra(GF(2), ['x', 'y'], [3, 6]) + sage: A1 = GradedCommutativeAlgebra(GF(2), 'x,y', (3, 6)) # optional - sage.rings.finite_rings + sage: A2 = GradedCommutativeAlgebra(GF(2), ['x', 'y'], [3, 6]) # optional - sage.rings.finite_rings sage: A1 is A2 True @@ -956,8 +962,8 @@ def __classcall__(cls, base, names=None, degrees=None, R=None, I=None, category= sage: A4. = GradedCommutativeAlgebra(QQ, degrees=[4]) sage: z**2 == 0 False - sage: A5. = GradedCommutativeAlgebra(GF(2)) - sage: z**2 == 0 + sage: A5. = GradedCommutativeAlgebra(GF(2)) # optional - sage.rings.finite_rings + sage: z**2 == 0 # optional - sage.rings.finite_rings False """ if names is None: @@ -1201,18 +1207,19 @@ def quotient(self, I, check=True): EXAMPLES:: - sage: A. = GradedCommutativeAlgebra(GF(5), degrees=(2, 2, 3, 4)) - sage: I = A.ideal([x*t+z^2, x*y - t]) - sage: B = A.quotient(I) - sage: B - Graded Commutative Algebra with generators ('x', 'y', 'z', 't') in degrees (2, 2, 3, 4) with relations [x*t, x*y - t] over Finite Field of size 5 - sage: B(x*t) + sage: A. = GradedCommutativeAlgebra(GF(5), degrees=(2, 2, 3, 4)) # optional - sage.rings.finite_rings + sage: I = A.ideal([x*t+z^2, x*y - t]) # optional - sage.rings.finite_rings + sage: B = A.quotient(I); B # optional - sage.rings.finite_rings + Graded Commutative Algebra with generators ('x', 'y', 'z', 't') + in degrees (2, 2, 3, 4) with relations [x*t, x*y - t] + over Finite Field of size 5 + sage: B(x*t) # optional - sage.rings.finite_rings 0 - sage: B(x*y) + sage: B(x*y) # optional - sage.rings.finite_rings t - sage: A.basis(7) + sage: A.basis(7) # optional - sage.rings.finite_rings [x^2*z, x*y*z, y^2*z, z*t] - sage: B.basis(7) + sage: B.basis(7) # optional - sage.rings.finite_rings [x^2*z, y^2*z, z*t] """ if check and any(not i.is_homogeneous() for i in I.gens()): @@ -1304,13 +1311,22 @@ def _Hom_(self, B, category): sage: B. = GradedCommutativeAlgebra(QQ, degrees=(1,2,3)) sage: C. = GradedCommutativeAlgebra(GF(17)) sage: Hom(A,A) - Set of Homomorphisms from Graded Commutative Algebra with generators ('x', 'y') in degrees (1, 1) over Rational Field to Graded Commutative Algebra with generators ('x', 'y') in degrees (1, 1) over Rational Field + Set of Homomorphisms + from Graded Commutative Algebra with generators ('x', 'y') + in degrees (1, 1) over Rational Field + to Graded Commutative Algebra with generators ('x', 'y') + in degrees (1, 1) over Rational Field sage: Hom(A,B) - Set of Homomorphisms from Graded Commutative Algebra with generators ('x', 'y') in degrees (1, 1) over Rational Field to Graded Commutative Algebra with generators ('a', 'b', 'c') in degrees (1, 2, 3) over Rational Field + Set of Homomorphisms + from Graded Commutative Algebra with generators ('x', 'y') + in degrees (1, 1) over Rational Field + to Graded Commutative Algebra with generators ('a', 'b', 'c') + in degrees (1, 2, 3) over Rational Field sage: Hom(A,C) Traceback (most recent call last): ... - NotImplementedError: homomorphisms of graded commutative algebras have only been implemented when the base rings are the same + NotImplementedError: homomorphisms of graded commutative algebras + have only been implemented when the base rings are the same """ R = self.base_ring() # The base rings need to be checked before the categories, or @@ -1345,7 +1361,8 @@ def differential(self, diff): sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1, 1, 2)) sage: A.differential({y:x*y, x: x*y}) - Differential of Graded Commutative Algebra with generators ('x', 'y', 'z') in degrees (1, 1, 2) over Rational Field + Differential of Graded Commutative Algebra with generators ('x', 'y', 'z') + in degrees (1, 1, 2) over Rational Field Defn: x --> x*y y --> x*y z --> 0 @@ -1382,7 +1399,8 @@ def cdg_algebra(self, differential): sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1, 1, 1)) sage: B = A.cdg_algebra({a: b*c, b: a*c}) sage: B - Commutative Differential Graded Algebra with generators ('a', 'b', 'c') in degrees (1, 1, 1) over Rational Field with differential: + Commutative Differential Graded Algebra with generators ('a', 'b', 'c') + in degrees (1, 1, 1) over Rational Field with differential: a --> b*c b --> a*c c --> 0 @@ -1391,7 +1409,8 @@ def cdg_algebra(self, differential): sage: d = A.differential({a: b*c, b: a*c}) sage: d - Differential of Graded Commutative Algebra with generators ('a', 'b', 'c') in degrees (1, 1, 1) over Rational Field + Differential of Graded Commutative Algebra with generators ('a', 'b', 'c') + in degrees (1, 1, 1) over Rational Field Defn: a --> b*c b --> a*c c --> 0 @@ -1646,7 +1665,8 @@ class GCAlgebra_multigraded(GCAlgebra): sage: A. = GradedCommutativeAlgebra(QQ, degrees=((1,0), (0,1), (1,1))) sage: A - Graded Commutative Algebra with generators ('a', 'b', 'c') in degrees ((1, 0), (0, 1), (1, 1)) over Rational Field + Graded Commutative Algebra with generators ('a', 'b', 'c') + in degrees ((1, 0), (0, 1), (1, 1)) over Rational Field sage: a**2 0 sage: c.degree(total=True) @@ -1727,7 +1747,9 @@ def quotient(self, I, check=True): sage: I = A.ideal([x*t+z^2, x*y - t]) sage: B = A.quotient(I) sage: B - Graded Commutative Algebra with generators ('x', 'y', 'z', 't') in degrees (2, 2, 3, 4) with relations [x*t, x*y - t] over Finite Field of size 5 + Graded Commutative Algebra with generators ('x', 'y', 'z', 't') + in degrees (2, 2, 3, 4) with relations [x*t, x*y - t] + over Finite Field of size 5 sage: B(x*t) 0 sage: B(x*y) @@ -1823,7 +1845,8 @@ def differential(self, diff): sage: A. = GradedCommutativeAlgebra(QQ, degrees=((1,0), (0, 1), (0,2))) sage: A.differential({a: c}) - Differential of Graded Commutative Algebra with generators ('a', 'b', 'c') in degrees ((1, 0), (0, 1), (0, 2)) over Rational Field + Differential of Graded Commutative Algebra with generators ('a', 'b', 'c') + in degrees ((1, 0), (0, 1), (0, 2)) over Rational Field Defn: a --> c b --> 0 c --> 0 @@ -1855,13 +1878,15 @@ def cdg_algebra(self, differential): sage: A. = GradedCommutativeAlgebra(QQ, degrees=((1,0), (0, 1), (0,2))) sage: A.cdg_algebra({a: c}) - Commutative Differential Graded Algebra with generators ('a', 'b', 'c') in degrees ((1, 0), (0, 1), (0, 2)) over Rational Field with differential: + Commutative Differential Graded Algebra with generators ('a', 'b', 'c') + in degrees ((1, 0), (0, 1), (0, 2)) over Rational Field with differential: a --> c b --> 0 c --> 0 sage: d = A.differential({a: c}) sage: A.cdg_algebra(d) - Commutative Differential Graded Algebra with generators ('a', 'b', 'c') in degrees ((1, 0), (0, 1), (0, 2)) over Rational Field with differential: + Commutative Differential Graded Algebra with generators ('a', 'b', 'c') + in degrees ((1, 0), (0, 1), (0, 2)) over Rational Field with differential: a --> c b --> 0 c --> 0 @@ -1884,18 +1909,19 @@ def degree(self, total=False): EXAMPLES:: - sage: A. = GradedCommutativeAlgebra(GF(2), degrees=((1,0), (0,1), (1,1))) - sage: (a**2*b).degree() + sage: A. = GradedCommutativeAlgebra(GF(2), # optional - sage.rings.finite_rings + ....: degrees=((1,0), (0,1), (1,1))) + sage: (a**2*b).degree() # optional - sage.rings.finite_rings (2, 1) - sage: (a**2*b).degree(total=True) + sage: (a**2*b).degree(total=True) # optional - sage.rings.finite_rings 3 - sage: (a**2*b + c).degree() + sage: (a**2*b + c).degree() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: this element is not homogeneous - sage: (a**2*b + c).degree(total=True) + sage: (a**2*b + c).degree(total=True) # optional - sage.rings.finite_rings 3 - sage: A(0).degree() + sage: A(0).degree() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: the zero element does not have a well-defined degree @@ -1944,7 +1970,8 @@ class DifferentialGCAlgebra(GCAlgebra): sage: A. = GradedCommutativeAlgebra(QQ, degrees=(2, 2, 3, 3)) sage: A.cdg_algebra({z: x*y}) - Commutative Differential Graded Algebra with generators ('x', 'y', 'z', 't') in degrees (2, 2, 3, 3) over Rational Field with differential: + Commutative Differential Graded Algebra with generators ('x', 'y', 'z', 't') + in degrees (2, 2, 3, 3) over Rational Field with differential: x --> 0 y --> 0 z --> x*y @@ -1954,7 +1981,8 @@ class DifferentialGCAlgebra(GCAlgebra): sage: A. = GradedCommutativeAlgebra(QQ, degrees=(2, 2, 3, 3)) sage: A.cdg_algebra(differential={z: x*y}) - Commutative Differential Graded Algebra with generators ('x', 'y', 'z', 't') in degrees (2, 2, 3, 3) over Rational Field with differential: + Commutative Differential Graded Algebra with generators ('x', 'y', 'z', 't') + in degrees (2, 2, 3, 3) over Rational Field with differential: x --> 0 y --> 0 z --> x*y @@ -2052,13 +2080,17 @@ def cdg_algebra(self, differential): sage: B = A.quotient(A.ideal(x^3-z*t)) sage: C = B.cdg_algebra({y:t}) sage: C - Commutative Differential Graded Algebra with generators ('x', 'y', 'z', 't') in degrees (2, 3, 2, 4) with relations [x^3 - z*t] over Finite Field of size 5 with differential: + Commutative Differential Graded Algebra with generators ('x', 'y', 'z', 't') + in degrees (2, 3, 2, 4) with relations [x^3 - z*t] + over Finite Field of size 5 with differential: x --> 0 y --> t z --> 0 t --> 0 sage: C.cdg_algebra({}) - Commutative Differential Graded Algebra with generators ('x', 'y', 'z', 't') in degrees (2, 3, 2, 4) with relations [x^3 - z*t] over Finite Field of size 5 with differential: + Commutative Differential Graded Algebra with generators ('x', 'y', 'z', 't') + in degrees (2, 3, 2, 4) with relations [x^3 - z*t] + over Finite Field of size 5 with differential: x --> 0 y --> 0 z --> 0 @@ -2168,7 +2200,8 @@ def differential(self, x=None): sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,1,2)) sage: B = A.cdg_algebra({y:x*y, x: y*x}) sage: d = B.differential(); d - Differential of Commutative Differential Graded Algebra with generators ('x', 'y', 'z') in degrees (1, 1, 2) over Rational Field + Differential of Commutative Differential Graded Algebra + with generators ('x', 'y', 'z') in degrees (1, 1, 2) over Rational Field Defn: x --> -x*y y --> x*y z --> 0 @@ -2281,7 +2314,8 @@ def cohomology(self, n): sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,1,1,1,1)) sage: B = A.cdg_algebra({d: a*b, e: b*c}) sage: B.cohomology(2) - Free module generated by {[a*c], [a*d], [b*d], [c*d - a*e], [b*e], [c*e]} over Rational Field + Free module generated by {[a*c], [a*d], [b*d], [c*d - a*e], [b*e], [c*e]} + over Rational Field Compare to :meth:`cohomology_raw`:: @@ -2354,21 +2388,23 @@ def cohomology_generators(self, max_degree): In contrast, the corresponding algebra in characteristic `p` has finitely generated cohomology:: - sage: A3. = GradedCommutativeAlgebra(GF(3), degrees=(1,2,2)) - sage: B3 = A3.cdg_algebra(differential={y: a*x}) - sage: B3.cohomology_generators(16) + sage: A3. = GradedCommutativeAlgebra(GF(3), degrees=(1,2,2)) # optional - sage.rings.finite_rings + sage: B3 = A3.cdg_algebra(differential={y: a*x}) # optional - sage.rings.finite_rings + sage: B3.cohomology_generators(16) # optional - sage.rings.finite_rings {1: [a], 2: [x], 3: [a*y], 5: [a*y^2], 6: [y^3]} This method works with both singly graded and multi-graded algebras:: - sage: Cs. = GradedCommutativeAlgebra(GF(2), degrees=(1,2,2,3)) - sage: Ds = Cs.cdg_algebra({a:c, b:d}) - sage: Ds.cohomology_generators(10) + sage: Cs. = GradedCommutativeAlgebra(GF(2), degrees=(1,2,2,3)) # optional - sage.rings.finite_rings + sage: Ds = Cs.cdg_algebra({a:c, b:d}) # optional - sage.rings.finite_rings + sage: Ds.cohomology_generators(10) # optional - sage.rings.finite_rings {2: [a^2], 4: [b^2]} - sage: Cm. = GradedCommutativeAlgebra(GF(2), degrees=((1,0), (1,1), (0,2), (0,3))) - sage: Dm = Cm.cdg_algebra({a:c, b:d}) - sage: Dm.cohomology_generators(10) + sage: Cm. = GradedCommutativeAlgebra(GF(2), # optional - sage.rings.finite_rings + ....: degrees=((1,0), (1,1), + ....: (0,2), (0,3))) + sage: Dm = Cm.cdg_algebra({a:c, b:d}) # optional - sage.rings.finite_rings + sage: Dm.cohomology_generators(10) # optional - sage.rings.finite_rings {2: [a^2], 4: [b^2]} TESTS: @@ -2459,13 +2495,17 @@ def minimal_model(self, i=3, max_iterations=3, partial_result=False): sage: T = p.domain() sage: p Commutative Differential Graded Algebra morphism: - From: Commutative Differential Graded Algebra with generators ('x1_0', 'x2_0') in degrees (1, 2) over Rational Field with differential: - x1_0 --> 0 - x2_0 --> 0 - To: Commutative Differential Graded Algebra with generators ('x', 'y', 'z') in degrees (1, 1, 2) over Rational Field with differential: - x --> x*y - y --> x*y - z --> 0 + From: Commutative Differential Graded Algebra + with generators ('x1_0', 'x2_0') in degrees (1, 2) + over Rational Field with differential: + x1_0 --> 0 + x2_0 --> 0 + To: Commutative Differential Graded Algebra + with generators ('x', 'y', 'z') in degrees (1, 1, 2) + over Rational Field with differential: + x --> x*y + y --> x*y + z --> 0 Defn: (x1_0, x2_0) --> (x - y, z) sage: R.cohomology(1) Free module generated by {[x - y]} over Rational Field @@ -2488,7 +2528,11 @@ def minimal_model(self, i=3, max_iterations=3, partial_result=False): sage: phi = B.minimal_model(i=3) sage: M = phi.domain() sage: M - Commutative Differential Graded Algebra with generators ('x1_0', 'x1_1', 'x1_2', 'x2_0', 'x2_1', 'x2_2', 'x2_3', 'y3_0', 'y3_1', 'y3_2', 'y3_3', 'y3_4', 'y3_5', 'y3_6', 'y3_7', 'y3_8') in degrees (1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3) over Rational Field with differential: + Commutative Differential Graded Algebra with generators + ('x1_0', 'x1_1', 'x1_2', 'x2_0', 'x2_1', 'x2_2', 'x2_3', + 'y3_0', 'y3_1', 'y3_2', 'y3_3', 'y3_4', 'y3_5', 'y3_6', 'y3_7', 'y3_8') + in degrees (1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3) + over Rational Field with differential: x1_0 --> 0 x1_1 --> 0 x1_2 --> 0 @@ -2508,32 +2552,40 @@ def minimal_model(self, i=3, max_iterations=3, partial_result=False): sage: phi Commutative Differential Graded Algebra morphism: - From: Commutative Differential Graded Algebra with generators ('x1_0', 'x1_1', 'x1_2', 'x2_0', 'x2_1', 'x2_2', 'x2_3', 'y3_0', 'y3_1', 'y3_2', 'y3_3', 'y3_4', 'y3_5', 'y3_6', 'y3_7', 'y3_8') in degrees (1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3) over Rational Field with differential: - x1_0 --> 0 - x1_1 --> 0 - x1_2 --> 0 - x2_0 --> 0 - x2_1 --> 0 - x2_2 --> 0 - x2_3 --> 0 - y3_0 --> x2_0^2 - y3_1 --> x2_0*x2_1 - y3_2 --> x2_1^2 - y3_3 --> x2_0*x2_2 - y3_4 --> x2_1*x2_2 + x2_0*x2_3 - y3_5 --> x2_2^2 - y3_6 --> x2_1*x2_3 - y3_7 --> x2_2*x2_3 - y3_8 --> x2_3^2 - To: Commutative Differential Graded Algebra with generators ('e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7') in degrees (1, 1, 1, 1, 1, 1, 1) over Rational Field with differential: - e1 --> e1*e7 - e2 --> e2*e7 - e3 --> -e3*e7 - e4 --> -e4*e7 - e5 --> 0 - e6 --> 0 - e7 --> 0 - Defn: (x1_0, x1_1, x1_2, x2_0, x2_1, x2_2, x2_3, y3_0, y3_1, y3_2, y3_3, y3_4, y3_5, y3_6, y3_7, y3_8) --> (e5, e6, e7, e1*e3, e2*e3, e1*e4, e2*e4, 0, 0, 0, 0, 0, 0, 0, 0, 0) + From: Commutative Differential Graded Algebra with generators + ('x1_0', 'x1_1', 'x1_2', 'x2_0', 'x2_1', 'x2_2', 'x2_3', + 'y3_0', 'y3_1', 'y3_2', 'y3_3', 'y3_4', 'y3_5', 'y3_6', 'y3_7', 'y3_8') + in degrees (1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3) + over Rational Field with differential: + x1_0 --> 0 + x1_1 --> 0 + x1_2 --> 0 + x2_0 --> 0 + x2_1 --> 0 + x2_2 --> 0 + x2_3 --> 0 + y3_0 --> x2_0^2 + y3_1 --> x2_0*x2_1 + y3_2 --> x2_1^2 + y3_3 --> x2_0*x2_2 + y3_4 --> x2_1*x2_2 + x2_0*x2_3 + y3_5 --> x2_2^2 + y3_6 --> x2_1*x2_3 + y3_7 --> x2_2*x2_3 + y3_8 --> x2_3^2 + To: Commutative Differential Graded Algebra with generators + ('e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7') + in degrees (1, 1, 1, 1, 1, 1, 1) over Rational Field with differential: + e1 --> e1*e7 + e2 --> e2*e7 + e3 --> -e3*e7 + e4 --> -e4*e7 + e5 --> 0 + e6 --> 0 + e7 --> 0 + Defn: (x1_0, x1_1, x1_2, x2_0, x2_1, x2_2, x2_3, + y3_0, y3_1, y3_2, y3_3, y3_4, y3_5, y3_6, y3_7, y3_8) + --> (e5, e6, e7, e1*e3, e2*e3, e1*e4, e2*e4, 0, 0, 0, 0, 0, 0, 0, 0, 0) sage: [B.cohomology(i).dimension() for i in [1..3]] [3, 7, 13] sage: [M.cohomology(i).dimension() for i in [1..3]] @@ -2772,7 +2824,8 @@ def cohomology_algebra(self, max_degree=3): sage: B = A.cdg_algebra(d) sage: M = B.cohomology_algebra() sage: M - Commutative Differential Graded Algebra with generators ('x0', 'x1', 'x2') in degrees (1, 1, 2) over Rational Field with differential: + Commutative Differential Graded Algebra with generators ('x0', 'x1', 'x2') + in degrees (1, 1, 2) over Rational Field with differential: x0 --> 0 x1 --> 0 x2 --> 0 @@ -2843,14 +2896,18 @@ def numerical_invariants(self, max_degree=3, max_iterations=3): sage: B = A.cdg_algebra({e3 : e1*e2}) sage: B.minimal_model(4) Commutative Differential Graded Algebra morphism: - From: Commutative Differential Graded Algebra with generators ('x1_0', 'x1_1', 'y1_0') in degrees (1, 1, 1) over Rational Field with differential: - x1_0 --> 0 - x1_1 --> 0 - y1_0 --> x1_0*x1_1 - To: Commutative Differential Graded Algebra with generators ('e1', 'e2', 'e3') in degrees (1, 1, 1) over Rational Field with differential: - e1 --> 0 - e2 --> 0 - e3 --> e1*e2 + From: Commutative Differential Graded Algebra with + generators ('x1_0', 'x1_1', 'y1_0') in degrees (1, 1, 1) + over Rational Field with differential: + x1_0 --> 0 + x1_1 --> 0 + y1_0 --> x1_0*x1_1 + To: Commutative Differential Graded Algebra with + generators ('e1', 'e2', 'e3') in degrees (1, 1, 1) + over Rational Field with differential: + e1 --> 0 + e2 --> 0 + e3 --> e1*e2 Defn: (x1_0, x1_1, y1_0) --> (e1, e2, e3) sage: B.numerical_invariants(2) {1: [2, 1, 0], 2: [0, 0]} @@ -2908,7 +2965,7 @@ def is_formal(self, i, max_iterations=3): EXAMPLES:: sage: A. = GradedCommutativeAlgebra(QQ) - sage: B = A.cdg_algebra({e5 : e1*e2 + e3*e4}) + sage: B = A.cdg_algebra({e5: e1*e2 + e3*e4}) sage: B.is_formal(1) True sage: B.is_formal(2) @@ -2946,7 +3003,7 @@ def differential(self): EXAMPLES:: - sage: A. = GradedCommutativeAlgebra(QQ, degrees = (2, 2, 3, 4)) + sage: A. = GradedCommutativeAlgebra(QQ, degrees=(2, 2, 3, 4)) sage: B = A.cdg_algebra({t: x*z, x: z, y: z}) sage: B.inject_variables() Defining x, y, z, t @@ -2973,9 +3030,9 @@ def is_coboundary(self): False sage: (x*z).is_coboundary() True - sage: (x*z+x*y).is_coboundary() + sage: (x*z + x*y).is_coboundary() False - sage: (x*z+y**2).is_coboundary() + sage: (x*z + y**2).is_coboundary() Traceback (most recent call last): ... ValueError: this element is not homogeneous @@ -3000,7 +3057,7 @@ def is_cohomologous_to(self, other): EXAMPLES:: sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,1,1,1)) - sage: B = A.cdg_algebra(differential={a:b*c-c*d}) + sage: B = A.cdg_algebra(differential={a: b*c-c*d}) sage: w, x, y, z = B.gens() sage: (x*y).is_cohomologous_to(y*z) True @@ -3016,7 +3073,7 @@ def is_cohomologous_to(self, other): False sage: (x*y-y*z).is_cohomologous_to(x*y*z) True - sage: (x*y*z).is_cohomologous_to(0) # make sure 0 works + sage: (x*y*z).is_cohomologous_to(0) # make sure 0 works True """ if other.is_zero(): @@ -3036,17 +3093,17 @@ def cohomology_class(self): EXAMPLES:: sage: A. = GradedCommutativeAlgebra(QQ) - sage: B = A.cdg_algebra({e5:e1*e2+e3*e4}) + sage: B = A.cdg_algebra({e5: e1*e2+e3*e4}) sage: B.inject_variables() Defining e1, e2, e3, e4, e5 - sage: a = e1*e3*e5-3*e2*e3*e5 + sage: a = e1*e3*e5 - 3*e2*e3*e5 sage: a.cohomology_class() B[[e1*e3*e5]] - 3*B[[e2*e3*e5]] TESTS:: sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1, 2, 3)) - sage: B = A.cdg_algebra({a:b}) + sage: B = A.cdg_algebra({a: b}) sage: B.inject_variables() Defining a, b, c sage: b.cohomology_class() @@ -3057,10 +3114,10 @@ def cohomology_class(self): Check that the issue detected in :trac:`28155` is solved:: sage: A. = GradedCommutativeAlgebra(QQ) - sage: B = A.cdg_algebra({e5:e1*e2+e3*e4}) + sage: B = A.cdg_algebra({e5: e1*e2+e3*e4}) sage: B.inject_variables() Defining e1, e2, e3, e4, e5 - sage: a = e1*e3*e5-3*e2*e3*e5 + sage: a = e1*e3*e5 - 3*e2*e3*e5 sage: ca = a.cohomology_class() sage: C = B.cohomology(3) sage: ca in C @@ -3087,7 +3144,7 @@ def _cohomology_class_dict(self): EXAMPLES:: sage: A. = GradedCommutativeAlgebra(QQ) - sage: B = A.cdg_algebra({e5:e1*e2+e3*e4}) + sage: B = A.cdg_algebra({e5: e1*e2+e3*e4}) sage: a = B(e1*e3*e5-3*e2*e3*e5) sage: a._cohomology_class_dict() {(0, 0, 0, 0, 0, 0, 1, 0, 0): -3, (0, 0, 0, 0, 0, 1, 0, 0, 0): 1} @@ -3096,7 +3153,7 @@ def _cohomology_class_dict(self): x5 - 3*x6 sage: B.cohomology_generators(3) {1: [e1, e2, e3, e4], - 3: [e1*e2*e5 - e3*e4*e5, e1*e3*e5, e2*e3*e5, e1*e4*e5, e2*e4*e5]} + 3: [e1*e2*e5 - e3*e4*e5, e1*e3*e5, e2*e3*e5, e1*e4*e5, e2*e4*e5]} sage: [H(g._cohomology_class_dict()) for g in flatten(B.cohomology_generators(3).values())] [x0, x1, x2, x3, x4, x5, x6, x7, x8] """ @@ -3380,9 +3437,11 @@ def GradedCommutativeAlgebra(ring, names=None, degrees=None, max_degree=None, Defining a graded commutative algebra:: sage: GradedCommutativeAlgebra(QQ, 'x, y, z') - Graded Commutative Algebra with generators ('x', 'y', 'z') in degrees (1, 1, 1) over Rational Field + Graded Commutative Algebra with generators ('x', 'y', 'z') + in degrees (1, 1, 1) over Rational Field sage: GradedCommutativeAlgebra(QQ, degrees=(2, 3, 4)) - Graded Commutative Algebra with generators ('x0', 'x1', 'x2') in degrees (2, 3, 4) over Rational Field + Graded Commutative Algebra with generators ('x0', 'x1', 'x2') + in degrees (2, 3, 4) over Rational Field As usual in Sage, the ``A.<...>`` notation defines both the algebra and the generator names:: @@ -3390,21 +3449,21 @@ def GradedCommutativeAlgebra(ring, names=None, degrees=None, max_degree=None, sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1, 1, 2)) sage: x^2 0 - sage: y*x # Odd classes anticommute. + sage: y*x # Odd classes anticommute. -x*y - sage: z*y # z is central since it is in degree 2. + sage: z*y # z is central since it is in degree 2. y*z sage: (x*y*z**3).degree() 8 - sage: A.basis(3) # basis of homogeneous degree 3 elements + sage: A.basis(3) # basis of homogeneous degree 3 elements [x*z, y*z] Defining a quotient:: sage: I = A.ideal(x*z) - sage: AQ = A.quotient(I) - sage: AQ - Graded Commutative Algebra with generators ('x', 'y', 'z') in degrees (1, 1, 2) with relations [x*z] over Rational Field + sage: AQ = A.quotient(I); AQ + Graded Commutative Algebra with generators ('x', 'y', 'z') + in degrees (1, 1, 2) with relations [x*z] over Rational Field sage: AQ.basis(3) [y*z] @@ -3421,14 +3480,15 @@ def GradedCommutativeAlgebra(ring, names=None, degrees=None, max_degree=None, Now we add a differential to ``AQ``:: - sage: B = AQ.cdg_algebra({z:y*z}) - sage: B - Commutative Differential Graded Algebra with generators ('x', 'y', 'z') in degrees (1, 1, 2) with relations [x*z] over Rational Field with differential: + sage: B = AQ.cdg_algebra({z: y*z}); B + Commutative Differential Graded Algebra with generators ('x', 'y', 'z') + in degrees (1, 1, 2) with relations [x*z] over Rational Field with differential: x --> 0 y --> 0 z --> y*z sage: B.differential() - Differential of Commutative Differential Graded Algebra with generators ('x', 'y', 'z') in degrees (1, 1, 2) with relations [x*z] over Rational Field + Differential of Commutative Differential Graded Algebra with generators + ('x', 'y', 'z') in degrees (1, 1, 2) with relations [x*z] over Rational Field Defn: x --> 0 y --> 0 z --> y*z @@ -3447,10 +3507,12 @@ def GradedCommutativeAlgebra(ring, names=None, degrees=None, max_degree=None, We can construct multi-graded rings as well. We work in characteristic 2 for a change, so the algebras here are honestly commutative:: - sage: C. = GradedCommutativeAlgebra(GF(2), degrees=((1,0), (1,1), (0,2), (0,3))) - sage: D = C.cdg_algebra(differential={a:c, b:d}) - sage: D - Commutative Differential Graded Algebra with generators ('a', 'b', 'c', 'd') in degrees ((1, 0), (1, 1), (0, 2), (0, 3)) over Finite Field of size 2 with differential: + sage: C. = GradedCommutativeAlgebra(GF(2), # optional - sage.rings.finite_rings + ....: degrees=((1,0), (1,1), (0,2), (0,3))) + sage: D = C.cdg_algebra(differential={a: c, b: d}); D # optional - sage.rings.finite_rings + Commutative Differential Graded Algebra with generators ('a', 'b', 'c', 'd') + in degrees ((1, 0), (1, 1), (0, 2), (0, 3)) over Finite Field of size 2 + with differential: a --> c b --> d c --> 0 @@ -3460,52 +3522,51 @@ def GradedCommutativeAlgebra(ring, names=None, degrees=None, max_degree=None, Use tuples, lists, vectors, or elements of additive abelian groups to specify degrees:: - sage: D.basis(3) # basis in total degree 3 + sage: D.basis(3) # basis in total degree 3 # optional - sage.rings.finite_rings [a^3, a*b, a*c, d] - sage: D.basis((1,2)) # basis in degree (1,2) + sage: D.basis((1,2)) # basis in degree (1,2) # optional - sage.rings.finite_rings [a*c] - sage: D.basis([1,2]) + sage: D.basis([1,2]) # optional - sage.rings.finite_rings [a*c] - sage: D.basis(vector([1,2])) + sage: D.basis(vector([1,2])) # optional - sage.rings.finite_rings [a*c] sage: G = AdditiveAbelianGroup([0,0]); G Additive abelian group isomorphic to Z + Z - sage: D.basis(G(vector([1,2]))) + sage: D.basis(G(vector([1,2]))) # optional - sage.rings.finite_rings [a*c] At this point, ``a``, for example, is an element of ``C``. We can redefine it so that it is instead an element of ``D`` in several ways, for instance using :meth:`gens` method:: - sage: a, b, c, d = D.gens() - sage: a.differential() + sage: a, b, c, d = D.gens() # optional - sage.rings.finite_rings + sage: a.differential() # optional - sage.rings.finite_rings c Or the :meth:`inject_variables` method:: - sage: D.inject_variables() + sage: D.inject_variables() # optional - sage.rings.finite_rings Defining a, b, c, d - sage: (a*b).differential() + sage: (a*b).differential() # optional - sage.rings.finite_rings b*c + a*d - sage: (a*b*c**2).degree() + sage: (a*b*c**2).degree() # optional - sage.rings.finite_rings (2, 5) Degrees are returned as elements of additive abelian groups:: - sage: (a*b*c**2).degree() in G + sage: (a*b*c**2).degree() in G # optional - sage.rings.finite_rings True - sage: (a*b*c**2).degree(total=True) # total degree + sage: (a*b*c**2).degree(total=True) # total degree # optional - sage.rings.finite_rings 7 - sage: D.cohomology(4) + sage: D.cohomology(4) # optional - sage.rings.finite_rings Free module generated by {[a^4], [b^2]} over Finite Field of size 2 - sage: D.cohomology((2,2)) + sage: D.cohomology((2,2)) # optional - sage.rings.finite_rings Free module generated by {[b^2]} over Finite Field of size 2 Graded algebra with maximal degree:: - sage: A. = GradedCommutativeAlgebra(QQ, degrees=(4,2), max_degree=6) - sage: A + sage: A. = GradedCommutativeAlgebra(QQ, degrees=(4,2), max_degree=6); A Graded commutative algebra with generators ('p', 'e') in degrees (4, 2) with maximal degree 6 sage: p^2 @@ -3563,7 +3624,8 @@ class GCAlgebraMorphism(RingHomomorphism_im_gens): sage: H = Hom(A,A) sage: f = H([y,x]) sage: f - Graded Commutative Algebra endomorphism of Graded Commutative Algebra with generators ('x', 'y') in degrees (1, 1) over Rational Field + Graded Commutative Algebra endomorphism of Graded Commutative Algebra + with generators ('x', 'y') in degrees (1, 1) over Rational Field Defn: (x, y) --> (y, x) sage: f(x*y) -x*y @@ -3590,7 +3652,8 @@ def __init__(self, parent, im_gens, check=True): sage: H = Hom(A,A) sage: f = H([x,x]) sage: f - Graded Commutative Algebra endomorphism of Graded Commutative Algebra with generators ('x', 'y') in degrees (1, 2) over Rational Field + Graded Commutative Algebra endomorphism of Graded Commutative Algebra + with generators ('x', 'y') in degrees (1, 2) over Rational Field Defn: (x, y) --> (x, x) sage: f.is_graded() False @@ -3608,7 +3671,8 @@ def __init__(self, parent, im_gens, check=True): sage: A2. = GradedCommutativeAlgebra(GF(2), degrees=(1,2)) sage: H2 = Hom(A2,A2) sage: H2([y,y]) - Graded Commutative Algebra endomorphism of Graded Commutative Algebra with generators ('x', 'y') in degrees (1, 2) over Finite Field of size 2 + Graded Commutative Algebra endomorphism of Graded Commutative Algebra + with generators ('x', 'y') in degrees (1, 2) over Finite Field of size 2 Defn: (x, y) --> (y, y) The "nc-relations" `a*b = -b*a`, for `a` and `b` in odd @@ -3652,7 +3716,8 @@ def __init__(self, parent, im_gens, check=True): sage: A.cover_ring() Multivariate Polynomial Ring in e1 over Rational Field sage: A.hom([2*e1]) - Graded Commutative Algebra endomorphism of Graded Commutative Algebra with generators ('e1',) in degrees (1,) over Rational Field + Graded Commutative Algebra endomorphism of Graded Commutative Algebra + with generators ('e1',) in degrees (1,) over Rational Field Defn: (e1,) --> (2*e1,) """ @@ -3834,13 +3899,17 @@ class GCAlgebraHomset(RingHomset_generic): sage: H = Hom(A,B) sage: H([y,0]) Graded Commutative Algebra morphism: - From: Graded Commutative Algebra with generators ('w', 'x') in degrees (1, 2) over Rational Field - To: Graded Commutative Algebra with generators ('y', 'z') in degrees (1, 1) over Rational Field + From: Graded Commutative Algebra with generators ('w', 'x') + in degrees (1, 2) over Rational Field + To: Graded Commutative Algebra with generators ('y', 'z') + in degrees (1, 1) over Rational Field Defn: (w, x) --> (y, 0) sage: H([y,y*z]) Graded Commutative Algebra morphism: - From: Graded Commutative Algebra with generators ('w', 'x') in degrees (1, 2) over Rational Field - To: Graded Commutative Algebra with generators ('y', 'z') in degrees (1, 1) over Rational Field + From: Graded Commutative Algebra with generators ('w', 'x') + in degrees (1, 2) over Rational Field + To: Graded Commutative Algebra with generators ('y', 'z') + in degrees (1, 1) over Rational Field Defn: (w, x) --> (y, y*z) """ @@ -4085,7 +4154,7 @@ def total_degree(deg): INPUT: - - ``deg`` - an element of a free abelian group. + - ``deg`` -- an element of a free abelian group. In fact, ``deg`` could be an integer, a Python int, a list, a tuple, a vector, etc. This function returns the sum of the diff --git a/src/sage/algebras/down_up_algebra.py b/src/sage/algebras/down_up_algebra.py index 3ee1bcea25f..b39c86b3d4f 100644 --- a/src/sage/algebras/down_up_algebra.py +++ b/src/sage/algebras/down_up_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Down-Up Algebras diff --git a/src/sage/algebras/exterior_algebra_groebner.pyx b/src/sage/algebras/exterior_algebra_groebner.pyx index 376eb454082..ee54b5e4baf 100644 --- a/src/sage/algebras/exterior_algebra_groebner.pyx +++ b/src/sage/algebras/exterior_algebra_groebner.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Exterior algebras Gröbner bases diff --git a/src/sage/algebras/finite_gca.py b/src/sage/algebras/finite_gca.py index 5f21cdc8290..9c76ddf3199 100644 --- a/src/sage/algebras/finite_gca.py +++ b/src/sage/algebras/finite_gca.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Finite dimensional graded commutative algebras diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 460b623b877..eaddfc54e5a 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.combinat sage.modules """ Free algebras @@ -17,11 +17,12 @@ EXAMPLES:: - sage: F = FreeAlgebra(ZZ,3,'x,y,z') + sage: F = FreeAlgebra(ZZ, 3, 'x,y,z') sage: F.base_ring() Integer Ring sage: G = FreeAlgebra(F, 2, 'm,n'); G - Free Algebra on 2 generators (m, n) over Free Algebra on 3 generators (x, y, z) over Integer Ring + Free Algebra on 2 generators (m, n) over + Free Algebra on 3 generators (x, y, z) over Integer Ring sage: G.base_ring() Free Algebra on 3 generators (x, y, z) over Integer Ring @@ -34,11 +35,10 @@ Moreover, we can compute Groebner bases with degree bound for its two-sided ideals, and thus provide ideal containment tests:: - sage: F. = FreeAlgebra(QQ, implementation='letterplace') - sage: F + sage: F. = FreeAlgebra(QQ, implementation='letterplace'); F # optional - sage.libs.singular Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field - sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F - sage: I.groebner_basis(degbound=4) + sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F # optional - sage.libs.singular + sage: I.groebner_basis(degbound=4) # optional - sage.libs.singular Twosided Ideal (x*y + y*z, x*x - y*x - y*y - y*z, y*y*y - y*y*z + y*z*y - y*z*z, @@ -48,67 +48,67 @@ y*y*z*x + y*y*z*z + y*z*z*x + y*z*z*z, y*z*y*x + y*z*y*z + y*z*z*x + y*z*z*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field - sage: y*z*y*y*z*z + 2*y*z*y*z*z*x + y*z*y*z*z*z - y*z*z*y*z*x + y*z*z*z*z*x in I + sage: y*z*y*y*z*z + 2*y*z*y*z*z*x + y*z*y*z*z*z - y*z*z*y*z*x + y*z*z*z*z*x in I # optional - sage.libs.singular True Positive integral degree weights for the letterplace implementation was introduced in :trac:`7797`:: - sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) - sage: x.degree() + sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) # optional - sage.libs.singular + sage: x.degree() # optional - sage.libs.singular 2 - sage: y.degree() + sage: y.degree() # optional - sage.libs.singular 1 - sage: z.degree() + sage: z.degree() # optional - sage.libs.singular 3 - sage: I = F*[x*y-y*x, x^2+2*y*z, (x*y)^2-z^2]*F - sage: Q. = F.quo(I) - sage: TestSuite(Q).run() - sage: a^2*b^2 + sage: I = F*[x*y-y*x, x^2+2*y*z, (x*y)^2-z^2]*F # optional - sage.libs.singular + sage: Q. = F.quo(I) # optional - sage.libs.singular + sage: TestSuite(Q).run() # optional - sage.libs.singular + sage: a^2*b^2 # optional - sage.libs.singular c*c TESTS:: - sage: F = FreeAlgebra(GF(5),3,'x') - sage: TestSuite(F).run() - sage: F is loads(dumps(F)) + sage: F = FreeAlgebra(GF(5),3,'x') # optional - sage.rings.finite_rings + sage: TestSuite(F).run() # optional - sage.rings.finite_rings + sage: F is loads(dumps(F)) # optional - sage.rings.finite_rings True - sage: F = FreeAlgebra(GF(5),3,'x', implementation='letterplace') - sage: TestSuite(F).run() - sage: F is loads(dumps(F)) + sage: F = FreeAlgebra(GF(5),3,'x', implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings + sage: TestSuite(F).run() # optional - sage.libs.singular sage.rings.finite_rings + sage: F is loads(dumps(F)) # optional - sage.libs.singular sage.rings.finite_rings True :: - sage: F. = FreeAlgebra(GF(5),3) - sage: TestSuite(F).run() - sage: F is loads(dumps(F)) + sage: F. = FreeAlgebra(GF(5),3) # optional - sage.rings.finite_rings + sage: TestSuite(F).run() # optional - sage.rings.finite_rings + sage: F is loads(dumps(F)) # optional - sage.rings.finite_rings True - sage: F. = FreeAlgebra(GF(5),3, implementation='letterplace') - sage: TestSuite(F).run() - sage: F is loads(dumps(F)) + sage: F. = FreeAlgebra(GF(5),3, implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings + sage: TestSuite(F).run() # optional - sage.libs.singular sage.rings.finite_rings + sage: F is loads(dumps(F)) # optional - sage.libs.singular sage.rings.finite_rings True :: - sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y']) - sage: TestSuite(F).run() - sage: F is loads(dumps(F)) + sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y']) # optional - sage.rings.finite_rings + sage: TestSuite(F).run() # optional - sage.rings.finite_rings + sage: F is loads(dumps(F)) # optional - sage.rings.finite_rings True - sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y'], implementation='letterplace') - sage: TestSuite(F).run() - sage: F is loads(dumps(F)) + sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y'], implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings + sage: TestSuite(F).run() # optional - sage.libs.singular sage.rings.finite_rings + sage: F is loads(dumps(F)) # optional - sage.libs.singular sage.rings.finite_rings True :: - sage: F = FreeAlgebra(GF(5),3, 'abc') - sage: TestSuite(F).run() - sage: F is loads(dumps(F)) + sage: F = FreeAlgebra(GF(5),3, 'abc') # optional - sage.rings.finite_rings + sage: TestSuite(F).run() # optional - sage.rings.finite_rings + sage: F is loads(dumps(F)) # optional - sage.rings.finite_rings True - sage: F = FreeAlgebra(GF(5),3, 'abc', implementation='letterplace') - sage: TestSuite(F).run() - sage: F is loads(dumps(F)) + sage: F = FreeAlgebra(GF(5),3, 'abc', implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings + sage: TestSuite(F).run() # optional - sage.libs.singular sage.rings.finite_rings + sage: F is loads(dumps(F)) # optional - sage.libs.singular sage.rings.finite_rings True :: @@ -121,7 +121,7 @@ Note that the letterplace implementation can only be used if the corresponding (multivariate) polynomial ring has an implementation in Singular:: - sage: FreeAlgebra(FreeAlgebra(ZZ,2,'ab'), 2, 'x', implementation='letterplace') + sage: FreeAlgebra(FreeAlgebra(ZZ,2,'ab'), 2, 'x', implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: polynomials over Free Algebra on 2 generators (a, b) over Integer Ring are not supported in Singular @@ -165,21 +165,22 @@ class FreeAlgebraFactory(UniqueFactory): EXAMPLES:: - sage: FreeAlgebra(GF(5),3,'x') + sage: FreeAlgebra(GF(5),3,'x') # optional - sage.rings.finite_rings Free Algebra on 3 generators (x0, x1, x2) over Finite Field of size 5 - sage: F. = FreeAlgebra(GF(5),3) - sage: (x+y+z)^2 + sage: F. = FreeAlgebra(GF(5),3) # optional - sage.rings.finite_rings + sage: (x+y+z)^2 # optional - sage.rings.finite_rings x^2 + x*y + x*z + y*x + y^2 + y*z + z*x + z*y + z^2 - sage: FreeAlgebra(GF(5),3, 'xx, zba, Y') + sage: FreeAlgebra(GF(5),3, 'xx, zba, Y') # optional - sage.rings.finite_rings Free Algebra on 3 generators (xx, zba, Y) over Finite Field of size 5 - sage: FreeAlgebra(GF(5),3, 'abc') + sage: FreeAlgebra(GF(5),3, 'abc') # optional - sage.rings.finite_rings Free Algebra on 3 generators (a, b, c) over Finite Field of size 5 - sage: FreeAlgebra(GF(5),1, 'z') + sage: FreeAlgebra(GF(5),1, 'z') # optional - sage.rings.finite_rings Free Algebra on 1 generators (z,) over Finite Field of size 5 - sage: FreeAlgebra(GF(5),1, ['alpha']) + sage: FreeAlgebra(GF(5),1, ['alpha']) # optional - sage.rings.finite_rings Free Algebra on 1 generators (alpha,) over Finite Field of size 5 sage: FreeAlgebra(FreeAlgebra(ZZ,1,'a'), 2, 'x') - Free Algebra on 2 generators (x0, x1) over Free Algebra on 1 generators (a,) over Integer Ring + Free Algebra on 2 generators (x0, x1) over + Free Algebra on 1 generators (a,) over Integer Ring Free algebras are globally unique:: @@ -187,14 +188,14 @@ class FreeAlgebraFactory(UniqueFactory): sage: G = FreeAlgebra(ZZ,3,'x,y,z') sage: F is G True - sage: F. = FreeAlgebra(GF(5),3) # indirect doctest - sage: F is loads(dumps(F)) + sage: F. = FreeAlgebra(GF(5),3) # indirect doctest # optional - sage.rings.finite_rings + sage: F is loads(dumps(F)) # optional - sage.rings.finite_rings True - sage: F is FreeAlgebra(GF(5),['x','y','z']) + sage: F is FreeAlgebra(GF(5),['x','y','z']) # optional - sage.rings.finite_rings True - sage: copy(F) is F is loads(dumps(F)) + sage: copy(F) is F is loads(dumps(F)) # optional - sage.rings.finite_rings True - sage: TestSuite(F).run() + sage: TestSuite(F).run() # optional - sage.rings.finite_rings By :trac:`7797`, we provide a different implementation of free algebras, based on Singular's "letterplace rings". Our letterplace @@ -203,25 +204,27 @@ class FreeAlgebraFactory(UniqueFactory): elements are supported. Of course, isomorphic algebras in different implementations are not identical:: - sage: G = FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace') - sage: F == G + sage: G = FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings + sage: F == G # optional - sage.libs.singular sage.rings.finite_rings False - sage: G is FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace') + sage: G is FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings True - sage: copy(G) is G is loads(dumps(G)) + sage: copy(G) is G is loads(dumps(G)) # optional - sage.libs.singular sage.rings.finite_rings True - sage: TestSuite(G).run() + sage: TestSuite(G).run() # optional - sage.libs.singular sage.rings.finite_rings :: - sage: H = FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace', degrees=[1,2,3]) - sage: F != H != G + sage: H = FreeAlgebra(GF(5), ['x','y','z'], implementation='letterplace', # optional - sage.libs.singular sage.rings.finite_rings + ....: degrees=[1,2,3]) + sage: F != H != G # optional - sage.libs.singular sage.rings.finite_rings True - sage: H is FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace', degrees=[1,2,3]) + sage: H is FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace', # optional - sage.libs.singular sage.rings.finite_rings + ....: degrees=[1,2,3]) True - sage: copy(H) is H is loads(dumps(H)) + sage: copy(H) is H is loads(dumps(H)) # optional - sage.libs.singular sage.rings.finite_rings True - sage: TestSuite(H).run() + sage: TestSuite(H).run() # optional - sage.libs.singular sage.rings.finite_rings Free algebras commute with their base ring. :: @@ -235,7 +238,8 @@ class FreeAlgebraFactory(UniqueFactory): sage: s = a*b^2 * c^3; s a*b^2*c^3 sage: parent(s) - Free Algebra on 1 generators (c,) over Free Algebra on 2 generators (a, b) over Rational Field + Free Algebra on 1 generators (c,) over + Free Algebra on 2 generators (a, b) over Rational Field sage: c^3 * a * b^2 a*b^2*c^3 """ @@ -248,19 +252,23 @@ def create_key(self, base_ring, arg1=None, arg2=None, TESTS:: - sage: FreeAlgebra.create_key(GF(5),['x','y','z']) + sage: FreeAlgebra.create_key(GF(5),['x','y','z']) # optional - sage.rings.finite_rings (Finite Field of size 5, ('x', 'y', 'z')) - sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3) + sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3) # optional - sage.rings.finite_rings (Finite Field of size 5, ('x', 'y', 'z')) - sage: FreeAlgebra.create_key(GF(5),3,'xyz') + sage: FreeAlgebra.create_key(GF(5),3,'xyz') # optional - sage.rings.finite_rings (Finite Field of size 5, ('x', 'y', 'z')) - sage: FreeAlgebra.create_key(GF(5),['x','y','z'], implementation='letterplace') + sage: FreeAlgebra.create_key(GF(5),['x','y','z'], # optional - sage.libs.singular sage.rings.finite_rings + ....: implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) - sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3, implementation='letterplace') + sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3, # optional - sage.libs.singular sage.rings.finite_rings + ....: implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) - sage: FreeAlgebra.create_key(GF(5),3,'xyz', implementation='letterplace') + sage: FreeAlgebra.create_key(GF(5),3,'xyz', # optional - sage.libs.singular sage.rings.finite_rings + ....: implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) - sage: FreeAlgebra.create_key(GF(5),3,'xyz', implementation='letterplace', degrees=[1,2,3]) + sage: FreeAlgebra.create_key(GF(5),3,'xyz', # optional - sage.libs.singular sage.rings.finite_rings + ....: implementation='letterplace', degrees=[1,2,3]) ((1, 2, 3), Multivariate Polynomial Ring in x, y, z, x_ over Finite Field of size 5) """ @@ -543,21 +551,21 @@ def _element_constructor_(self, x): TESTS:: - sage: F. = FreeAlgebra(GF(5),3) - sage: L. = FreeAlgebra(ZZ,3,implementation='letterplace') - sage: F(x) # indirect doctest + sage: F. = FreeAlgebra(GF(5),3) # optional - sage.rings.finite_rings + sage: L. = FreeAlgebra(ZZ,3,implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings + sage: F(x) # indirect doctest # optional - sage.libs.singular sage.rings.finite_rings x - sage: F.1*L.2 + sage: F.1*L.2 # optional - sage.libs.singular sage.rings.finite_rings y*z - sage: (F.1*L.2).parent() is F + sage: (F.1*L.2).parent() is F # optional - sage.libs.singular sage.rings.finite_rings True :: - sage: K. = GF(25) - sage: F. = FreeAlgebra(K,3) - sage: L. = FreeAlgebra(K,3, implementation='letterplace') - sage: F.1+(z+1)*L.2 + sage: K. = GF(25) # optional - sage.rings.finite_rings + sage: F. = FreeAlgebra(K,3) # optional - sage.rings.finite_rings + sage: L. = FreeAlgebra(K,3, implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings + sage: F.1+(z+1)*L.2 # optional - sage.libs.singular sage.rings.finite_rings b + (z+1)*c Check that :trac:`15169` is fixed:: @@ -667,23 +675,23 @@ def _coerce_map_from_(self, R): sage: F.has_coerce_map_from(PolynomialRing(ZZ, 3, 'x,y,z')) False - sage: K. = GF(25) - sage: F. = FreeAlgebra(K,3) - sage: F._coerce_map_from_(ZZ) + sage: K. = GF(25) # optional - sage.rings.finite_rings + sage: F. = FreeAlgebra(K,3) # optional - sage.rings.finite_rings + sage: F._coerce_map_from_(ZZ) # optional - sage.rings.finite_rings True - sage: F._coerce_map_from_(QQ) + sage: F._coerce_map_from_(QQ) # optional - sage.rings.finite_rings False - sage: F._coerce_map_from_(F.monoid()) + sage: F._coerce_map_from_(F.monoid()) # optional - sage.rings.finite_rings True - sage: F._coerce_map_from_(F.pbw_basis()) + sage: F._coerce_map_from_(F.pbw_basis()) # optional - sage.rings.finite_rings True sage: G = FreeAlgebra(ZZ, 3, 'a,b,c') - sage: F._coerce_map_from_(G) + sage: F._coerce_map_from_(G) # optional - sage.rings.finite_rings True - sage: G._coerce_map_from_(F) + sage: G._coerce_map_from_(F) # optional - sage.rings.finite_rings False - sage: L. = FreeAlgebra(K,3, implementation='letterplace') - sage: F.1 + (z+1) * L.2 + sage: L. = FreeAlgebra(K,3, implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings + sage: F.1 + (z+1) * L.2 # optional - sage.libs.singular sage.rings.finite_rings b + (z+1)*c """ if self._indices.has_coerce_map_from(R): @@ -780,9 +788,12 @@ def quotient(self, mons, mats=None, names=None, **args): sage: i, j, k = F.gens() sage: mons = [ F(1), i, j, k ] sage: M = MatrixSpace(QQ,4) - sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]), M([0,0,0,1, 0,0,-1,0, 0,1,0,0, -1,0,0,0]) ] + sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), + ....: M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]), + ....: M([0,0,0,1, 0,0,-1,0, 0,1,0,0, -1,0,0,0]) ] sage: H. = A.quotient(mons, mats); H - Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field + Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 + over Rational Field """ if mats is None: return super().quotient(mons, names) diff --git a/src/sage/algebras/free_algebra_element.py b/src/sage/algebras/free_algebra_element.py index 559df673fbf..f5bf4277f16 100644 --- a/src/sage/algebras/free_algebra_element.py +++ b/src/sage/algebras/free_algebra_element.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.combinat sage.modules """ Free algebra elements diff --git a/src/sage/algebras/free_algebra_quotient.py b/src/sage/algebras/free_algebra_quotient.py index b19884335c4..d79b9a2ac47 100644 --- a/src/sage/algebras/free_algebra_quotient.py +++ b/src/sage/algebras/free_algebra_quotient.py @@ -21,11 +21,12 @@ sage: A = FreeAlgebra(QQ,n,'x') sage: F = A.monoid() sage: i, j = F.gens() - sage: mons = [ F(1), i, j, i*j ] + sage: mons = [F(1), i, j, i*j] sage: r = len(mons) sage: M = MatrixSpace(QQ,r) - sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ] - sage: H2. = A.quotient(mons,mats) + sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), +....: M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ] + sage: H2. = A.quotient(mons, mats) sage: H2 == loads(dumps(H2)) True sage: i == loads(dumps(i)) @@ -106,15 +107,20 @@ def __init__(self, A, mons, mats, names): sage: A = FreeAlgebra(QQ,n,'i') sage: F = A.monoid() sage: i, j, k = F.gens() - sage: mons = [ F(1), i, j, k ] + sage: mons = [F(1), i, j, k] sage: M = MatrixSpace(QQ,4) - sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]), M([0,0,0,1, 0,0,-1,0, 0,1,0,0, -1,0,0,0]) ] + sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), + ....: M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]), + ....: M([0,0,0,1, 0,0,-1,0, 0,1,0,0, -1,0,0,0]) ] sage: H3. = FreeAlgebraQuotient(A,mons,mats) sage: x = 1 + i + j + k sage: x 1 + i + j + k sage: x**128 - -170141183460469231731687303715884105728 + 170141183460469231731687303715884105728*i + 170141183460469231731687303715884105728*j + 170141183460469231731687303715884105728*k + -170141183460469231731687303715884105728 + + 170141183460469231731687303715884105728*i + + 170141183460469231731687303715884105728*j + + 170141183460469231731687303715884105728*k Same algebra defined in terms of two generators, with some penalty on already slow arithmetic. @@ -128,14 +134,18 @@ def __init__(self, A, mons, mats, names): sage: mons = [ F(1), i, j, i*j ] sage: r = len(mons) sage: M = MatrixSpace(QQ,r) - sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ] + sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), + ....: M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ] sage: H2. = A.quotient(mons,mats) sage: k = i*j sage: x = 1 + i + j + k sage: x 1 + i + j + i*j sage: x**128 - -170141183460469231731687303715884105728 + 170141183460469231731687303715884105728*i + 170141183460469231731687303715884105728*j + 170141183460469231731687303715884105728*i*j + -170141183460469231731687303715884105728 + + 170141183460469231731687303715884105728*i + + 170141183460469231731687303715884105728*j + + 170141183460469231731687303715884105728*i*j TESTS:: @@ -180,7 +190,7 @@ def _coerce_map_from_(self, S): True sage: H._coerce_map_from_(QQ) True - sage: H._coerce_map_from_(GF(7)) + sage: H._coerce_map_from_(GF(7)) # optional - sage.rings.finite_rings False """ return S == self or self.__free_algebra.has_coerce_map_from(S) @@ -345,7 +355,8 @@ def hamilton_quatalg(R): sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ) sage: H - Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Integer Ring + Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 + over Integer Ring sage: i^2 -1 sage: i in H diff --git a/src/sage/algebras/free_algebra_quotient_element.py b/src/sage/algebras/free_algebra_quotient_element.py index c841a9210cf..738e5b723a3 100644 --- a/src/sage/algebras/free_algebra_quotient_element.py +++ b/src/sage/algebras/free_algebra_quotient_element.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Free algebra quotient elements diff --git a/src/sage/algebras/free_zinbiel_algebra.py b/src/sage/algebras/free_zinbiel_algebra.py index 39ac9091618..f7e2f97e50c 100644 --- a/src/sage/algebras/free_zinbiel_algebra.py +++ b/src/sage/algebras/free_zinbiel_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Free Zinbiel Algebras @@ -539,14 +540,14 @@ def _coerce_map_from_(self, R): EXAMPLES:: - sage: F = algebras.FreeZinbiel(GF(7), 'x,y,z'); F + sage: F = algebras.FreeZinbiel(GF(7), 'x,y,z'); F # optional - sage.rings.finite_rings Free Zinbiel algebra on generators (Z[x], Z[y], Z[z]) over Finite Field of size 7 Elements of the free Zinbiel algebra canonically coerce in:: - sage: x, y, z = F.gens() - sage: F.coerce(x+y) == x+y + sage: x, y, z = F.gens() # optional - sage.rings.finite_rings + sage: F.coerce(x+y) == x+y # optional - sage.rings.finite_rings True The free Zinbiel algebra over `\ZZ` on `x, y, z` coerces in, since @@ -554,15 +555,15 @@ def _coerce_map_from_(self, R): sage: G = algebras.FreeZinbiel(ZZ, 'x,y,z') sage: Gx,Gy,Gz = G.gens() - sage: z = F.coerce(Gx+Gy); z + sage: z = F.coerce(Gx+Gy); z # optional - sage.rings.finite_rings Z[x] + Z[y] - sage: z.parent() is F + sage: z.parent() is F # optional - sage.rings.finite_rings True However, `\GF{7}` does not coerce to `\ZZ`, so the free Zinbiel algebra over `\GF{7}` does not coerce to the one over `\ZZ`:: - sage: G.coerce(y) + sage: G.coerce(y) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no canonical coercion from Free Zinbiel algebra on @@ -641,18 +642,18 @@ class ZinbielFunctor(ConstructionFunctor): sage: F = P.construction()[0]; F Zinbiel[x,y] - sage: A = GF(5)['a,b'] - sage: a, b = A.gens() - sage: F(A) + sage: A = GF(5)['a,b'] # optional - sage.rings.finite_rings + sage: a, b = A.gens() # optional - sage.rings.finite_rings + sage: F(A) # optional - sage.rings.finite_rings Free Zinbiel algebra on generators (Z[x], Z[y]) over Multivariate Polynomial Ring in a, b over Finite Field of size 5 - sage: f = A.hom([a+b,a-b],A) - sage: F(f) + sage: f = A.hom([a+b,a-b],A) # optional - sage.rings.finite_rings + sage: F(f) # optional - sage.rings.finite_rings Generic endomorphism of Free Zinbiel algebra on generators (Z[x], Z[y]) over Multivariate Polynomial Ring in a, b over Finite Field of size 5 - sage: F(f)(a * F(A)(x)) + sage: F(f)(a * F(A)(x)) # optional - sage.rings.finite_rings (a+b)*Z[x] """ rank = 9 @@ -705,7 +706,7 @@ def _apply_functor_to_morphism(self, f): TESTS:: sage: R = algebras.FreeZinbiel(ZZ, 'x').construction()[0] - sage: R(ZZ.hom(GF(3))) # indirect doctest + sage: R(ZZ.hom(GF(3))) # indirect doctest # optional - sage.rings.finite_rings Generic morphism: From: Free Zinbiel algebra on generators (Z[x],) over Integer Ring diff --git a/src/sage/algebras/group_algebra.py b/src/sage/algebras/group_algebra.py index e16b0c08a21..38698c5f00d 100644 --- a/src/sage/algebras/group_algebra.py +++ b/src/sage/algebras/group_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.groups sage.modules r""" Group algebras diff --git a/src/sage/algebras/hall_algebra.py b/src/sage/algebras/hall_algebra.py index 3492ba5e073..1da3c8f397e 100644 --- a/src/sage/algebras/hall_algebra.py +++ b/src/sage/algebras/hall_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Hall Algebras diff --git a/src/sage/algebras/iwahori_hecke_algebra.py b/src/sage/algebras/iwahori_hecke_algebra.py index 0b6696af043..abd613791d3 100644 --- a/src/sage/algebras/iwahori_hecke_algebra.py +++ b/src/sage/algebras/iwahori_hecke_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Iwahori-Hecke Algebras diff --git a/src/sage/algebras/nil_coxeter_algebra.py b/src/sage/algebras/nil_coxeter_algebra.py index 862fdc3b97e..32d9de8638e 100644 --- a/src/sage/algebras/nil_coxeter_algebra.py +++ b/src/sage/algebras/nil_coxeter_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Nil-Coxeter Algebra """ diff --git a/src/sage/algebras/octonion_algebra.pyx b/src/sage/algebras/octonion_algebra.pyx index aef4f54aa9d..85984dff57c 100644 --- a/src/sage/algebras/octonion_algebra.pyx +++ b/src/sage/algebras/octonion_algebra.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules """ Octonion Algebras diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 920056787c6..8a57893dc7f 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Orlik-Solomon Algebras """ @@ -545,10 +546,10 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): Lets start with the action of `S_3` on the rank `2` braid matroid:: - sage: M = matroids.CompleteGraphic(3) - sage: M.groundset() + sage: M = matroids.CompleteGraphic(3) # optional - sage.graphs + sage: M.groundset() # optional - sage.graphs frozenset({0, 1, 2}) - sage: G = SymmetricGroup(3) + sage: G = SymmetricGroup(3) # optional - sage.groups Calling elements ``g`` of ``G`` on an element `i` of `\{1, 2, 3\}` defines the action we want, but since the groundset is `\{0, 1, 2\}` @@ -560,30 +561,30 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): Now that we have defined an action we can create the invariant, and get its basis:: - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G, on_groundset)) - sage: OSG.basis() + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G, on_groundset)) # optional - sage.graphs sage.groups + sage: OSG.basis() # optional - sage.graphs sage.groups Finite family {0: B[0], 1: B[1]} - sage: [OSG.lift(b) for b in OSG.basis()] + sage: [OSG.lift(b) for b in OSG.basis()] # optional - sage.graphs sage.groups [OS{}, OS{0} + OS{1} + OS{2}] Since it is invariant, the action of any ``g`` in ``G`` is trivial:: - sage: x = OSG.an_element(); x + sage: x = OSG.an_element(); x # optional - sage.graphs sage.groups 2*B[0] + 2*B[1] - sage: g = G.an_element(); g + sage: g = G.an_element(); g # optional - sage.graphs sage.groups (2,3) - sage: g * x + sage: g * x # optional - sage.graphs sage.groups 2*B[0] + 2*B[1] - sage: x = OSG.random_element() - sage: g = G.random_element() - sage: g * x == x + sage: x = OSG.random_element() # optional - sage.graphs sage.groups + sage: g = G.random_element() # optional - sage.graphs sage.groups + sage: g * x == x # optional - sage.graphs sage.groups True The underlying ambient module is the Orlik-Solomon algebra, which is accessible via :meth:`ambient()`:: - sage: M.orlik_solomon_algebra(QQ) is OSG.ambient() + sage: M.orlik_solomon_algebra(QQ) is OSG.ambient() # optional - sage.graphs sage.groups True There is not much structure here, so lets look at a bigger example. @@ -591,53 +592,53 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): easier, we'll start the indexing at `1` so that the `S_6` action on the groundset is simply calling `g`:: - sage: M = matroids.CompleteGraphic(4); M.groundset() + sage: M = matroids.CompleteGraphic(4); M.groundset() # optional - sage.graphs frozenset({0, 1, 2, 3, 4, 5}) - sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] - sage: M = Matroid(bases=new_bases); M.groundset() + sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] # optional - sage.graphs + sage: M = Matroid(bases=new_bases); M.groundset() # optional - sage.graphs frozenset({1, 2, 3, 4, 5, 6}) - sage: G = SymmetricGroup(6) - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) - sage: OSG.basis() + sage: G = SymmetricGroup(6) # optional - sage.groups + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) # optional - sage.graphs sage.groups + sage: OSG.basis() # optional - sage.graphs sage.groups Finite family {0: B[0], 1: B[1]} - sage: [OSG.lift(b) for b in OSG.basis()] + sage: [OSG.lift(b) for b in OSG.basis()] # optional - sage.graphs sage.groups [OS{}, OS{1} + OS{2} + OS{3} + OS{4} + OS{5} + OS{6}] - sage: (OSG.basis()[1])^2 + sage: (OSG.basis()[1])^2 # optional - sage.graphs sage.groups 0 - sage: 5 * OSG.basis()[1] + sage: 5 * OSG.basis()[1] # optional - sage.graphs sage.groups 5*B[1] Next, we look at the same matroid but with an `S_3 \times S_3` action (here realized as a Young subgroup of `S_6`):: - sage: H = G.young_subgroup([3, 3]) - sage: OSH = M.orlik_solomon_algebra(QQ, invariant=H) - sage: OSH.basis() + sage: H = G.young_subgroup([3, 3]) # optional - sage.graphs sage.groups + sage: OSH = M.orlik_solomon_algebra(QQ, invariant=H) # optional - sage.graphs sage.groups + sage: OSH.basis() # optional - sage.graphs sage.groups Finite family {0: B[0], 1: B[1], 2: B[2]} - sage: [OSH.lift(b) for b in OSH.basis()] + sage: [OSH.lift(b) for b in OSH.basis()] # optional - sage.graphs sage.groups [OS{}, OS{4} + OS{5} + OS{6}, OS{1} + OS{2} + OS{3}] We implement an `S_4` action on the vertices:: - sage: M = matroids.CompleteGraphic(4) - sage: G = SymmetricGroup(4) - sage: edge_map = {i: M.groundset_to_edges([i])[0][:2] + sage: M = matroids.CompleteGraphic(4) # optional - sage.graphs + sage: G = SymmetricGroup(4) # optional - sage.groups + sage: edge_map = {i: M.groundset_to_edges([i])[0][:2] # optional - sage.graphs ....: for i in M.groundset()} - sage: inv_map = {v: k for k, v in edge_map.items()} + sage: inv_map = {v: k for k, v in edge_map.items()} # optional - sage.graphs sage: def vert_action(g, x): ....: a, b = edge_map[x] ....: return inv_map[tuple(sorted([g(a+1)-1, g(b+1)-1]))] - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G, vert_action)) - sage: B = OSG.basis() - sage: [OSG.lift(b) for b in B] + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G, vert_action)) # optional - sage.graphs sage.groups + sage: B = OSG.basis() # optional - sage.graphs sage.groups + sage: [OSG.lift(b) for b in B] # optional - sage.graphs sage.groups [OS{}, OS{0} + OS{1} + OS{2} + OS{3} + OS{4} + OS{5}] We use this to describe the Young subgroup `S_2 \times S_2` action:: - sage: H = G.young_subgroup([2,2]) - sage: OSH = M.orlik_solomon_algebra(QQ, invariant=(H, vert_action)) - sage: B = OSH.basis() - sage: [OSH.lift(b) for b in B] + sage: H = G.young_subgroup([2,2]) # optional - sage.graphs sage.groups + sage: OSH = M.orlik_solomon_algebra(QQ, invariant=(H, vert_action)) # optional - sage.graphs sage.groups + sage: B = OSH.basis() # optional - sage.graphs sage.groups + sage: [OSH.lift(b) for b in B] # optional - sage.graphs sage.groups [OS{}, OS{5}, OS{1} + OS{2} + OS{3} + OS{4}, OS{0}, -1/2*OS{1, 2} + OS{1, 5} - 1/2*OS{3, 4} + OS{3, 5}, OS{0, 5}, OS{0, 1} + OS{0, 2} + OS{0, 3} + OS{0, 4}, @@ -645,7 +646,7 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): We demonstrate the algebra structure:: - sage: matrix([[b*bp for b in B] for bp in B]) + sage: matrix([[b*bp for b in B] for bp in B]) # optional - sage.graphs sage.groups [ B[0] B[1] B[2] B[3] B[4] B[5] B[6] B[7]] [ B[1] 0 2*B[4] B[5] 0 0 2*B[7] 0] [ B[2] -2*B[4] 0 B[6] 0 -2*B[7] 0 0] @@ -668,12 +669,12 @@ def __init__(self, R, M, G, action_on_groundset=None, *args, **kwargs): EXAMPLES:: - sage: M = matroids.CompleteGraphic(4) - sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] - sage: M = Matroid(bases=new_bases) - sage: G = SymmetricGroup(6) - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) - sage: TestSuite(OSG).run() + sage: M = matroids.CompleteGraphic(4) # optional - sage.graphs + sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] # optional - sage.graphs + sage: M = Matroid(bases=new_bases) # optional - sage.graphs + sage: G = SymmetricGroup(6) # optional - sage.groups + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) # optional - sage.graphs sage.groups + sage: TestSuite(OSG).run() # optional - sage.graphs sage.groups """ ordering = kwargs.pop('ordering', None) OS = OrlikSolomonAlgebra(R, M, ordering) @@ -756,16 +757,16 @@ def _basis_action(self, g, f): EXAMPLES:: - sage: M = matroids.CompleteGraphic(3) - sage: M.groundset() + sage: M = matroids.CompleteGraphic(3) # optional - sage.graphs + sage: M.groundset() # optional - sage.graphs frozenset({0, 1, 2}) - sage: G = SymmetricGroup(3) - sage: def on_groundset(g,x): + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: def on_groundset(g, x): ....: return g(x+1)-1 - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G,on_groundset)) + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G,on_groundset)) # optional - sage.graphs sage.groups sage: act = lambda g: (OSG._basis_action(g,frozenset({0,1})), ....: OSG._basis_action(g,frozenset({0,2}))) - sage: [act(g) for g in G] + sage: [act(g) for g in G] # optional - sage.graphs sage.groups [(OS{0, 1}, OS{0, 2}), (-OS{0, 2}, OS{0, 1} - OS{0, 2}), (-OS{0, 1} + OS{0, 2}, -OS{0, 1}), @@ -775,26 +776,26 @@ def _basis_action(self, g, f): We also check that the ordering is respected:: - sage: fset = frozenset({1,2}) - sage: OS1 = M.orlik_solomon_algebra(QQ) - sage: OS1.subset_image(fset) + sage: fset = frozenset({1,2}) # optional - sage.graphs sage.groups + sage: OS1 = M.orlik_solomon_algebra(QQ) # optional - sage.graphs sage.groups + sage: OS1.subset_image(fset) # optional - sage.graphs sage.groups -OS{0, 1} + OS{0, 2} - sage: OS2 = M.orlik_solomon_algebra(QQ, range(2,-1,-1)) - sage: OS2.subset_image(fset) + sage: OS2 = M.orlik_solomon_algebra(QQ, range(2,-1,-1)) # optional - sage.graphs sage.groups + sage: OS2.subset_image(fset) # optional - sage.graphs sage.groups OS{1, 2} - sage: OSG2 = M.orlik_solomon_algebra(QQ, + sage: OSG2 = M.orlik_solomon_algebra(QQ, # optional - sage.graphs sage.groups ....: invariant=(G,on_groundset), ....: ordering=range(2,-1,-1)) - sage: g = G.an_element(); g + sage: g = G.an_element(); g # optional - sage.graphs sage.groups (2,3) This choice of ``g`` acting on this choice of ``fset`` reverses the sign:: - sage: OSG._basis_action(g, fset) + sage: OSG._basis_action(g, fset) # optional - sage.graphs sage.groups OS{0, 1} - OS{0, 2} - sage: OSG2._basis_action(g, fset) + sage: OSG2._basis_action(g, fset) # optional - sage.graphs sage.groups -OS{1, 2} """ OS = self._ambient diff --git a/src/sage/algebras/orlik_terao.py b/src/sage/algebras/orlik_terao.py index 55fd2bdb641..f7728124ec3 100644 --- a/src/sage/algebras/orlik_terao.py +++ b/src/sage/algebras/orlik_terao.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Orlik-Terao Algebras """ diff --git a/src/sage/algebras/q_commuting_polynomials.py b/src/sage/algebras/q_commuting_polynomials.py index a50b2335787..670e890ecd8 100644 --- a/src/sage/algebras/q_commuting_polynomials.py +++ b/src/sage/algebras/q_commuting_polynomials.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" `q`-Commuting Polynomials diff --git a/src/sage/algebras/q_system.py b/src/sage/algebras/q_system.py index f7d495aac50..c39a97db88c 100644 --- a/src/sage/algebras/q_system.py +++ b/src/sage/algebras/q_system.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.combinat sage.modules r""" Q-Systems diff --git a/src/sage/algebras/quantum_clifford.py b/src/sage/algebras/quantum_clifford.py index 2b85615cf20..3a414418c52 100644 --- a/src/sage/algebras/quantum_clifford.py +++ b/src/sage/algebras/quantum_clifford.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Quantum Clifford Algebras diff --git a/src/sage/algebras/quantum_groups/fock_space.py b/src/sage/algebras/quantum_groups/fock_space.py index 3352f143a7c..965247f858f 100644 --- a/src/sage/algebras/quantum_groups/fock_space.py +++ b/src/sage/algebras/quantum_groups/fock_space.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.combinat sage.modules r""" Fock Space diff --git a/src/sage/algebras/quantum_matrix_coordinate_algebra.py b/src/sage/algebras/quantum_matrix_coordinate_algebra.py index 1579896fa86..64b29c82a45 100644 --- a/src/sage/algebras/quantum_matrix_coordinate_algebra.py +++ b/src/sage/algebras/quantum_matrix_coordinate_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Quantum Matrix Coordinate Algebras diff --git a/src/sage/algebras/quaternion_algebra.py b/src/sage/algebras/quaternion_algebra.py index 0f577bbd0b9..bb617738cdc 100644 --- a/src/sage/algebras/quaternion_algebra.py +++ b/src/sage/algebras/quaternion_algebra.py @@ -1,3 +1,5 @@ +# sage.doctest: optional - sage.modules + ############################################################ # Backwards compatible unpickling ############################################################ diff --git a/src/sage/algebras/quaternion_algebra_element.py b/src/sage/algebras/quaternion_algebra_element.py index 48c1c9871ec..aa4f349f1da 100644 --- a/src/sage/algebras/quaternion_algebra_element.py +++ b/src/sage/algebras/quaternion_algebra_element.py @@ -1,3 +1,5 @@ +# sage.doctest: optional - sage.modules + ####################################################################### # Backward compatible unpickle functions ####################################################################### diff --git a/src/sage/algebras/rational_cherednik_algebra.py b/src/sage/algebras/rational_cherednik_algebra.py index 3b85c1e13a3..d17c415f027 100644 --- a/src/sage/algebras/rational_cherednik_algebra.py +++ b/src/sage/algebras/rational_cherednik_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Rational Cherednik Algebras """ diff --git a/src/sage/algebras/schur_algebra.py b/src/sage/algebras/schur_algebra.py index ff960e56dd9..0329c502fc1 100644 --- a/src/sage/algebras/schur_algebra.py +++ b/src/sage/algebras/schur_algebra.py @@ -1,3 +1,4 @@ +# optional - sage.combinat sage.modules r""" Schur algebras for `GL_n` diff --git a/src/sage/algebras/shuffle_algebra.py b/src/sage/algebras/shuffle_algebra.py index 5d383f8dfab..50d43f2a8f7 100644 --- a/src/sage/algebras/shuffle_algebra.py +++ b/src/sage/algebras/shuffle_algebra.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# optional - sage.combinat sage.modules r""" Shuffle algebras diff --git a/src/sage/algebras/splitting_algebra.py b/src/sage/algebras/splitting_algebra.py index 3b0dfce4586..57bbf71b64e 100644 --- a/src/sage/algebras/splitting_algebra.py +++ b/src/sage/algebras/splitting_algebra.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# optional - sage.modules r""" Splitting Algebras diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index 7c4d444f81c..ba94cf6311b 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.combinat sage.modules r""" The Steenrod algebra diff --git a/src/sage/algebras/steenrod/steenrod_algebra_bases.py b/src/sage/algebras/steenrod/steenrod_algebra_bases.py index c289b284fe1..367c854249e 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_bases.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_bases.py @@ -132,12 +132,12 @@ def convert_to_milnor_matrix(n, basis, p=2, generic='auto'): EXAMPLES:: sage: from sage.algebras.steenrod.steenrod_algebra_bases import convert_to_milnor_matrix - sage: convert_to_milnor_matrix(5, 'adem') # indirect doctest + sage: convert_to_milnor_matrix(5, 'adem') # indirect doctest # optional - sage.modules sage.rings.finite_rings [0 1] [1 1] - sage: convert_to_milnor_matrix(45, 'milnor') + sage: convert_to_milnor_matrix(45, 'milnor') # optional - sage.modules sage.rings.finite_rings 111 x 111 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries) - sage: convert_to_milnor_matrix(12,'wall') + sage: convert_to_milnor_matrix(12,'wall') # optional - sage.modules sage.rings.finite_rings [1 0 0 1 0 0 0] [1 1 0 0 0 1 0] [0 1 0 1 0 0 0] @@ -149,15 +149,15 @@ def convert_to_milnor_matrix(n, basis, p=2, generic='auto'): The function takes an optional argument, the prime `p` over which to work:: - sage: convert_to_milnor_matrix(17,'adem',3) + sage: convert_to_milnor_matrix(17,'adem',3) # optional - sage.modules sage.rings.finite_rings [0 0 1 1] [0 0 0 1] [1 1 1 1] [0 1 0 1] - sage: convert_to_milnor_matrix(48,'adem',5) + sage: convert_to_milnor_matrix(48,'adem',5) # optional - sage.modules sage.rings.finite_rings [0 1] [1 1] - sage: convert_to_milnor_matrix(36,'adem',3) + sage: convert_to_milnor_matrix(36,'adem',3) # optional - sage.modules sage.rings.finite_rings [0 0 1] [0 1 0] [1 2 0] @@ -206,7 +206,7 @@ def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): EXAMPLES:: sage: from sage.algebras.steenrod.steenrod_algebra_bases import convert_from_milnor_matrix, convert_to_milnor_matrix - sage: convert_from_milnor_matrix(12,'wall') + sage: convert_from_milnor_matrix(12,'wall') # optional - sage.modules sage.rings.finite_rings [1 0 0 1 0 0 0] [0 0 1 1 0 0 0] [0 0 0 1 0 1 1] @@ -214,10 +214,10 @@ def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): [1 0 1 0 1 0 0] [1 1 1 0 0 0 0] [1 0 1 0 1 0 1] - sage: convert_from_milnor_matrix(38,'serre_cartan') + sage: convert_from_milnor_matrix(38,'serre_cartan') # optional - sage.modules sage.rings.finite_rings 72 x 72 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries) - sage: x = convert_to_milnor_matrix(20,'wood_y') - sage: y = convert_from_milnor_matrix(20,'wood_y') + sage: x = convert_to_milnor_matrix(20,'wood_y') # optional - sage.modules sage.rings.finite_rings + sage: y = convert_from_milnor_matrix(20,'wood_y') # optional - sage.modules sage.rings.finite_rings sage: x*y [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] @@ -240,7 +240,7 @@ def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): The function takes an optional argument, the prime `p` over which to work:: - sage: convert_from_milnor_matrix(17,'adem',3) + sage: convert_from_milnor_matrix(17,'adem',3) # optional - sage.modules sage.rings.finite_rings [2 1 1 2] [0 2 0 1] [1 2 0 0] diff --git a/src/sage/algebras/tensor_algebra.py b/src/sage/algebras/tensor_algebra.py index 664027ee6ae..6054ef8f6c5 100644 --- a/src/sage/algebras/tensor_algebra.py +++ b/src/sage/algebras/tensor_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Tensor Algebras diff --git a/src/sage/algebras/weyl_algebra.py b/src/sage/algebras/weyl_algebra.py index efb148bb5b3..142136d2232 100644 --- a/src/sage/algebras/weyl_algebra.py +++ b/src/sage/algebras/weyl_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Weyl Algebras diff --git a/src/sage/algebras/yangian.py b/src/sage/algebras/yangian.py index 55bb61fccf5..2b9702fa247 100644 --- a/src/sage/algebras/yangian.py +++ b/src/sage/algebras/yangian.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Yangians diff --git a/src/sage/algebras/yokonuma_hecke_algebra.py b/src/sage/algebras/yokonuma_hecke_algebra.py index df474b8d4f7..8651e5d32bd 100644 --- a/src/sage/algebras/yokonuma_hecke_algebra.py +++ b/src/sage/algebras/yokonuma_hecke_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules """ Yokonuma-Hecke Algebras From 1bddc6b40312479e222980c2ce89ea62223f7384 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 9 Jun 2023 00:55:41 -0700 Subject: [PATCH 104/463] More # optional --- .../algebras/hecke_algebras/ariki_koike_algebra.py | 2 +- .../algebras/hecke_algebras/cubic_hecke_algebra.py | 2 +- .../algebras/hecke_algebras/cubic_hecke_matrix_rep.py | 2 +- src/sage/algebras/jordan_algebra.py | 1 + .../abelian_lie_conformal_algebra.py | 1 + .../affine_lie_conformal_algebra.py | 1 + .../bosonic_ghosts_lie_conformal_algebra.py | 1 + .../fermionic_ghosts_lie_conformal_algebra.py | 1 + .../finitely_freely_generated_lca.py | 1 + .../free_bosons_lie_conformal_algebra.py | 1 + .../free_fermions_lie_conformal_algebra.py | 1 + .../freely_generated_lie_conformal_algebra.py | 1 + .../graded_lie_conformal_algebra.py | 1 + .../lie_conformal_algebras/lie_conformal_algebra.py | 1 + .../lie_conformal_algebra_element.py | 1 + .../lie_conformal_algebra_with_basis.py | 1 + .../lie_conformal_algebra_with_structure_coefs.py | 1 + .../n2_lie_conformal_algebra.py | 1 + .../neveu_schwarz_lie_conformal_algebra.py | 1 + .../virasoro_lie_conformal_algebra.py | 1 + .../weyl_lie_conformal_algebra.py | 1 + .../algebras/quantum_groups/ace_quantum_onsager.py | 1 + src/sage/algebras/quantum_groups/quantum_group_gap.py | 11 +++++++---- src/sage/algebras/quantum_groups/representations.py | 1 + src/sage/algebras/shuffle_algebra.py | 2 +- src/sage/algebras/steenrod/steenrod_algebra_mult.py | 1 + 26 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py index cf1c7a04c39..15a0566747c 100644 --- a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py +++ b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.combinat sage.modules r""" Ariki-Koike Algebras diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py index 29d444e745f..a1c175e9151 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.combinat sage.groups sage.modules r""" Cubic Hecke Algebras diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py b/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py index ef8ba7316c9..ceda4ec816b 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules r""" Cubic Hecke matrix representations diff --git a/src/sage/algebras/jordan_algebra.py b/src/sage/algebras/jordan_algebra.py index 81c40105f8a..0e3a05b4026 100644 --- a/src/sage/algebras/jordan_algebra.py +++ b/src/sage/algebras/jordan_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Jordan Algebras diff --git a/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py index aa8b71901e1..d1efd6e21f2 100644 --- a/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Abelian Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py index 9fdf888fe39..5b7aea16317 100644 --- a/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Affine Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py index 178493b13e8..7367bab5c4d 100644 --- a/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Bosonic Ghosts Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py index e6bca4de671..4a21da4370b 100644 --- a/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Fermionic Ghosts Super Lie Conformal Algebra 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 9077ef8f6a2..4aaf9da36eb 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 @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Finitely and Freely Generated Lie Conformal Algebras. diff --git a/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py index 53952f38c91..9008a9770ad 100644 --- a/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Free Bosons Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py index 8cc6533b781..83f7bdc0698 100644 --- a/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Free Fermions Super Lie Conformal Algebra. diff --git a/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py index 8fa5460d29a..21fc30d393b 100644 --- a/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Freely Generated Lie Conformal Algebras diff --git a/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py index 35863aece41..a2f1eb8fdf1 100644 --- a/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Graded Lie Conformal Algebras diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py index 1007488e165..16758675fdd 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py index 723ae5c385a..ccf3ce24111 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Lie Conformal Algebra Element diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py index ae4882dbad0..3b3e3674897 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Lie Conformal Algebras With Basis diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py index 7581daf0ddb..89f7ecc0483 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Lie Conformal Algebras With Structure Coefficients diff --git a/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py index 045bfb6e57a..3d02419cc18 100644 --- a/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules sage.rings.number_field r""" N=2 Super Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py index 8f5756f993f..45e28ab3a3c 100644 --- a/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Neveu-Schwarz Super Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py index cc11ec06a0a..6c16820f412 100644 --- a/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Virasoro Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py index 343ee8a66f9..07c6007e0a4 100644 --- a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Weyl Lie Conformal Algebra diff --git a/src/sage/algebras/quantum_groups/ace_quantum_onsager.py b/src/sage/algebras/quantum_groups/ace_quantum_onsager.py index 91138258e5a..4d2a8386980 100644 --- a/src/sage/algebras/quantum_groups/ace_quantum_onsager.py +++ b/src/sage/algebras/quantum_groups/ace_quantum_onsager.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Alternating Central Extension Quantum Onsager Algebra diff --git a/src/sage/algebras/quantum_groups/quantum_group_gap.py b/src/sage/algebras/quantum_groups/quantum_group_gap.py index 8925c047916..4998af7b588 100644 --- a/src/sage/algebras/quantum_groups/quantum_group_gap.py +++ b/src/sage/algebras/quantum_groups/quantum_group_gap.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - gap_package_quagroup +# sage.doctest: optional - gap_package_quagroup sage.combinat sage.libs.gap sage.modules """ Quantum Groups Using GAP's QuaGroup Package @@ -21,7 +21,12 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +import re + +from copy import copy + from sage.misc.lazy_attribute import lazy_attribute +from sage.misc.lazy_import import lazy_import from sage.misc.cachefunc import cached_method from sage.structure.parent import Parent from sage.structure.element import Element @@ -33,7 +38,6 @@ from sage.combinat.root_system.cartan_type import CartanType from sage.libs.gap.libgap import libgap from sage.features.gap import GapPackage -from sage.graphs.digraph import DiGraph from sage.rings.rational_field import QQ from sage.categories.algebras import Algebras from sage.categories.cartesian_product import cartesian_product @@ -44,8 +48,7 @@ from sage.categories.morphism import Morphism from sage.categories.rings import Rings -from copy import copy -import re +lazy_import('sage.graphs.digraph', 'DiGraph') class QuaGroupModuleElement(Element): diff --git a/src/sage/algebras/quantum_groups/representations.py b/src/sage/algebras/quantum_groups/representations.py index b874d264669..19a35b0aa53 100644 --- a/src/sage/algebras/quantum_groups/representations.py +++ b/src/sage/algebras/quantum_groups/representations.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Quantum Group Representations diff --git a/src/sage/algebras/shuffle_algebra.py b/src/sage/algebras/shuffle_algebra.py index 50d43f2a8f7..d137e2bc9d6 100644 --- a/src/sage/algebras/shuffle_algebra.py +++ b/src/sage/algebras/shuffle_algebra.py @@ -1,4 +1,4 @@ -# optional - sage.combinat sage.modules +# sage.doctest: optional - sage.combinat sage.modules r""" Shuffle algebras diff --git a/src/sage/algebras/steenrod/steenrod_algebra_mult.py b/src/sage/algebras/steenrod/steenrod_algebra_mult.py index 1fb52aba028..35c06d9f711 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_mult.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_mult.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Multiplication for elements of the Steenrod algebra From c78b53caee3fa98e9d86c392e09ad420b3b6d756 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 17:42:47 -0700 Subject: [PATCH 105/463] sage.algebras: More # optional --- src/sage/algebras/free_algebra_quotient.py | 2 +- src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py | 1 + src/sage/algebras/schur_algebra.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/algebras/free_algebra_quotient.py b/src/sage/algebras/free_algebra_quotient.py index d79b9a2ac47..9ac3706444d 100644 --- a/src/sage/algebras/free_algebra_quotient.py +++ b/src/sage/algebras/free_algebra_quotient.py @@ -25,7 +25,7 @@ sage: r = len(mons) sage: M = MatrixSpace(QQ,r) sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), -....: M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ] + ....: M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ] sage: H2. = A.quotient(mons, mats) sage: H2 == loads(dumps(H2)) True diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py b/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py index 7c2fe4a2210..159ab06db3a 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari (for factorization) r""" Cubic Hecke Base Rings diff --git a/src/sage/algebras/schur_algebra.py b/src/sage/algebras/schur_algebra.py index 0329c502fc1..9356d18cd4b 100644 --- a/src/sage/algebras/schur_algebra.py +++ b/src/sage/algebras/schur_algebra.py @@ -1,4 +1,4 @@ -# optional - sage.combinat sage.modules +# sage.doctest: optional - sage.combinat sage.modules r""" Schur algebras for `GL_n` From 4fef2a5a0ef42aad72c87e0e8fe9e196d35da9b6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 10:51:37 -0700 Subject: [PATCH 106/463] More # optional --- .../finite_dimensional_algebra.py | 4 ++-- .../finite_dimensional_algebra_element.pyx | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py index 67625148ecd..ed6c762ac23 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py @@ -814,7 +814,7 @@ def maximal_ideal(self): sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) - sage: B.maximal_ideal() + sage: B.maximal_ideal() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: algebra is not local @@ -860,7 +860,7 @@ def primary_decomposition(self): sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) - sage: B.primary_decomposition() + sage: B.primary_decomposition() # optional - sage.libs.pari [Morphism from Finite-dimensional algebra of degree 3 over Rational Field to Finite-dimensional algebra of degree 1 over Rational Field diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx index d0724bca028..b51f5ed4f7a 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx @@ -642,12 +642,12 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) - sage: B(0).minimal_polynomial() + sage: B(0).minimal_polynomial() # optional - sage.libs.pari x sage: b = B.random_element() - sage: f = b.minimal_polynomial(); f # random + sage: f = b.minimal_polynomial(); f # random # optional - sage.libs.pari x^3 + 1/2*x^2 - 7/16*x + 1/16 - sage: f(b) == 0 + sage: f(b) == 0 # optional - sage.libs.pari True """ A = self.parent() @@ -673,12 +673,12 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) - sage: B(0).characteristic_polynomial() + sage: B(0).characteristic_polynomial() # optional - sage.libs.pari x^3 sage: b = B.random_element() - sage: f = b.characteristic_polynomial(); f # random + sage: f = b.characteristic_polynomial(); f # random # optional - sage.libs.pari x^3 - 8*x^2 + 16*x - sage: f(b) == 0 + sage: f(b) == 0 # optional - sage.libs.pari True """ return self.matrix().characteristic_polynomial() From a9fdb2224a3e35bb2e4020c950b1ee2ed4276084 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 23:46:46 -0700 Subject: [PATCH 107/463] src/sage/algebras/free_algebra.py: Use lazy_import --- src/sage/algebras/free_algebra.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index eaddfc54e5a..ea4e2707e67 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -149,6 +149,7 @@ from sage.structure.factory import UniqueFactory from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.ring import Algebra from sage.categories.algebras_with_basis import AlgebrasWithBasis @@ -156,6 +157,8 @@ from sage.combinat.words.word import Word from sage.structure.category_object import normalize_names +lazy_import('sage.algebras.letterplace.free_algebra_letterplace', 'FreeAlgebra_letterplace') + class FreeAlgebraFactory(UniqueFactory): """ @@ -362,8 +365,7 @@ def is_FreeAlgebra(x): True """ - from sage.algebras.letterplace.free_algebra_letterplace import FreeAlgebra_letterplace - return isinstance(x, (FreeAlgebra_generic,FreeAlgebra_letterplace)) + return isinstance(x, (FreeAlgebra_generic, FreeAlgebra_letterplace)) class FreeAlgebra_generic(CombinatorialFreeModule, Algebra): From 445721d621620feb36d3ccb6f9a35fb7ae4bc02c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 23:47:37 -0700 Subject: [PATCH 108/463] More # optional --- src/sage/algebras/free_algebra_quotient.py | 1 + src/sage/algebras/splitting_algebra.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/algebras/free_algebra_quotient.py b/src/sage/algebras/free_algebra_quotient.py index 9ac3706444d..e54d92ae482 100644 --- a/src/sage/algebras/free_algebra_quotient.py +++ b/src/sage/algebras/free_algebra_quotient.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules """ Finite dimensional free algebra quotients diff --git a/src/sage/algebras/splitting_algebra.py b/src/sage/algebras/splitting_algebra.py index 57bbf71b64e..8e6d35e7c1b 100644 --- a/src/sage/algebras/splitting_algebra.py +++ b/src/sage/algebras/splitting_algebra.py @@ -1,4 +1,4 @@ -# optional - sage.modules +# sage.doctest: optional - sage.libs.pari sage.modules r""" Splitting Algebras From aa70cd75243ee4743c458114a687f00eda173446 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 12 Jun 2023 20:59:16 -0700 Subject: [PATCH 109/463] More # optional --- .../finite_dimensional_algebra_morphism.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py index eea375c01d0..5f6512baccf 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py @@ -86,9 +86,9 @@ def _repr_(self): sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: I = A.maximal_ideal() - sage: q = A.quotient_map(I) - sage: q._repr_() + sage: I = A.maximal_ideal() # optional - sage.libs.pari + sage: q = A.quotient_map(I) # optional - sage.libs.pari + sage: q._repr_() # optional - sage.libs.pari 'Morphism from Finite-dimensional algebra of degree 2 over Rational Field to Finite-dimensional algebra of degree 1 over Rational Field given by matrix\n[1]\n[0]' """ return "Morphism from {} to {} given by matrix\n{}".format( @@ -100,9 +100,9 @@ def __call__(self, x): sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: I = A.maximal_ideal() - sage: q = A.quotient_map(I) - sage: q(0) == 0 and q(1) == 1 + sage: I = A.maximal_ideal() # optional - sage.libs.pari + sage: q = A.quotient_map(I) # optional - sage.libs.pari + sage: q(0) == 0 and q(1) == 1 # optional - sage.libs.pari True """ x = self.domain()(x) @@ -182,10 +182,10 @@ def inverse_image(self, I): sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: I = A.maximal_ideal() - sage: q = A.quotient_map(I) - sage: B = q.codomain() - sage: q.inverse_image(B.zero_ideal()) == I + sage: I = A.maximal_ideal() # optional - sage.libs.pari + sage: q = A.quotient_map(I) # optional - sage.libs.pari + sage: B = q.codomain() # optional - sage.libs.pari + sage: q.inverse_image(B.zero_ideal()) == I # optional - sage.libs.pari True """ coker_I = I.basis_matrix().transpose().kernel().basis_matrix().transpose() From 017f8bf14432565a9749e432f61281ebf10a1d23 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 30 Jun 2023 18:57:29 -0700 Subject: [PATCH 110/463] ./sage -fixdoctests --long --distribution 'sagemath-modules' --probe sage.rings.finite_rings,sage.libs.pari --overwrite src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx --- .../finite_dimensional_algebra_element.pyx | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx index b51f5ed4f7a..f953a9fab7c 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx @@ -61,20 +61,20 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), ....: Matrix([[0,1], [0,0]])]) - sage: A(17) # optional - sage.rings.finite_rings + sage: A(17) 2*e0 - sage: A([1,1]) # optional - sage.rings.finite_rings + sage: A([1,1]) e0 + e1 """ def __init__(self, A, elt=None, check=True): """ TESTS:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), ....: Matrix([[0,1], [0,0]])]) - sage: A(QQ(4)) # optional - sage.rings.finite_rings + sage: A(QQ(4)) Traceback (most recent call last): ... TypeError: elt should be a vector, a matrix, or an element of the base field @@ -290,9 +290,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), ....: Matrix([[0,1], [0,0]])]) - sage: A(1) # optional - sage.rings.finite_rings + sage: A(1) e0 """ s = " " @@ -327,9 +327,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), ....: Matrix([[0,1], [0,0]])]) - sage: latex(A(1)) # indirect doctest # optional - sage.rings.finite_rings + sage: latex(A(1)) # indirect doctest \left(\begin{array}{rr} 1 & 0 \\ 0 & 1 @@ -369,13 +369,13 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), ....: Matrix([[0,1], [0,0]])]) - sage: A(2) == 2 # optional - sage.rings.finite_rings + sage: A(2) == 2 True - sage: A(2) == 3 # optional - sage.rings.finite_rings + sage: A(2) == 3 False - sage: A(2) == GF(5)(2) # optional - sage.rings.finite_rings + sage: A(2) == GF(5)(2) # needs sage.rings.finite_rings False sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), @@ -389,13 +389,13 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): the algebra corresponds to the standard monomials of the relation ideal, when the algebra is considered as a quotient of a path algebra. :: - sage: A(1) > 0 # optional - sage.rings.finite_rings + sage: A(1) > 0 True - sage: A(1) < 0 # optional - sage.rings.finite_rings + sage: A(1) < 0 False - sage: A(1) >= 0 # optional - sage.rings.finite_rings + sage: A(1) >= 0 True - sage: A(1) <= 0 # optional - sage.rings.finite_rings + sage: A(1) <= 0 False """ return richcmp(self._vector, right._vector, op) @@ -404,9 +404,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), ....: Matrix([[0,1], [0,0]])]) - sage: A.basis()[0] + A.basis()[1] # optional - sage.rings.finite_rings + sage: A.basis()[0] + A.basis()[1] e0 + e1 """ return self._parent.element_class(self._parent, self._vector + other._vector) @@ -415,9 +415,9 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): """ EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1,0], [0,1]]), ....: Matrix([[0,1], [0,0]])]) - sage: A.basis()[0] - A.basis()[1] # optional - sage.rings.finite_rings + sage: A.basis()[0] - A.basis()[1] e0 + 2*e1 """ return self._parent.element_class(self._parent, self._vector - other._vector) @@ -642,12 +642,12 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) - sage: B(0).minimal_polynomial() # optional - sage.libs.pari + sage: B(0).minimal_polynomial() # needs sage.libs.pari x sage: b = B.random_element() - sage: f = b.minimal_polynomial(); f # random # optional - sage.libs.pari + sage: f = b.minimal_polynomial(); f # random # needs sage.libs.pari x^3 + 1/2*x^2 - 7/16*x + 1/16 - sage: f(b) == 0 # optional - sage.libs.pari + sage: f(b) == 0 # needs sage.libs.pari True """ A = self.parent() @@ -673,12 +673,12 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) - sage: B(0).characteristic_polynomial() # optional - sage.libs.pari + sage: B(0).characteristic_polynomial() # needs sage.libs.pari x^3 sage: b = B.random_element() - sage: f = b.characteristic_polynomial(); f # random # optional - sage.libs.pari + sage: f = b.characteristic_polynomial(); f # random # needs sage.libs.pari x^3 - 8*x^2 + 16*x - sage: f(b) == 0 # optional - sage.libs.pari + sage: f(b) == 0 # needs sage.libs.pari True """ return self.matrix().characteristic_polynomial() From 6f704455414c78e2ddfbecf0f9460bf68eb539f6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 1 Jul 2023 17:45:47 -0700 Subject: [PATCH 111/463] ./sage -fixdoctests --long --distribution 'sagemath-modules' --only-tags --probe sage.rings.finite_rings --overwrite src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py --- .../finite_dimensional_algebra.py | 142 +++++++++--------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py index ed6c762ac23..448c1916aed 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py @@ -57,10 +57,10 @@ class FiniteDimensionalAlgebra(UniqueRepresentation, Algebra): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]); A Finite-dimensional algebra of degree 2 over Finite Field of size 3 - sage: TestSuite(A).run() # optional - sage.rings.finite_rings + sage: TestSuite(A).run() sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), @@ -70,13 +70,13 @@ class FiniteDimensionalAlgebra(UniqueRepresentation, Algebra): TESTS:: - sage: A.category() # optional - sage.rings.finite_rings + sage: A.category() Category of finite dimensional magmatic algebras with basis over Finite Field of size 3 - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])], ....: assume_associative=True) - sage: A.category() # optional - sage.rings.finite_rings + sage: A.category() Category of finite dimensional associative algebras with basis over Finite Field of size 3 """ @@ -89,47 +89,47 @@ def __classcall_private__(cls, k, table, names='e', assume_associative=False, TESTS:: sage: table = [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])] - sage: A1 = FiniteDimensionalAlgebra(GF(3), table) # optional - sage.rings.finite_rings - sage: A2 = FiniteDimensionalAlgebra(GF(3), table, names='e') # optional - sage.rings.finite_rings - sage: A3 = FiniteDimensionalAlgebra(GF(3), table, names=['e0', 'e1']) # optional - sage.rings.finite_rings - sage: A1 is A2 and A2 is A3 # optional - sage.rings.finite_rings + sage: A1 = FiniteDimensionalAlgebra(GF(3), table) + sage: A2 = FiniteDimensionalAlgebra(GF(3), table, names='e') + sage: A3 = FiniteDimensionalAlgebra(GF(3), table, names=['e0', 'e1']) + sage: A1 is A2 and A2 is A3 True The ``assume_associative`` keyword is built into the category:: sage: from sage.categories.magmatic_algebras import MagmaticAlgebras - sage: cat = MagmaticAlgebras(GF(3)).FiniteDimensional().WithBasis() # optional - sage.rings.finite_rings - sage: A1 = FiniteDimensionalAlgebra(GF(3), table, # optional - sage.rings.finite_rings + sage: cat = MagmaticAlgebras(GF(3)).FiniteDimensional().WithBasis() + sage: A1 = FiniteDimensionalAlgebra(GF(3), table, ....: category=cat.Associative()) - sage: A2 = FiniteDimensionalAlgebra(GF(3), table, assume_associative=True) # optional - sage.rings.finite_rings - sage: A1 is A2 # optional - sage.rings.finite_rings + sage: A2 = FiniteDimensionalAlgebra(GF(3), table, assume_associative=True) + sage: A1 is A2 True Uniqueness depends on the category:: - sage: cat = Algebras(GF(3)).FiniteDimensional().WithBasis() # optional - sage.rings.finite_rings - sage: A1 = FiniteDimensionalAlgebra(GF(3), table) # optional - sage.rings.finite_rings - sage: A2 = FiniteDimensionalAlgebra(GF(3), table, category=cat) # optional - sage.rings.finite_rings - sage: A1 == A2 # optional - sage.rings.finite_rings + sage: cat = Algebras(GF(3)).FiniteDimensional().WithBasis() + sage: A1 = FiniteDimensionalAlgebra(GF(3), table) + sage: A2 = FiniteDimensionalAlgebra(GF(3), table, category=cat) + sage: A1 == A2 False - sage: A1 is A2 # optional - sage.rings.finite_rings + sage: A1 is A2 False Checking that equality is still as expected:: - sage: A = FiniteDimensionalAlgebra(GF(3), table) # optional - sage.rings.finite_rings - sage: B = FiniteDimensionalAlgebra(GF(5), [Matrix([0])]) # optional - sage.rings.finite_rings - sage: A == A # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), table) + sage: B = FiniteDimensionalAlgebra(GF(5), [Matrix([0])]) + sage: A == A True - sage: B == B # optional - sage.rings.finite_rings + sage: B == B True - sage: A == B # optional - sage.rings.finite_rings + sage: A == B False - sage: A != A # optional - sage.rings.finite_rings + sage: A != A False - sage: B != B # optional - sage.rings.finite_rings + sage: B != B False - sage: A != B # optional - sage.rings.finite_rings + sage: A != B True """ n = len(table) @@ -161,17 +161,17 @@ def __init__(self, k, table, names='e', category=None): sage: TestSuite(A).run() - sage: B = FiniteDimensionalAlgebra(GF(7), [Matrix([1])]) # optional - sage.rings.finite_rings - sage: B # optional - sage.rings.finite_rings + sage: B = FiniteDimensionalAlgebra(GF(7), [Matrix([1])]) + sage: B Finite-dimensional algebra of degree 1 over Finite Field of size 7 - sage: TestSuite(B).run() # optional - sage.rings.finite_rings + sage: TestSuite(B).run() sage: C = FiniteDimensionalAlgebra(CC, [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]) sage: C Finite-dimensional algebra of degree 2 over Complex Field with 53 bits of precision sage: TestSuite(C).run() - sage: FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]])]) # optional - sage.rings.finite_rings + sage: FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]])]) Traceback (most recent call last): ... ValueError: input is not a multiplication table @@ -204,15 +204,15 @@ def _coerce_map_from_(self, S): """ TESTS:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: A.has_coerce_map_from(ZZ) # optional - sage.rings.finite_rings + sage: A.has_coerce_map_from(ZZ) True - sage: A.has_coerce_map_from(GF(3)) # optional - sage.rings.finite_rings + sage: A.has_coerce_map_from(GF(3)) True - sage: A.has_coerce_map_from(GF(5)) # optional - sage.rings.finite_rings + sage: A.has_coerce_map_from(GF(5)) # needs sage.rings.finite_rings False - sage: A.has_coerce_map_from(QQ) # optional - sage.rings.finite_rings + sage: A.has_coerce_map_from(QQ) False """ return S == self or (self.base_ring().has_coerce_map_from(S) and self.is_unitary()) @@ -270,9 +270,9 @@ def ngens(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: A.ngens() # optional - sage.rings.finite_rings + sage: A.ngens() 2 """ return len(self._table) @@ -286,9 +286,9 @@ def gen(self, i): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: A.gen(0) # optional - sage.rings.finite_rings + sage: A.gen(0) e0 """ return self.element_class(self, [j == i for j in range(self.ngens())]) @@ -300,9 +300,9 @@ def basis(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: A.basis() # optional - sage.rings.finite_rings + sage: A.basis() Family (e0, e1) """ from sage.sets.family import Family @@ -314,9 +314,9 @@ def __iter__(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: list(A) # optional - sage.rings.finite_rings + sage: list(A) [0, e0, 2*e0, e1, e0 + e1, 2*e0 + e1, 2*e1, e0 + 2*e1, 2*e0 + 2*e1] This is used in the :class:`Testsuite`'s when ``self`` is @@ -335,9 +335,9 @@ def _ideal_class_(self, n=0): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: A._ideal_class_() # optional - sage.rings.finite_rings + sage: A._ideal_class_() """ return FiniteDimensionalAlgebraIdeal @@ -349,9 +349,9 @@ def table(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: A.table() # optional - sage.rings.finite_rings + sage: A.table() ( [1 0] [0 1] [0 1], [0 0] @@ -400,9 +400,9 @@ def base_extend(self, F): EXAMPLES:: - sage: C = FiniteDimensionalAlgebra(GF(2), [Matrix([1])]) # optional - sage.rings.finite_rings - sage: k. = GF(4) # optional - sage.rings.finite_rings - sage: C.base_extend(k) # optional - sage.rings.finite_rings + sage: C = FiniteDimensionalAlgebra(GF(2), [Matrix([1])]) + sage: k. = GF(4) # needs sage.rings.finite_rings + sage: C.base_extend(k) # needs sage.rings.finite_rings Finite-dimensional algebra of degree 1 over Finite Field in y of size 2^2 """ # Base extension of the multiplication table is done by __classcall_private__. @@ -414,9 +414,9 @@ def cardinality(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [2, 3]])]) - sage: A.cardinality() # optional - sage.rings.finite_rings + sage: A.cardinality() 49 sage: B = FiniteDimensionalAlgebra(RR, [Matrix([[1, 0], [0, 1]]), @@ -452,9 +452,9 @@ def ideal(self, gens=None, given_by_matrix=False, side=None): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: A.ideal(A([1,1])) # optional - sage.rings.finite_rings + sage: A.ideal(A([1,1])) Ideal (e0 + e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3 """ @@ -525,9 +525,9 @@ def is_finite(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(7), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [2, 3]])]) - sage: A.is_finite() # optional - sage.rings.finite_rings + sage: A.is_finite() True sage: B = FiniteDimensionalAlgebra(RR, [Matrix([[1, 0], [0, 1]]), @@ -623,8 +623,8 @@ def is_zero(self): sage: A.is_zero() True - sage: B = FiniteDimensionalAlgebra(GF(7), [Matrix([0])]) # optional - sage.rings.finite_rings - sage: B.is_zero() # optional - sage.rings.finite_rings + sage: B = FiniteDimensionalAlgebra(GF(7), [Matrix([0])]) + sage: B.is_zero() False """ return self.degree() == 0 @@ -680,9 +680,9 @@ def random_element(self, *args, **kwargs): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: A.random_element() # random # optional - sage.rings.finite_rings + sage: A.random_element() # random e0 + 2*e1 sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), @@ -759,16 +759,16 @@ def quotient_map(self, ideal): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: q0 = A.quotient_map(A.zero_ideal()); q0 # optional - sage.rings.finite_rings + sage: q0 = A.quotient_map(A.zero_ideal()); q0 Morphism from Finite-dimensional algebra of degree 2 over Finite Field of size 3 to Finite-dimensional algebra of degree 2 over Finite Field of size 3 given by matrix [1 0] [0 1] - sage: q1 = A.quotient_map(A.ideal(A.gen(1))); q1 # optional - sage.rings.finite_rings + sage: q1 = A.quotient_map(A.ideal(A.gen(1))); q1 Morphism from Finite-dimensional algebra of degree 2 over Finite Field of size 3 to Finite-dimensional algebra of degree 1 over Finite Field of size 3 @@ -805,16 +805,16 @@ def maximal_ideal(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: A.maximal_ideal() # optional - sage.rings.finite_rings + sage: A.maximal_ideal() # needs sage.rings.finite_rings Ideal (0, e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3 sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) - sage: B.maximal_ideal() # optional - sage.libs.pari + sage: B.maximal_ideal() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: algebra is not local @@ -848,9 +848,9 @@ def primary_decomposition(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: A.primary_decomposition() # optional - sage.rings.finite_rings + sage: A.primary_decomposition() # needs sage.rings.finite_rings [Morphism from Finite-dimensional algebra of degree 2 over Finite Field of size 3 to Finite-dimensional algebra of degree 2 over Finite Field of size 3 @@ -860,7 +860,7 @@ def primary_decomposition(self): sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), ....: Matrix([[0,1,0], [0,0,0], [0,0,0]]), ....: Matrix([[0,0,0], [0,0,0], [0,0,1]])]) - sage: B.primary_decomposition() # optional - sage.libs.pari + sage: B.primary_decomposition() # needs sage.libs.pari [Morphism from Finite-dimensional algebra of degree 3 over Rational Field to Finite-dimensional algebra of degree 1 over Rational Field @@ -916,9 +916,9 @@ def maximal_ideals(self): EXAMPLES:: - sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), # optional - sage.rings.finite_rings + sage: A = FiniteDimensionalAlgebra(GF(3), [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: A.maximal_ideals() # optional - sage.rings.finite_rings + sage: A.maximal_ideals() # needs sage.rings.finite_rings [Ideal (e1) of Finite-dimensional algebra of degree 2 over Finite Field of size 3] sage: B = FiniteDimensionalAlgebra(QQ, []) From 88c05fd59806e6312847e3dad4ca57849a823740 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 2 Jul 2023 01:00:55 -0700 Subject: [PATCH 112/463] sage.algebras: Update # optional / # needs --- src/sage/algebras/algebra.py | 2 +- .../algebras/clifford_algebra_element.pyx | 1 + src/sage/algebras/group_algebra.py | 2 +- src/sage/algebras/octonion_algebra.pyx | 12 +- src/sage/algebras/orlik_solomon.py | 188 ++++++++++-------- src/sage/algebras/orlik_terao.py | 32 ++- 6 files changed, 137 insertions(+), 100 deletions(-) diff --git a/src/sage/algebras/algebra.py b/src/sage/algebras/algebra.py index 547eee6c699..e69ea7da530 100644 --- a/src/sage/algebras/algebra.py +++ b/src/sage/algebras/algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Abstract base class for algebras """ diff --git a/src/sage/algebras/clifford_algebra_element.pyx b/src/sage/algebras/clifford_algebra_element.pyx index fc70360dab3..3ebad1013fe 100644 --- a/src/sage/algebras/clifford_algebra_element.pyx +++ b/src/sage/algebras/clifford_algebra_element.pyx @@ -945,6 +945,7 @@ cdef class CohomologyRAAGElement(CliffordAlgebraElement): EXAMPLES:: + sage: # needs sage.graphs sage: C4 = graphs.CycleGraph(4) sage: A = groups.misc.RightAngledArtin(C4) sage: H = A.cohomology() diff --git a/src/sage/algebras/group_algebra.py b/src/sage/algebras/group_algebra.py index 38698c5f00d..eaffe7538b7 100644 --- a/src/sage/algebras/group_algebra.py +++ b/src/sage/algebras/group_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.groups sage.modules +# sage.doctest: needs sage.groups sage.modules r""" Group algebras diff --git a/src/sage/algebras/octonion_algebra.pyx b/src/sage/algebras/octonion_algebra.pyx index 85984dff57c..ee69aca6a7e 100644 --- a/src/sage/algebras/octonion_algebra.pyx +++ b/src/sage/algebras/octonion_algebra.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules """ Octonion Algebras @@ -416,7 +416,7 @@ cdef class Octonion_generic(AlgebraElement): sage: O = OctonionAlgebra(QQ, 1, 3, 7) sage: elt = sum(i * b for i, b in enumerate(O.basis(), start=2)) - sage: elt.norm() + sage: elt.norm() # needs sage.symbolic 2*sqrt(-61) sage: elt = sum(O.basis()) sage: elt.norm() @@ -439,7 +439,7 @@ cdef class Octonion_generic(AlgebraElement): sage: O = OctonionAlgebra(QQ, 1, 3, 7) sage: elt = sum(i * b for i, b in enumerate(O.basis(), start=2)) - sage: elt.abs() + sage: elt.abs() # needs sage.symbolic 2*sqrt(-61) sage: elt = sum(O.basis()) sage: elt.abs() @@ -577,10 +577,10 @@ cdef class Octonion(Octonion_generic): sage: O = OctonionAlgebra(QQ) sage: elt = sum(i * b for i, b in enumerate(O.basis(), start=2)) - sage: elt.norm() + sage: elt.norm() # needs sage.symbolic 2*sqrt(71) sage: elt = sum(O.basis()) - sage: elt.norm() + sage: elt.norm() # needs sage.symbolic 2*sqrt(2) """ return self.vec.norm() @@ -751,7 +751,7 @@ class OctonionAlgebra(UniqueRepresentation, Parent): EXAMPLES:: sage: O = OctonionAlgebra(QQ) - sage: TestSuite(O).run() + sage: TestSuite(O).run() # needs sage.symbolic sage: O = OctonionAlgebra(QQ, 1, 3, 7) sage: TestSuite(O).run() diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 8a57893dc7f..f92a93c7e21 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules r""" Orlik-Solomon Algebras """ @@ -115,9 +115,10 @@ def __init__(self, R, M, ordering=None): We check on the matroid associated to the graph with 3 vertices and 2 edges between each vertex:: + sage: # needs sage.graphs sage: G = Graph([[1,2],[1,2],[2,3],[2,3],[1,3],[1,3]], multiedges=True) - sage: M = Matroid(G) - sage: OS = M.orlik_solomon_algebra(QQ) + sage: MG = Matroid(G) + sage: OS = MG.orlik_solomon_algebra(QQ) sage: elts = OS.some_elements() + list(OS.algebra_generators()) sage: TestSuite(OS).run(elements=elts) """ @@ -254,10 +255,11 @@ def product_on_basis(self, a, b): Let us check that `e_{s_1} e_{s_2} \cdots e_{s_k} = e_S` for any subset `S = \{ s_1 < s_2 < \cdots < s_k \}` of the ground set:: + sage: # needs sage.graphs sage: G = Graph([[1,2],[1,2],[2,3],[3,4],[4,2]], multiedges=True) - sage: M = Matroid(G).regular_matroid() - sage: E = M.groundset_list() - sage: OS = M.orlik_solomon_algebra(ZZ) + sage: MG = Matroid(G).regular_matroid() + sage: E = MG.groundset_list() + sage: OS = MG.orlik_solomon_algebra(ZZ) sage: G = OS.algebra_generators() sage: import itertools sage: def test_prod(F): @@ -327,31 +329,33 @@ def subset_image(self, S): ([2, 5], -OS{0, 2} + OS{0, 5}) ([4, 5], -OS{3, 4} + OS{3, 5}) + sage: # needs sage.graphs sage: M4 = matroids.CompleteGraphic(4) - sage: OS = M4.orlik_solomon_algebra(QQ) - sage: OS.subset_image(frozenset({2,3,4})) + sage: OSM4 = M4.orlik_solomon_algebra(QQ) + sage: OSM4.subset_image(frozenset({2,3,4})) OS{0, 2, 3} + OS{0, 3, 4} An example of a custom ordering:: + sage: # needs sage.graphs sage: G = Graph([[3, 4], [4, 1], [1, 2], [2, 3], [3, 5], [5, 6], [6, 3]]) - sage: M = Matroid(G) + sage: MG = Matroid(G) sage: s = [(5, 6), (1, 2), (3, 5), (2, 3), (1, 4), (3, 6), (3, 4)] - sage: sorted([sorted(c) for c in M.circuits()]) + sage: sorted([sorted(c) for c in MG.circuits()]) [[(1, 2), (1, 4), (2, 3), (3, 4)], [(3, 5), (3, 6), (5, 6)]] - sage: OS = M.orlik_solomon_algebra(QQ, ordering=s) - sage: OS.subset_image(frozenset([])) + sage: OSMG = MG.orlik_solomon_algebra(QQ, ordering=s) + sage: OSMG.subset_image(frozenset([])) OS{} - sage: OS.subset_image(frozenset([(1,2),(3,4),(1,4),(2,3)])) + sage: OSMG.subset_image(frozenset([(1,2),(3,4),(1,4),(2,3)])) 0 - sage: OS.subset_image(frozenset([(2,3),(1,2),(3,4)])) + sage: OSMG.subset_image(frozenset([(2,3),(1,2),(3,4)])) OS{(1, 2), (2, 3), (3, 4)} - sage: OS.subset_image(frozenset([(1,4),(3,4),(2,3),(3,6),(5,6)])) + sage: OSMG.subset_image(frozenset([(1,4),(3,4),(2,3),(3,6),(5,6)])) -OS{(1, 2), (1, 4), (2, 3), (3, 6), (5, 6)} + OS{(1, 2), (1, 4), (3, 4), (3, 6), (5, 6)} - OS{(1, 2), (2, 3), (3, 4), (3, 6), (5, 6)} - sage: OS.subset_image(frozenset([(1,4),(3,4),(2,3),(3,6),(3,5)])) + sage: OSMG.subset_image(frozenset([(1,4),(3,4),(2,3),(3,6),(3,5)])) OS{(1, 2), (1, 4), (2, 3), (3, 5), (5, 6)} - OS{(1, 2), (1, 4), (2, 3), (3, 6), (5, 6)} + OS{(1, 2), (1, 4), (3, 4), (3, 5), (5, 6)} @@ -361,34 +365,36 @@ def subset_image(self, S): TESTS:: + sage: # needs sage.graphs sage: G = Graph([[1,2],[1,2],[2,3],[2,3],[1,3],[1,3]], multiedges=True) - sage: M = Matroid(G) + sage: MG = Matroid(G) sage: sorted([sorted(c) for c in M.circuits()]) [[0, 1], [0, 2, 4], [0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [2, 3], [4, 5]] - sage: OS = M.orlik_solomon_algebra(QQ) - sage: OS.subset_image(frozenset([])) + sage: OSMG = MG.orlik_solomon_algebra(QQ) + sage: OSMG.subset_image(frozenset([])) OS{} - sage: OS.subset_image(frozenset([1, 2, 3])) + sage: OSMG.subset_image(frozenset([1, 2, 3])) 0 - sage: OS.subset_image(frozenset([1, 3, 5])) + sage: OSMG.subset_image(frozenset([1, 3, 5])) 0 - sage: OS.subset_image(frozenset([1, 2])) + sage: OSMG.subset_image(frozenset([1, 2])) OS{0, 2} - sage: OS.subset_image(frozenset([3, 4])) + sage: OSMG.subset_image(frozenset([3, 4])) -OS{0, 2} + OS{0, 4} - sage: OS.subset_image(frozenset([1, 5])) + sage: OSMG.subset_image(frozenset([1, 5])) OS{0, 4} + sage: # needs sage.graphs sage: G = Graph([[1,2],[1,2],[2,3],[3,4],[4,2]], multiedges=True) - sage: M = Matroid(G) - sage: sorted([sorted(c) for c in M.circuits()]) + sage: MG = Matroid(G) + sage: sorted([sorted(c) for c in MG.circuits()]) [[0, 1], [2, 3, 4]] - sage: OS = M.orlik_solomon_algebra(QQ) - sage: OS.subset_image(frozenset([])) + sage: OSMG = MG.orlik_solomon_algebra(QQ) + sage: OSMG.subset_image(frozenset([])) OS{} - sage: OS.subset_image(frozenset([1, 3, 4])) + sage: OSMG.subset_image(frozenset([1, 3, 4])) -OS{0, 2, 3} + OS{0, 2, 4} We check on a non-standard ordering:: @@ -453,6 +459,7 @@ def as_gca(self): EXAMPLES:: + sage: # needs sage.geometry.polyhedron sage: H = hyperplane_arrangements.braid(3) sage: O = H.orlik_solomon_algebra(QQ) sage: O.as_gca() @@ -477,6 +484,7 @@ def as_gca(self): TESTS:: + sage: # needs sage.geometry.polyhedron sage: H = hyperplane_arrangements.Catalan(3,QQ).cone() sage: O = H.orlik_solomon_algebra(QQ) sage: A = O.as_gca() @@ -516,6 +524,7 @@ def as_cdga(self): EXAMPLES:: + sage: # needs sage.geometry.polyhedron sage: H = hyperplane_arrangements.braid(3) sage: O = H.orlik_solomon_algebra(QQ) sage: O.as_cdga() @@ -546,10 +555,11 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): Lets start with the action of `S_3` on the rank `2` braid matroid:: - sage: M = matroids.CompleteGraphic(3) # optional - sage.graphs - sage: M.groundset() # optional - sage.graphs + sage: # needs sage.graphs + sage: M = matroids.CompleteGraphic(3) + sage: M.groundset() frozenset({0, 1, 2}) - sage: G = SymmetricGroup(3) # optional - sage.groups + sage: G = SymmetricGroup(3) # needs sage.groups Calling elements ``g`` of ``G`` on an element `i` of `\{1, 2, 3\}` defines the action we want, but since the groundset is `\{0, 1, 2\}` @@ -561,30 +571,33 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): Now that we have defined an action we can create the invariant, and get its basis:: - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G, on_groundset)) # optional - sage.graphs sage.groups - sage: OSG.basis() # optional - sage.graphs sage.groups + sage: # needs sage.graphs sage.groups + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G, on_groundset)) + sage: OSG.basis() Finite family {0: B[0], 1: B[1]} - sage: [OSG.lift(b) for b in OSG.basis()] # optional - sage.graphs sage.groups + sage: [OSG.lift(b) for b in OSG.basis()] [OS{}, OS{0} + OS{1} + OS{2}] Since it is invariant, the action of any ``g`` in ``G`` is trivial:: - sage: x = OSG.an_element(); x # optional - sage.graphs sage.groups + sage: # needs sage.graphs sage.groups + sage: x = OSG.an_element(); x 2*B[0] + 2*B[1] - sage: g = G.an_element(); g # optional - sage.graphs sage.groups + sage: g = G.an_element(); g (2,3) - sage: g * x # optional - sage.graphs sage.groups + sage: g * x 2*B[0] + 2*B[1] - sage: x = OSG.random_element() # optional - sage.graphs sage.groups - sage: g = G.random_element() # optional - sage.graphs sage.groups - sage: g * x == x # optional - sage.graphs sage.groups + sage: # needs sage.graphs sage.groups + sage: x = OSG.random_element() + sage: g = G.random_element() + sage: g * x == x True The underlying ambient module is the Orlik-Solomon algebra, which is accessible via :meth:`ambient()`:: - sage: M.orlik_solomon_algebra(QQ) is OSG.ambient() # optional - sage.graphs sage.groups + sage: M.orlik_solomon_algebra(QQ) is OSG.ambient() # needs sage.graphs sage.groups True There is not much structure here, so lets look at a bigger example. @@ -592,53 +605,53 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): easier, we'll start the indexing at `1` so that the `S_6` action on the groundset is simply calling `g`:: - sage: M = matroids.CompleteGraphic(4); M.groundset() # optional - sage.graphs + sage: M = matroids.CompleteGraphic(4); M.groundset() # needs sage.graphs frozenset({0, 1, 2, 3, 4, 5}) - sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] # optional - sage.graphs - sage: M = Matroid(bases=new_bases); M.groundset() # optional - sage.graphs + sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] # needs sage.graphs + sage: M = Matroid(bases=new_bases); M.groundset() # needs sage.graphs frozenset({1, 2, 3, 4, 5, 6}) - sage: G = SymmetricGroup(6) # optional - sage.groups - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) # optional - sage.graphs sage.groups - sage: OSG.basis() # optional - sage.graphs sage.groups + sage: G = SymmetricGroup(6) # needs sage.groups + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) # needs sage.graphs sage.groups + sage: OSG.basis() # needs sage.graphs sage.groups Finite family {0: B[0], 1: B[1]} - sage: [OSG.lift(b) for b in OSG.basis()] # optional - sage.graphs sage.groups + sage: [OSG.lift(b) for b in OSG.basis()] # needs sage.graphs sage.groups [OS{}, OS{1} + OS{2} + OS{3} + OS{4} + OS{5} + OS{6}] - sage: (OSG.basis()[1])^2 # optional - sage.graphs sage.groups + sage: (OSG.basis()[1])^2 # needs sage.graphs sage.groups 0 - sage: 5 * OSG.basis()[1] # optional - sage.graphs sage.groups + sage: 5 * OSG.basis()[1] # needs sage.graphs sage.groups 5*B[1] Next, we look at the same matroid but with an `S_3 \times S_3` action (here realized as a Young subgroup of `S_6`):: - sage: H = G.young_subgroup([3, 3]) # optional - sage.graphs sage.groups - sage: OSH = M.orlik_solomon_algebra(QQ, invariant=H) # optional - sage.graphs sage.groups - sage: OSH.basis() # optional - sage.graphs sage.groups + sage: H = G.young_subgroup([3, 3]) # needs sage.graphs sage.groups + sage: OSH = M.orlik_solomon_algebra(QQ, invariant=H) # needs sage.graphs sage.groups + sage: OSH.basis() # needs sage.graphs sage.groups Finite family {0: B[0], 1: B[1], 2: B[2]} - sage: [OSH.lift(b) for b in OSH.basis()] # optional - sage.graphs sage.groups + sage: [OSH.lift(b) for b in OSH.basis()] # needs sage.graphs sage.groups [OS{}, OS{4} + OS{5} + OS{6}, OS{1} + OS{2} + OS{3}] We implement an `S_4` action on the vertices:: - sage: M = matroids.CompleteGraphic(4) # optional - sage.graphs - sage: G = SymmetricGroup(4) # optional - sage.groups - sage: edge_map = {i: M.groundset_to_edges([i])[0][:2] # optional - sage.graphs + sage: M = matroids.CompleteGraphic(4) # needs sage.graphs + sage: G = SymmetricGroup(4) # needs sage.groups + sage: edge_map = {i: M.groundset_to_edges([i])[0][:2] # needs sage.graphs ....: for i in M.groundset()} - sage: inv_map = {v: k for k, v in edge_map.items()} # optional - sage.graphs + sage: inv_map = {v: k for k, v in edge_map.items()} # needs sage.graphs sage: def vert_action(g, x): ....: a, b = edge_map[x] ....: return inv_map[tuple(sorted([g(a+1)-1, g(b+1)-1]))] - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G, vert_action)) # optional - sage.graphs sage.groups - sage: B = OSG.basis() # optional - sage.graphs sage.groups - sage: [OSG.lift(b) for b in B] # optional - sage.graphs sage.groups + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G, vert_action)) # needs sage.graphs sage.groups + sage: B = OSG.basis() # needs sage.graphs sage.groups + sage: [OSG.lift(b) for b in B] # needs sage.graphs sage.groups [OS{}, OS{0} + OS{1} + OS{2} + OS{3} + OS{4} + OS{5}] We use this to describe the Young subgroup `S_2 \times S_2` action:: - sage: H = G.young_subgroup([2,2]) # optional - sage.graphs sage.groups - sage: OSH = M.orlik_solomon_algebra(QQ, invariant=(H, vert_action)) # optional - sage.graphs sage.groups - sage: B = OSH.basis() # optional - sage.graphs sage.groups - sage: [OSH.lift(b) for b in B] # optional - sage.graphs sage.groups + sage: H = G.young_subgroup([2,2]) # needs sage.graphs sage.groups + sage: OSH = M.orlik_solomon_algebra(QQ, invariant=(H, vert_action)) # needs sage.graphs sage.groups + sage: B = OSH.basis() # needs sage.graphs sage.groups + sage: [OSH.lift(b) for b in B] # needs sage.graphs sage.groups [OS{}, OS{5}, OS{1} + OS{2} + OS{3} + OS{4}, OS{0}, -1/2*OS{1, 2} + OS{1, 5} - 1/2*OS{3, 4} + OS{3, 5}, OS{0, 5}, OS{0, 1} + OS{0, 2} + OS{0, 3} + OS{0, 4}, @@ -646,7 +659,7 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): We demonstrate the algebra structure:: - sage: matrix([[b*bp for b in B] for bp in B]) # optional - sage.graphs sage.groups + sage: matrix([[b*bp for b in B] for bp in B]) # needs sage.graphs sage.groups [ B[0] B[1] B[2] B[3] B[4] B[5] B[6] B[7]] [ B[1] 0 2*B[4] B[5] 0 0 2*B[7] 0] [ B[2] -2*B[4] 0 B[6] 0 -2*B[7] 0 0] @@ -669,12 +682,12 @@ def __init__(self, R, M, G, action_on_groundset=None, *args, **kwargs): EXAMPLES:: - sage: M = matroids.CompleteGraphic(4) # optional - sage.graphs - sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] # optional - sage.graphs - sage: M = Matroid(bases=new_bases) # optional - sage.graphs - sage: G = SymmetricGroup(6) # optional - sage.groups - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) # optional - sage.graphs sage.groups - sage: TestSuite(OSG).run() # optional - sage.graphs sage.groups + sage: M = matroids.CompleteGraphic(4) # needs sage.graphs + sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] # needs sage.graphs + sage: M = Matroid(bases=new_bases) # needs sage.graphs + sage: G = SymmetricGroup(6) # needs sage.groups + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) # needs sage.graphs sage.groups + sage: TestSuite(OSG).run() # needs sage.graphs sage.groups """ ordering = kwargs.pop('ordering', None) OS = OrlikSolomonAlgebra(R, M, ordering) @@ -757,16 +770,17 @@ def _basis_action(self, g, f): EXAMPLES:: - sage: M = matroids.CompleteGraphic(3) # optional - sage.graphs - sage: M.groundset() # optional - sage.graphs + sage: # needs sage.graphs + sage: M = matroids.CompleteGraphic(3) + sage: M.groundset() frozenset({0, 1, 2}) - sage: G = SymmetricGroup(3) # optional - sage.groups + sage: G = SymmetricGroup(3) # needs sage.groups sage: def on_groundset(g, x): ....: return g(x+1)-1 - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G,on_groundset)) # optional - sage.graphs sage.groups + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G,on_groundset)) # needs sage.groups sage: act = lambda g: (OSG._basis_action(g,frozenset({0,1})), ....: OSG._basis_action(g,frozenset({0,2}))) - sage: [act(g) for g in G] # optional - sage.graphs sage.groups + sage: [act(g) for g in G] # needs sage.groups [(OS{0, 1}, OS{0, 2}), (-OS{0, 2}, OS{0, 1} - OS{0, 2}), (-OS{0, 1} + OS{0, 2}, -OS{0, 1}), @@ -776,26 +790,26 @@ def _basis_action(self, g, f): We also check that the ordering is respected:: - sage: fset = frozenset({1,2}) # optional - sage.graphs sage.groups - sage: OS1 = M.orlik_solomon_algebra(QQ) # optional - sage.graphs sage.groups - sage: OS1.subset_image(fset) # optional - sage.graphs sage.groups + sage: fset = frozenset({1,2}) # needs sage.graphs sage.groups + sage: OS1 = M.orlik_solomon_algebra(QQ) # needs sage.graphs sage.groups + sage: OS1.subset_image(fset) # needs sage.graphs sage.groups -OS{0, 1} + OS{0, 2} - sage: OS2 = M.orlik_solomon_algebra(QQ, range(2,-1,-1)) # optional - sage.graphs sage.groups - sage: OS2.subset_image(fset) # optional - sage.graphs sage.groups + sage: OS2 = M.orlik_solomon_algebra(QQ, range(2,-1,-1)) # needs sage.graphs sage.groups + sage: OS2.subset_image(fset) # needs sage.graphs sage.groups OS{1, 2} - sage: OSG2 = M.orlik_solomon_algebra(QQ, # optional - sage.graphs sage.groups + sage: OSG2 = M.orlik_solomon_algebra(QQ, # needs sage.graphs sage.groups ....: invariant=(G,on_groundset), ....: ordering=range(2,-1,-1)) - sage: g = G.an_element(); g # optional - sage.graphs sage.groups + sage: g = G.an_element(); g # needs sage.graphs sage.groups (2,3) This choice of ``g`` acting on this choice of ``fset`` reverses the sign:: - sage: OSG._basis_action(g, fset) # optional - sage.graphs sage.groups + sage: OSG._basis_action(g, fset) # needs sage.graphs sage.groups OS{0, 1} - OS{0, 2} - sage: OSG2._basis_action(g, fset) # optional - sage.graphs sage.groups + sage: OSG2._basis_action(g, fset) # needs sage.graphs sage.groups -OS{1, 2} """ OS = self._ambient diff --git a/src/sage/algebras/orlik_terao.py b/src/sage/algebras/orlik_terao.py index f7728124ec3..db493ac6b1b 100644 --- a/src/sage/algebras/orlik_terao.py +++ b/src/sage/algebras/orlik_terao.py @@ -131,10 +131,12 @@ def __init__(self, R, M, ordering=None): sage: OT = M.orlik_terao_algebra(QQ) sage: TestSuite(OT).run(elements=OT.basis()) + sage: # needs sage.graphs sage: M = matroids.CompleteGraphic(4).ternary_matroid() sage: OT = M.orlik_terao_algebra(GF(3)['t']) sage: TestSuite(OT).run(elements=OT.basis()) + sage: # needs sage.geometry.polyhedron sage: H = hyperplane_arrangements.Catalan(4).cone() sage: M = H.matroid() sage: OT = M.orlik_terao_algebra() @@ -145,6 +147,7 @@ def __init__(self, R, M, ordering=None): We check on the matroid associated to the graph with 3 vertices and 2 edges between each vertex:: + sage: # needs sage.graphs sage: G = Graph([[1,2],[1,2],[2,3],[2,3],[1,3],[1,3]], multiedges=True) sage: M = Matroid(G).regular_matroid() sage: OT = M.orlik_terao_algebra(QQ) @@ -322,6 +325,7 @@ def product_on_basis(self, a, b): Let us check that `e_{s_1} e_{s_2} \cdots e_{s_k} = e_S` for any subset `S = \{ s_1 < s_2 < \cdots < s_k \}` of the ground set:: + sage: # needs sage.graphs sage: G = Graph([[1,2],[1,2],[2,3],[3,4],[4,2]], multiedges=True) sage: M = Matroid(G).regular_matroid() sage: E = M.groundset_list() @@ -371,6 +375,7 @@ def subset_image(self, S): ([2, 5], -OT{0, 2} + OT{0, 5}) ([4, 5], -OT{3, 4} - OT{3, 5}) + sage: # needs sage.graphs sage: M4 = matroids.CompleteGraphic(4).ternary_matroid() sage: OT = M4.orlik_terao_algebra() sage: OT.subset_image(frozenset({2,3,4})) @@ -378,6 +383,7 @@ def subset_image(self, S): An example of a custom ordering:: + sage: # needs sage.graphs sage: G = Graph([[3, 4], [4, 1], [1, 2], [2, 3], [3, 5], [5, 6], [6, 3]]) sage: M = Matroid(G).regular_matroid() sage: s = [(5, 6), (1, 2), (3, 5), (2, 3), (1, 4), (3, 6), (3, 4)] @@ -405,6 +411,7 @@ def subset_image(self, S): TESTS:: + sage: # needs sage.graphs sage: G = Graph([[1,2],[1,2],[2,3],[2,3],[1,3],[1,3]], multiedges=True) sage: M = Matroid(G).regular_matroid() sage: sorted([sorted(c) for c in M.circuits()]) @@ -425,6 +432,7 @@ def subset_image(self, S): sage: OT.subset_image(frozenset([1, 5])) OT{0, 4} + sage: # needs sage.graphs sage: G = Graph([[1,2],[1,2],[2,3],[3,4],[4,2]], multiedges=True) sage: M = Matroid(G).regular_matroid() sage: sorted([sorted(c) for c in M.circuits()]) @@ -499,6 +507,7 @@ def _chi(self, X): EXAMPLES:: + sage: # needs sage.geometry.polyhedron sage: H = hyperplane_arrangements.Catalan(2).cone() sage: M = H.matroid() sage: OT = M.orlik_terao_algebra() @@ -542,7 +551,7 @@ class OrlikTeraoInvariantAlgebra(FiniteDimensionalInvariantModule): sage: M = Matroid(A) sage: M.groundset() frozenset({0, 1, 2}) - sage: G = SymmetricGroup(3) + sage: G = SymmetricGroup(3) # needs sage.groups Calling elements ``g`` of ``G`` on an element `i` of `\{1,2,3\}` defines the action we want, but since the groundset is `\{0,1,2\}` @@ -554,7 +563,8 @@ class OrlikTeraoInvariantAlgebra(FiniteDimensionalInvariantModule): Now that we have defined an action we can create the invariant, and get its basis:: - sage: OTG = M.orlik_terao_algebra(QQ, invariant = (G, on_groundset)) + sage: # needs sage.groups + sage: OTG = M.orlik_terao_algebra(QQ, invariant=(G, on_groundset)) sage: OTG.basis() Finite family {0: B[0], 1: B[1]} sage: [OTG.lift(b) for b in OTG.basis()] @@ -562,6 +572,7 @@ class OrlikTeraoInvariantAlgebra(FiniteDimensionalInvariantModule): Since it is invariant, the action of any ``g`` in ``G`` is trivial:: + sage: # needs sage.groups sage: x = OTG.an_element(); x 2*B[0] + 2*B[1] sage: g = G.an_element(); g @@ -569,6 +580,7 @@ class OrlikTeraoInvariantAlgebra(FiniteDimensionalInvariantModule): sage: g*x 2*B[0] + 2*B[1] + sage: # needs sage.groups sage: x = OTG.random_element() sage: g = G.random_element() sage: g*x == x @@ -577,11 +589,12 @@ class OrlikTeraoInvariantAlgebra(FiniteDimensionalInvariantModule): The underlying ambient module is the Orlik-Terao algebra, which is accessible via :meth:`ambient()`:: - sage: M.orlik_terao_algebra(QQ) is OTG.ambient() + sage: M.orlik_terao_algebra(QQ) is OTG.ambient() # needs sage.groups True For a bigger example, here we will look at the rank-`3` braid matroid:: + sage: # needs sage.groups sage: A = matrix([[1,1,1,0,0,0],[-1,0,0,1,1,0], ....: [0,-1,0,-1,0,1],[0,0,-1,0,-1,-1]]); A [ 1 1 1 0 0 0] @@ -591,9 +604,11 @@ class OrlikTeraoInvariantAlgebra(FiniteDimensionalInvariantModule): sage: M = Matroid(A); M.groundset() frozenset({0, 1, 2, 3, 4, 5}) sage: G = SymmetricGroup(6) - sage: OTG = M.orlik_terao_algebra(QQ, invariant = (G, on_groundset)) + sage: OTG = M.orlik_terao_algebra(QQ, invariant=(G, on_groundset)) sage: OTG.ambient() - Orlik-Terao algebra of Linear matroid of rank 3 on 6 elements represented over the Rational Field over Rational Field + Orlik-Terao algebra of + Linear matroid of rank 3 on 6 elements represented over the Rational Field + over Rational Field sage: OTG.basis() Finite family {0: B[0], 1: B[1]} sage: [OTG.lift(b) for b in OTG.basis()] @@ -606,6 +621,7 @@ def __init__(self, R, M, G, action_on_groundset=None, *args, **kwargs): EXAMPLES:: + sage: # needs sage.groups sage: A = matrix([[1,1,1,0,0,0],[-1,0,0,1,1,0],[0,-1,0,-1,0,1], ....: [0,0,-1,0,-1,-1]]) sage: M = Matroid(A); @@ -669,6 +685,7 @@ def construction(self): TESTS:: + sage: # needs sage.groups sage: A = matrix([[1,1,0],[-1,0,1],[0,-1,-1]]) sage: M = Matroid(A) sage: G = SymmetricGroup(3) @@ -697,6 +714,7 @@ def _basis_action(self, g, f): EXAMPLES:: + sage: # needs sage.groups sage: A = matrix([[1,1,0],[-1,0,1],[0,-1,-1]]) sage: M = Matroid(A) sage: M.groundset() @@ -719,6 +737,7 @@ def _basis_action(self, g, f): We also check that the ordering is respected:: + sage: # needs sage.groups sage: fset = frozenset({1,2}) sage: OT1 = M.orlik_terao_algebra(QQ) sage: OT1.subset_image(fset) @@ -727,6 +746,7 @@ def _basis_action(self, g, f): sage: OT2.subset_image(fset) OT{1, 2} + sage: # needs sage.groups sage: OTG2 = M.orlik_terao_algebra(QQ, ....: invariant=(G,on_groundset), ....: ordering=range(2,-1,-1)) @@ -735,6 +755,7 @@ def _basis_action(self, g, f): This choice of ``g`` fixes these elements:: + sage: # needs sage.groups sage: OTG._basis_action(g, fset) -OT{0, 1} + OT{0, 2} sage: OTG2._basis_action(g, fset) @@ -742,6 +763,7 @@ def _basis_action(self, g, f): TESTS:: + sage: # needs sage.groups sage: [on_groundset(g, e) for e in M.groundset()] [0, 2, 1] sage: [OTG._groundset_action(g,e) for e in M.groundset()] From 6857ee2ab51b999e267a9a9d7f65c786e5b80c70 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 6 Aug 2023 20:44:52 -0700 Subject: [PATCH 113/463] src/sage/algebras: Update file-level doctest tag --- src/sage/algebras/affine_nil_temperley_lieb.py | 2 +- src/sage/algebras/askey_wilson.py | 2 +- src/sage/algebras/associated_graded.py | 2 +- src/sage/algebras/cellular_basis.py | 2 +- src/sage/algebras/clifford_algebra.py | 2 +- src/sage/algebras/clifford_algebra_element.pyx | 2 +- src/sage/algebras/cluster_algebra.py | 2 +- src/sage/algebras/commutative_dga.py | 2 +- src/sage/algebras/down_up_algebra.py | 2 +- src/sage/algebras/exterior_algebra_groebner.pyx | 2 +- .../finite_dimensional_algebra_ideal.py | 1 + src/sage/algebras/finite_gca.py | 2 +- src/sage/algebras/free_algebra.py | 2 +- src/sage/algebras/free_algebra_element.py | 2 +- src/sage/algebras/free_algebra_quotient.py | 2 +- src/sage/algebras/free_algebra_quotient_element.py | 2 +- src/sage/algebras/free_zinbiel_algebra.py | 2 +- src/sage/algebras/hall_algebra.py | 2 +- src/sage/algebras/hecke_algebras/ariki_koike_algebra.py | 2 +- src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py | 2 +- src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py | 2 +- src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py | 2 +- src/sage/algebras/iwahori_hecke_algebra.py | 2 +- src/sage/algebras/jordan_algebra.py | 2 +- .../lie_conformal_algebras/abelian_lie_conformal_algebra.py | 2 +- .../lie_conformal_algebras/affine_lie_conformal_algebra.py | 2 +- .../bosonic_ghosts_lie_conformal_algebra.py | 2 +- .../fermionic_ghosts_lie_conformal_algebra.py | 2 +- .../lie_conformal_algebras/finitely_freely_generated_lca.py | 2 +- .../lie_conformal_algebras/free_bosons_lie_conformal_algebra.py | 2 +- .../free_fermions_lie_conformal_algebra.py | 2 +- .../freely_generated_lie_conformal_algebra.py | 2 +- .../lie_conformal_algebras/graded_lie_conformal_algebra.py | 2 +- .../algebras/lie_conformal_algebras/lie_conformal_algebra.py | 2 +- .../lie_conformal_algebras/lie_conformal_algebra_element.py | 2 +- .../lie_conformal_algebras/lie_conformal_algebra_with_basis.py | 2 +- .../lie_conformal_algebra_with_structure_coefs.py | 2 +- .../algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py | 2 +- .../neveu_schwarz_lie_conformal_algebra.py | 2 +- .../lie_conformal_algebras/virasoro_lie_conformal_algebra.py | 2 +- .../lie_conformal_algebras/weyl_lie_conformal_algebra.py | 2 +- src/sage/algebras/nil_coxeter_algebra.py | 2 +- src/sage/algebras/orlik_terao.py | 2 +- src/sage/algebras/q_commuting_polynomials.py | 2 +- src/sage/algebras/q_system.py | 2 +- src/sage/algebras/quantum_clifford.py | 2 +- src/sage/algebras/quantum_groups/ace_quantum_onsager.py | 2 +- src/sage/algebras/quantum_groups/fock_space.py | 2 +- src/sage/algebras/quantum_groups/representations.py | 2 +- src/sage/algebras/quantum_matrix_coordinate_algebra.py | 2 +- src/sage/algebras/quaternion_algebra.py | 2 +- src/sage/algebras/quaternion_algebra_element.py | 2 +- src/sage/algebras/rational_cherednik_algebra.py | 2 +- src/sage/algebras/schur_algebra.py | 2 +- src/sage/algebras/shuffle_algebra.py | 2 +- src/sage/algebras/splitting_algebra.py | 2 +- src/sage/algebras/steenrod/steenrod_algebra.py | 2 +- src/sage/algebras/steenrod/steenrod_algebra_mult.py | 2 +- src/sage/algebras/tensor_algebra.py | 2 +- src/sage/algebras/weyl_algebra.py | 2 +- src/sage/algebras/yangian.py | 2 +- src/sage/algebras/yokonuma_hecke_algebra.py | 2 +- 62 files changed, 62 insertions(+), 61 deletions(-) diff --git a/src/sage/algebras/affine_nil_temperley_lieb.py b/src/sage/algebras/affine_nil_temperley_lieb.py index 8f88e2bb3b7..1fa213bd4bc 100644 --- a/src/sage/algebras/affine_nil_temperley_lieb.py +++ b/src/sage/algebras/affine_nil_temperley_lieb.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Affine nilTemperley Lieb Algebra of type A """ diff --git a/src/sage/algebras/askey_wilson.py b/src/sage/algebras/askey_wilson.py index 1d597987c60..4943c73b36d 100644 --- a/src/sage/algebras/askey_wilson.py +++ b/src/sage/algebras/askey_wilson.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Askey-Wilson Algebras diff --git a/src/sage/algebras/associated_graded.py b/src/sage/algebras/associated_graded.py index 9afb563923b..5dd01321114 100644 --- a/src/sage/algebras/associated_graded.py +++ b/src/sage/algebras/associated_graded.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules r""" Associated Graded Algebras To Filtered Algebras diff --git a/src/sage/algebras/cellular_basis.py b/src/sage/algebras/cellular_basis.py index 62aeaa03bdd..e6e7487cba9 100644 --- a/src/sage/algebras/cellular_basis.py +++ b/src/sage/algebras/cellular_basis.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Cellular Basis ============== diff --git a/src/sage/algebras/clifford_algebra.py b/src/sage/algebras/clifford_algebra.py index 7d517534792..ed24df4abfc 100644 --- a/src/sage/algebras/clifford_algebra.py +++ b/src/sage/algebras/clifford_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules r""" Clifford Algebras diff --git a/src/sage/algebras/clifford_algebra_element.pyx b/src/sage/algebras/clifford_algebra_element.pyx index 3ebad1013fe..ce4708313b4 100644 --- a/src/sage/algebras/clifford_algebra_element.pyx +++ b/src/sage/algebras/clifford_algebra_element.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules """ Clifford algebra elements diff --git a/src/sage/algebras/cluster_algebra.py b/src/sage/algebras/cluster_algebra.py index 8a468dad0e1..bdd8164955c 100644 --- a/src/sage/algebras/cluster_algebra.py +++ b/src/sage/algebras/cluster_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.graphs sage.modules +# sage.doctest: needs sage.graphs sage.modules r""" Cluster algebras diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index 39da2cd3772..f3ef35660cc 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Commutative Differential Graded Algebras diff --git a/src/sage/algebras/down_up_algebra.py b/src/sage/algebras/down_up_algebra.py index b39c86b3d4f..d5fe1c257eb 100644 --- a/src/sage/algebras/down_up_algebra.py +++ b/src/sage/algebras/down_up_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules r""" Down-Up Algebras diff --git a/src/sage/algebras/exterior_algebra_groebner.pyx b/src/sage/algebras/exterior_algebra_groebner.pyx index ee54b5e4baf..265e9323536 100644 --- a/src/sage/algebras/exterior_algebra_groebner.pyx +++ b/src/sage/algebras/exterior_algebra_groebner.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules r""" Exterior algebras Gröbner bases diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py index 54f137e1966..15f0881bb8b 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.rings.finite_rings (because all doctests use GF) """ Ideals of Finite Algebras """ diff --git a/src/sage/algebras/finite_gca.py b/src/sage/algebras/finite_gca.py index 9c76ddf3199..f2e7d9af301 100644 --- a/src/sage/algebras/finite_gca.py +++ b/src/sage/algebras/finite_gca.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules r""" Finite dimensional graded commutative algebras diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index ea4e2707e67..70ccb24c63f 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Free algebras diff --git a/src/sage/algebras/free_algebra_element.py b/src/sage/algebras/free_algebra_element.py index f5bf4277f16..1854414e2d0 100644 --- a/src/sage/algebras/free_algebra_element.py +++ b/src/sage/algebras/free_algebra_element.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Free algebra elements diff --git a/src/sage/algebras/free_algebra_quotient.py b/src/sage/algebras/free_algebra_quotient.py index e54d92ae482..21284681549 100644 --- a/src/sage/algebras/free_algebra_quotient.py +++ b/src/sage/algebras/free_algebra_quotient.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Finite dimensional free algebra quotients diff --git a/src/sage/algebras/free_algebra_quotient_element.py b/src/sage/algebras/free_algebra_quotient_element.py index 738e5b723a3..559d4246ac0 100644 --- a/src/sage/algebras/free_algebra_quotient_element.py +++ b/src/sage/algebras/free_algebra_quotient_element.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Free algebra quotient elements diff --git a/src/sage/algebras/free_zinbiel_algebra.py b/src/sage/algebras/free_zinbiel_algebra.py index f7e2f97e50c..3f4a41ea751 100644 --- a/src/sage/algebras/free_zinbiel_algebra.py +++ b/src/sage/algebras/free_zinbiel_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Free Zinbiel Algebras diff --git a/src/sage/algebras/hall_algebra.py b/src/sage/algebras/hall_algebra.py index 1da3c8f397e..83442eabc94 100644 --- a/src/sage/algebras/hall_algebra.py +++ b/src/sage/algebras/hall_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Hall Algebras diff --git a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py index 15a0566747c..df2818d5dd5 100644 --- a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py +++ b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Ariki-Koike Algebras diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py index a1c175e9151..df4b748dca4 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.groups sage.modules +# sage.doctest: needs sage.combinat sage.groups sage.modules r""" Cubic Hecke Algebras diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py b/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py index 159ab06db3a..99e359b518f 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari (for factorization) +# sage.doctest: needs sage.libs.pari (for factorization) r""" Cubic Hecke Base Rings diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py b/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py index ceda4ec816b..49ea61b5f3a 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules r""" Cubic Hecke matrix representations diff --git a/src/sage/algebras/iwahori_hecke_algebra.py b/src/sage/algebras/iwahori_hecke_algebra.py index abd613791d3..d0141592724 100644 --- a/src/sage/algebras/iwahori_hecke_algebra.py +++ b/src/sage/algebras/iwahori_hecke_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Iwahori-Hecke Algebras diff --git a/src/sage/algebras/jordan_algebra.py b/src/sage/algebras/jordan_algebra.py index 0e3a05b4026..f783dc890c8 100644 --- a/src/sage/algebras/jordan_algebra.py +++ b/src/sage/algebras/jordan_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Jordan Algebras diff --git a/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py index d1efd6e21f2..80df46c57d3 100644 --- a/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Abelian Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py index 5b7aea16317..f5d39cacbf2 100644 --- a/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Affine Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py index 7367bab5c4d..0b0b61b4e25 100644 --- a/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Bosonic Ghosts Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py index 4a21da4370b..098644908e6 100644 --- a/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Fermionic Ghosts Super Lie Conformal Algebra 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 4aaf9da36eb..8aefdd9d3a6 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 @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Finitely and Freely Generated Lie Conformal Algebras. diff --git a/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py index 9008a9770ad..0787226252d 100644 --- a/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Free Bosons Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py index 83f7bdc0698..1e7525ae1d3 100644 --- a/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Free Fermions Super Lie Conformal Algebra. diff --git a/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py index 21fc30d393b..b26d0bb4ca0 100644 --- a/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Freely Generated Lie Conformal Algebras diff --git a/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py index a2f1eb8fdf1..c335daf98f7 100644 --- a/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Graded Lie Conformal Algebras diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py index 16758675fdd..5ca0c8f6d07 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py index ccf3ce24111..09fb63a0a4c 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Lie Conformal Algebra Element diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py index 3b3e3674897..4fef0fcf2e6 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Lie Conformal Algebras With Basis diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py index 89f7ecc0483..3c4252ce905 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Lie Conformal Algebras With Structure Coefficients diff --git a/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py index 3d02419cc18..baf7a896144 100644 --- a/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules sage.rings.number_field +# sage.doctest: needs sage.combinat sage.modules sage.rings.number_field r""" N=2 Super Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py index 45e28ab3a3c..5542b9fc097 100644 --- a/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Neveu-Schwarz Super Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py index 6c16820f412..0db2d545290 100644 --- a/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Virasoro Lie Conformal Algebra diff --git a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py index 07c6007e0a4..3c319db7ca3 100644 --- a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Weyl Lie Conformal Algebra diff --git a/src/sage/algebras/nil_coxeter_algebra.py b/src/sage/algebras/nil_coxeter_algebra.py index 32d9de8638e..b5dbd2d62c8 100644 --- a/src/sage/algebras/nil_coxeter_algebra.py +++ b/src/sage/algebras/nil_coxeter_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Nil-Coxeter Algebra """ diff --git a/src/sage/algebras/orlik_terao.py b/src/sage/algebras/orlik_terao.py index db493ac6b1b..81158f3e9b7 100644 --- a/src/sage/algebras/orlik_terao.py +++ b/src/sage/algebras/orlik_terao.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules r""" Orlik-Terao Algebras """ diff --git a/src/sage/algebras/q_commuting_polynomials.py b/src/sage/algebras/q_commuting_polynomials.py index 670e890ecd8..0b23a756fd5 100644 --- a/src/sage/algebras/q_commuting_polynomials.py +++ b/src/sage/algebras/q_commuting_polynomials.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules r""" `q`-Commuting Polynomials diff --git a/src/sage/algebras/q_system.py b/src/sage/algebras/q_system.py index c39a97db88c..74bf87c2787 100644 --- a/src/sage/algebras/q_system.py +++ b/src/sage/algebras/q_system.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Q-Systems diff --git a/src/sage/algebras/quantum_clifford.py b/src/sage/algebras/quantum_clifford.py index 3a414418c52..dc61084f2f8 100644 --- a/src/sage/algebras/quantum_clifford.py +++ b/src/sage/algebras/quantum_clifford.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules r""" Quantum Clifford Algebras diff --git a/src/sage/algebras/quantum_groups/ace_quantum_onsager.py b/src/sage/algebras/quantum_groups/ace_quantum_onsager.py index 4d2a8386980..9d983529c73 100644 --- a/src/sage/algebras/quantum_groups/ace_quantum_onsager.py +++ b/src/sage/algebras/quantum_groups/ace_quantum_onsager.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Alternating Central Extension Quantum Onsager Algebra diff --git a/src/sage/algebras/quantum_groups/fock_space.py b/src/sage/algebras/quantum_groups/fock_space.py index 965247f858f..22665746325 100644 --- a/src/sage/algebras/quantum_groups/fock_space.py +++ b/src/sage/algebras/quantum_groups/fock_space.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Fock Space diff --git a/src/sage/algebras/quantum_groups/representations.py b/src/sage/algebras/quantum_groups/representations.py index 19a35b0aa53..cb026008d6d 100644 --- a/src/sage/algebras/quantum_groups/representations.py +++ b/src/sage/algebras/quantum_groups/representations.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Quantum Group Representations diff --git a/src/sage/algebras/quantum_matrix_coordinate_algebra.py b/src/sage/algebras/quantum_matrix_coordinate_algebra.py index 64b29c82a45..c9f7e312788 100644 --- a/src/sage/algebras/quantum_matrix_coordinate_algebra.py +++ b/src/sage/algebras/quantum_matrix_coordinate_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Quantum Matrix Coordinate Algebras diff --git a/src/sage/algebras/quaternion_algebra.py b/src/sage/algebras/quaternion_algebra.py index bb617738cdc..4e92b73de69 100644 --- a/src/sage/algebras/quaternion_algebra.py +++ b/src/sage/algebras/quaternion_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules ############################################################ # Backwards compatible unpickling diff --git a/src/sage/algebras/quaternion_algebra_element.py b/src/sage/algebras/quaternion_algebra_element.py index aa4f349f1da..dbd70e25856 100644 --- a/src/sage/algebras/quaternion_algebra_element.py +++ b/src/sage/algebras/quaternion_algebra_element.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules ####################################################################### # Backward compatible unpickle functions diff --git a/src/sage/algebras/rational_cherednik_algebra.py b/src/sage/algebras/rational_cherednik_algebra.py index d17c415f027..58b3ce5441d 100644 --- a/src/sage/algebras/rational_cherednik_algebra.py +++ b/src/sage/algebras/rational_cherednik_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules """ Rational Cherednik Algebras """ diff --git a/src/sage/algebras/schur_algebra.py b/src/sage/algebras/schur_algebra.py index 9356d18cd4b..0df04485a2a 100644 --- a/src/sage/algebras/schur_algebra.py +++ b/src/sage/algebras/schur_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Schur algebras for `GL_n` diff --git a/src/sage/algebras/shuffle_algebra.py b/src/sage/algebras/shuffle_algebra.py index d137e2bc9d6..2db55513d66 100644 --- a/src/sage/algebras/shuffle_algebra.py +++ b/src/sage/algebras/shuffle_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Shuffle algebras diff --git a/src/sage/algebras/splitting_algebra.py b/src/sage/algebras/splitting_algebra.py index 8e6d35e7c1b..8913932ffac 100644 --- a/src/sage/algebras/splitting_algebra.py +++ b/src/sage/algebras/splitting_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari sage.modules +# sage.doctest: needs sage.libs.pari sage.modules r""" Splitting Algebras diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index ba94cf6311b..ce764f0a258 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" The Steenrod algebra diff --git a/src/sage/algebras/steenrod/steenrod_algebra_mult.py b/src/sage/algebras/steenrod/steenrod_algebra_mult.py index 35c06d9f711..e2d48f616b7 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_mult.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_mult.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.rings.finite_rings +# sage.doctest: needs sage.rings.finite_rings r""" Multiplication for elements of the Steenrod algebra diff --git a/src/sage/algebras/tensor_algebra.py b/src/sage/algebras/tensor_algebra.py index 6054ef8f6c5..a14ab916336 100644 --- a/src/sage/algebras/tensor_algebra.py +++ b/src/sage/algebras/tensor_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Tensor Algebras diff --git a/src/sage/algebras/weyl_algebra.py b/src/sage/algebras/weyl_algebra.py index 142136d2232..14ae670b00e 100644 --- a/src/sage/algebras/weyl_algebra.py +++ b/src/sage/algebras/weyl_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Weyl Algebras diff --git a/src/sage/algebras/yangian.py b/src/sage/algebras/yangian.py index 2b9702fa247..8e19b92ba07 100644 --- a/src/sage/algebras/yangian.py +++ b/src/sage/algebras/yangian.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.modules r""" Yangians diff --git a/src/sage/algebras/yokonuma_hecke_algebra.py b/src/sage/algebras/yokonuma_hecke_algebra.py index 8651e5d32bd..779beb95ffe 100644 --- a/src/sage/algebras/yokonuma_hecke_algebra.py +++ b/src/sage/algebras/yokonuma_hecke_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules """ Yokonuma-Hecke Algebras From 63aba2094249585afb47b197d3b6b43de4ff57ff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 7 Aug 2023 22:43:56 -0700 Subject: [PATCH 114/463] src/sage/algebras: sage -fixdoctests --only-tags --- src/sage/algebras/clifford_algebra.py | 9 +- src/sage/algebras/cluster_algebra.py | 17 +- src/sage/algebras/commutative_dga.py | 102 +++++----- .../finite_dimensional_algebra_morphism.py | 20 +- src/sage/algebras/free_algebra.py | 181 ++++++++++-------- src/sage/algebras/free_algebra_quotient.py | 2 +- src/sage/algebras/free_zinbiel_algebra.py | 26 +-- .../hecke_algebras/cubic_hecke_algebra.py | 71 +++---- .../hecke_algebras/cubic_hecke_base_ring.py | 13 +- src/sage/algebras/iwahori_hecke_algebra.py | 67 ++++--- src/sage/algebras/lie_algebras/morphism.py | 18 +- src/sage/algebras/lie_algebras/quotient.py | 9 +- .../lie_algebras/structure_coefficients.py | 4 +- src/sage/algebras/lie_algebras/subalgebra.py | 26 +-- src/sage/algebras/orlik_solomon.py | 29 +-- .../algebras/quatalg/quaternion_algebra.py | 27 +-- .../quatalg/quaternion_algebra_element.pyx | 89 +++++---- .../algebras/quaternion_algebra_element.py | 9 +- .../steenrod/steenrod_algebra_bases.py | 33 ++-- src/sage/algebras/weyl_algebra.py | 17 +- 20 files changed, 406 insertions(+), 363 deletions(-) diff --git a/src/sage/algebras/clifford_algebra.py b/src/sage/algebras/clifford_algebra.py index ed24df4abfc..ad8bd314c25 100644 --- a/src/sage/algebras/clifford_algebra.py +++ b/src/sage/algebras/clifford_algebra.py @@ -1771,11 +1771,12 @@ def interior_product_on_basis(self, a, b): Check :trac:`34694`:: - sage: E = ExteriorAlgebra(SR,'e',3) # optional - sage.symbolic - sage: E.inject_variables() # optional - sage.symbolic + sage: # needs sage.symbolic + sage: E = ExteriorAlgebra(SR,'e',3) + sage: E.inject_variables() Defining e0, e1, e2 - sage: a = (e0*e1).interior_product(e0) # optional - sage.symbolic - sage: a * e0 # optional - sage.symbolic + sage: a = (e0*e1).interior_product(e0) + sage: a * e0 -e0*e1 """ sgn = True diff --git a/src/sage/algebras/cluster_algebra.py b/src/sage/algebras/cluster_algebra.py index bdd8164955c..fa29367d014 100644 --- a/src/sage/algebras/cluster_algebra.py +++ b/src/sage/algebras/cluster_algebra.py @@ -298,15 +298,16 @@ which might not be a good idea in algebras that are too big. One workaround is to first disable F-polynomials and then recompute only the desired mutations:: - sage: A.reset_exploring_iterator(mutating_F=False) # long time - sage: v = (-1, 1, -2, 2, -1, 1, -1, 1, 1) # long time - sage: seq = A.find_g_vector(v); seq # long time random + sage: # long time + sage: A.reset_exploring_iterator(mutating_F=False) + sage: v = (-1, 1, -2, 2, -1, 1, -1, 1, 1) + sage: seq = A.find_g_vector(v); seq [1, 0, 2, 6, 5, 4, 3, 8, 1] - sage: S = A.initial_seed().mutate(seq, inplace=False) # long time - sage: v in S.g_vectors() # long time + sage: S = A.initial_seed().mutate(seq, inplace=False) + sage: v in S.g_vectors() True - sage: A.current_seed().mutate(seq) # long time - sage: A.F_polynomial((-1, 1, -2, 2, -1, 1, -1, 1, 1)) # long time + sage: A.current_seed().mutate(seq) + sage: A.F_polynomial((-1, 1, -2, 2, -1, 1, -1, 1, 1)) u0*u1^2*u2^2*u3*u4*u5*u6*u8 + ... 2*u2 + u4 + u6 + 1 @@ -2373,7 +2374,7 @@ def cluster_fan(self, depth=infinity): EXAMPLES:: sage: A = ClusterAlgebra(['A', 2]) - sage: A.cluster_fan() # optional - sage.geometry.polyhedron + sage: A.cluster_fan() # needs sage.geometry.polyhedron Rational polyhedral fan in 2-d lattice N """ seeds = self.seeds(depth=depth, mutating_F=False) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index f3ef35660cc..d1ea9b782e4 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -949,9 +949,9 @@ def __classcall__(cls, base, names=None, degrees=None, R=None, I=None, category= TESTS:: - sage: A1 = GradedCommutativeAlgebra(GF(2), 'x,y', (3, 6)) # optional - sage.rings.finite_rings - sage: A2 = GradedCommutativeAlgebra(GF(2), ['x', 'y'], [3, 6]) # optional - sage.rings.finite_rings - sage: A1 is A2 + sage: A1 = GradedCommutativeAlgebra(GF(2), 'x,y', (3, 6)) # needs sage.rings.finite_rings + sage: A2 = GradedCommutativeAlgebra(GF(2), ['x', 'y'], [3, 6]) # needs sage.rings.finite_rings + sage: A1 is A2 # needs sage.rings.finite_rings True Testing the single generator case (:trac:`25276`):: @@ -962,8 +962,8 @@ def __classcall__(cls, base, names=None, degrees=None, R=None, I=None, category= sage: A4. = GradedCommutativeAlgebra(QQ, degrees=[4]) sage: z**2 == 0 False - sage: A5. = GradedCommutativeAlgebra(GF(2)) # optional - sage.rings.finite_rings - sage: z**2 == 0 # optional - sage.rings.finite_rings + sage: A5. = GradedCommutativeAlgebra(GF(2)) # needs sage.rings.finite_rings + sage: z**2 == 0 # needs sage.rings.finite_rings False """ if names is None: @@ -1207,19 +1207,20 @@ def quotient(self, I, check=True): EXAMPLES:: - sage: A. = GradedCommutativeAlgebra(GF(5), degrees=(2, 2, 3, 4)) # optional - sage.rings.finite_rings - sage: I = A.ideal([x*t+z^2, x*y - t]) # optional - sage.rings.finite_rings - sage: B = A.quotient(I); B # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: A. = GradedCommutativeAlgebra(GF(5), degrees=(2, 2, 3, 4)) + sage: I = A.ideal([x*t+z^2, x*y - t]) + sage: B = A.quotient(I); B Graded Commutative Algebra with generators ('x', 'y', 'z', 't') in degrees (2, 2, 3, 4) with relations [x*t, x*y - t] over Finite Field of size 5 - sage: B(x*t) # optional - sage.rings.finite_rings + sage: B(x*t) 0 - sage: B(x*y) # optional - sage.rings.finite_rings + sage: B(x*y) t - sage: A.basis(7) # optional - sage.rings.finite_rings + sage: A.basis(7) [x^2*z, x*y*z, y^2*z, z*t] - sage: B.basis(7) # optional - sage.rings.finite_rings + sage: B.basis(7) [x^2*z, y^2*z, z*t] """ if check and any(not i.is_homogeneous() for i in I.gens()): @@ -1909,19 +1910,20 @@ def degree(self, total=False): EXAMPLES:: - sage: A. = GradedCommutativeAlgebra(GF(2), # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: A. = GradedCommutativeAlgebra(GF(2), ....: degrees=((1,0), (0,1), (1,1))) - sage: (a**2*b).degree() # optional - sage.rings.finite_rings + sage: (a**2*b).degree() (2, 1) - sage: (a**2*b).degree(total=True) # optional - sage.rings.finite_rings + sage: (a**2*b).degree(total=True) 3 - sage: (a**2*b + c).degree() # optional - sage.rings.finite_rings + sage: (a**2*b + c).degree() Traceback (most recent call last): ... ValueError: this element is not homogeneous - sage: (a**2*b + c).degree(total=True) # optional - sage.rings.finite_rings + sage: (a**2*b + c).degree(total=True) 3 - sage: A(0).degree() # optional - sage.rings.finite_rings + sage: A(0).degree() Traceback (most recent call last): ... ValueError: the zero element does not have a well-defined degree @@ -2388,23 +2390,23 @@ def cohomology_generators(self, max_degree): In contrast, the corresponding algebra in characteristic `p` has finitely generated cohomology:: - sage: A3. = GradedCommutativeAlgebra(GF(3), degrees=(1,2,2)) # optional - sage.rings.finite_rings - sage: B3 = A3.cdg_algebra(differential={y: a*x}) # optional - sage.rings.finite_rings - sage: B3.cohomology_generators(16) # optional - sage.rings.finite_rings + sage: A3. = GradedCommutativeAlgebra(GF(3), degrees=(1,2,2)) # needs sage.rings.finite_rings + sage: B3 = A3.cdg_algebra(differential={y: a*x}) # needs sage.rings.finite_rings + sage: B3.cohomology_generators(16) # needs sage.rings.finite_rings {1: [a], 2: [x], 3: [a*y], 5: [a*y^2], 6: [y^3]} This method works with both singly graded and multi-graded algebras:: - sage: Cs. = GradedCommutativeAlgebra(GF(2), degrees=(1,2,2,3)) # optional - sage.rings.finite_rings - sage: Ds = Cs.cdg_algebra({a:c, b:d}) # optional - sage.rings.finite_rings - sage: Ds.cohomology_generators(10) # optional - sage.rings.finite_rings + sage: Cs. = GradedCommutativeAlgebra(GF(2), degrees=(1,2,2,3)) # needs sage.rings.finite_rings + sage: Ds = Cs.cdg_algebra({a:c, b:d}) # needs sage.rings.finite_rings + sage: Ds.cohomology_generators(10) # needs sage.rings.finite_rings {2: [a^2], 4: [b^2]} - sage: Cm. = GradedCommutativeAlgebra(GF(2), # optional - sage.rings.finite_rings + sage: Cm. = GradedCommutativeAlgebra(GF(2), # needs sage.rings.finite_rings ....: degrees=((1,0), (1,1), ....: (0,2), (0,3))) - sage: Dm = Cm.cdg_algebra({a:c, b:d}) # optional - sage.rings.finite_rings - sage: Dm.cohomology_generators(10) # optional - sage.rings.finite_rings + sage: Dm = Cm.cdg_algebra({a:c, b:d}) # needs sage.rings.finite_rings + sage: Dm.cohomology_generators(10) # needs sage.rings.finite_rings {2: [a^2], 4: [b^2]} TESTS: @@ -3507,9 +3509,9 @@ def GradedCommutativeAlgebra(ring, names=None, degrees=None, max_degree=None, We can construct multi-graded rings as well. We work in characteristic 2 for a change, so the algebras here are honestly commutative:: - sage: C. = GradedCommutativeAlgebra(GF(2), # optional - sage.rings.finite_rings + sage: C. = GradedCommutativeAlgebra(GF(2), # needs sage.rings.finite_rings ....: degrees=((1,0), (1,1), (0,2), (0,3))) - sage: D = C.cdg_algebra(differential={a: c, b: d}); D # optional - sage.rings.finite_rings + sage: D = C.cdg_algebra(differential={a: c, b: d}); D # needs sage.rings.finite_rings Commutative Differential Graded Algebra with generators ('a', 'b', 'c', 'd') in degrees ((1, 0), (1, 1), (0, 2), (0, 3)) over Finite Field of size 2 with differential: @@ -3522,46 +3524,46 @@ def GradedCommutativeAlgebra(ring, names=None, degrees=None, max_degree=None, Use tuples, lists, vectors, or elements of additive abelian groups to specify degrees:: - sage: D.basis(3) # basis in total degree 3 # optional - sage.rings.finite_rings + sage: D.basis(3) # basis in total degree 3 # needs sage.rings.finite_rings [a^3, a*b, a*c, d] - sage: D.basis((1,2)) # basis in degree (1,2) # optional - sage.rings.finite_rings + sage: D.basis((1,2)) # basis in degree (1,2) # needs sage.rings.finite_rings [a*c] - sage: D.basis([1,2]) # optional - sage.rings.finite_rings + sage: D.basis([1,2]) # needs sage.rings.finite_rings [a*c] - sage: D.basis(vector([1,2])) # optional - sage.rings.finite_rings + sage: D.basis(vector([1,2])) # needs sage.rings.finite_rings [a*c] sage: G = AdditiveAbelianGroup([0,0]); G Additive abelian group isomorphic to Z + Z - sage: D.basis(G(vector([1,2]))) # optional - sage.rings.finite_rings + sage: D.basis(G(vector([1,2]))) # needs sage.rings.finite_rings [a*c] At this point, ``a``, for example, is an element of ``C``. We can redefine it so that it is instead an element of ``D`` in several ways, for instance using :meth:`gens` method:: - sage: a, b, c, d = D.gens() # optional - sage.rings.finite_rings - sage: a.differential() # optional - sage.rings.finite_rings + sage: a, b, c, d = D.gens() # needs sage.rings.finite_rings + sage: a.differential() # needs sage.rings.finite_rings c Or the :meth:`inject_variables` method:: - sage: D.inject_variables() # optional - sage.rings.finite_rings + sage: D.inject_variables() # needs sage.rings.finite_rings Defining a, b, c, d - sage: (a*b).differential() # optional - sage.rings.finite_rings + sage: (a*b).differential() # needs sage.rings.finite_rings b*c + a*d - sage: (a*b*c**2).degree() # optional - sage.rings.finite_rings + sage: (a*b*c**2).degree() # needs sage.rings.finite_rings (2, 5) Degrees are returned as elements of additive abelian groups:: - sage: (a*b*c**2).degree() in G # optional - sage.rings.finite_rings + sage: (a*b*c**2).degree() in G # needs sage.rings.finite_rings True - sage: (a*b*c**2).degree(total=True) # total degree # optional - sage.rings.finite_rings + sage: (a*b*c**2).degree(total=True) # total degree # needs sage.rings.finite_rings 7 - sage: D.cohomology(4) # optional - sage.rings.finite_rings + sage: D.cohomology(4) # needs sage.rings.finite_rings Free module generated by {[a^4], [b^2]} over Finite Field of size 2 - sage: D.cohomology((2,2)) # optional - sage.rings.finite_rings + sage: D.cohomology((2,2)) # needs sage.rings.finite_rings Free module generated by {[b^2]} over Finite Field of size 2 Graded algebra with maximal degree:: @@ -4047,7 +4049,7 @@ def __init__(self, x, cdga=None): EXAMPLES:: sage: from sage.algebras.commutative_dga import CohomologyClass - sage: CohomologyClass(x - 2) # optional - sage.symbolic + sage: CohomologyClass(x - 2) # needs sage.symbolic [x - 2] """ self._x = x @@ -4058,7 +4060,7 @@ def __hash__(self): TESTS:: sage: from sage.algebras.commutative_dga import CohomologyClass - sage: hash(CohomologyClass(sin)) == hash(sin) # optional - sage.symbolic + sage: hash(CohomologyClass(sin)) == hash(sin) # needs sage.symbolic True """ return hash(self._x) @@ -4068,7 +4070,7 @@ def _repr_(self): EXAMPLES:: sage: from sage.algebras.commutative_dga import CohomologyClass - sage: CohomologyClass(sin) # optional - sage.symbolic + sage: CohomologyClass(sin) # needs sage.symbolic [sin] """ return '[{}]'.format(self._x) @@ -4078,9 +4080,9 @@ def _latex_(self): EXAMPLES:: sage: from sage.algebras.commutative_dga import CohomologyClass - sage: latex(CohomologyClass(sin)) # optional - sage.symbolic + sage: latex(CohomologyClass(sin)) # needs sage.symbolic \left[ \sin \right] - sage: latex(CohomologyClass(x^2)) # optional - sage.symbolic + sage: latex(CohomologyClass(x^2)) # needs sage.symbolic \left[ x^{2} \right] """ from sage.misc.latex import latex @@ -4093,8 +4095,8 @@ def representative(self): EXAMPLES:: sage: from sage.algebras.commutative_dga import CohomologyClass - sage: x = CohomologyClass(sin) # optional - sage.symbolic - sage: x.representative() == sin # optional - sage.symbolic + sage: x = CohomologyClass(sin) # needs sage.symbolic + sage: x.representative() == sin # needs sage.symbolic True """ return self._x diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py index 5f6512baccf..d2114511ae6 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py @@ -86,9 +86,9 @@ def _repr_(self): sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: I = A.maximal_ideal() # optional - sage.libs.pari - sage: q = A.quotient_map(I) # optional - sage.libs.pari - sage: q._repr_() # optional - sage.libs.pari + sage: I = A.maximal_ideal() # needs sage.libs.pari + sage: q = A.quotient_map(I) # needs sage.libs.pari + sage: q._repr_() # needs sage.libs.pari 'Morphism from Finite-dimensional algebra of degree 2 over Rational Field to Finite-dimensional algebra of degree 1 over Rational Field given by matrix\n[1]\n[0]' """ return "Morphism from {} to {} given by matrix\n{}".format( @@ -100,9 +100,9 @@ def __call__(self, x): sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: I = A.maximal_ideal() # optional - sage.libs.pari - sage: q = A.quotient_map(I) # optional - sage.libs.pari - sage: q(0) == 0 and q(1) == 1 # optional - sage.libs.pari + sage: I = A.maximal_ideal() # needs sage.libs.pari + sage: q = A.quotient_map(I) # needs sage.libs.pari + sage: q(0) == 0 and q(1) == 1 # needs sage.libs.pari True """ x = self.domain()(x) @@ -182,10 +182,10 @@ def inverse_image(self, I): sage: A = FiniteDimensionalAlgebra(QQ, [Matrix([[1, 0], [0, 1]]), ....: Matrix([[0, 1], [0, 0]])]) - sage: I = A.maximal_ideal() # optional - sage.libs.pari - sage: q = A.quotient_map(I) # optional - sage.libs.pari - sage: B = q.codomain() # optional - sage.libs.pari - sage: q.inverse_image(B.zero_ideal()) == I # optional - sage.libs.pari + sage: I = A.maximal_ideal() # needs sage.libs.pari + sage: q = A.quotient_map(I) # needs sage.libs.pari + sage: B = q.codomain() # needs sage.libs.pari + sage: q.inverse_image(B.zero_ideal()) == I # needs sage.libs.pari True """ coker_I = I.basis_matrix().transpose().kernel().basis_matrix().transpose() diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 70ccb24c63f..d1a536a7043 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -35,10 +35,11 @@ Moreover, we can compute Groebner bases with degree bound for its two-sided ideals, and thus provide ideal containment tests:: - sage: F. = FreeAlgebra(QQ, implementation='letterplace'); F # optional - sage.libs.singular + sage: # needs sage.libs.singular + sage: F. = FreeAlgebra(QQ, implementation='letterplace'); F Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field - sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F # optional - sage.libs.singular - sage: I.groebner_basis(degbound=4) # optional - sage.libs.singular + sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F + sage: I.groebner_basis(degbound=4) Twosided Ideal (x*y + y*z, x*x - y*x - y*y - y*z, y*y*y - y*y*z + y*z*y - y*z*z, @@ -48,67 +49,72 @@ y*y*z*x + y*y*z*z + y*z*z*x + y*z*z*z, y*z*y*x + y*z*y*z + y*z*z*x + y*z*z*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field - sage: y*z*y*y*z*z + 2*y*z*y*z*z*x + y*z*y*z*z*z - y*z*z*y*z*x + y*z*z*z*z*x in I # optional - sage.libs.singular + sage: y*z*y*y*z*z + 2*y*z*y*z*z*x + y*z*y*z*z*z - y*z*z*y*z*x + y*z*z*z*z*x in I True Positive integral degree weights for the letterplace implementation was introduced in :trac:`7797`:: - sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) # optional - sage.libs.singular - sage: x.degree() # optional - sage.libs.singular + sage: # needs sage.libs.singular + sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) + sage: x.degree() 2 - sage: y.degree() # optional - sage.libs.singular + sage: y.degree() 1 - sage: z.degree() # optional - sage.libs.singular + sage: z.degree() 3 - sage: I = F*[x*y-y*x, x^2+2*y*z, (x*y)^2-z^2]*F # optional - sage.libs.singular - sage: Q. = F.quo(I) # optional - sage.libs.singular - sage: TestSuite(Q).run() # optional - sage.libs.singular - sage: a^2*b^2 # optional - sage.libs.singular + sage: I = F*[x*y-y*x, x^2+2*y*z, (x*y)^2-z^2]*F + sage: Q. = F.quo(I) + sage: TestSuite(Q).run() + sage: a^2*b^2 c*c TESTS:: - sage: F = FreeAlgebra(GF(5),3,'x') # optional - sage.rings.finite_rings - sage: TestSuite(F).run() # optional - sage.rings.finite_rings - sage: F is loads(dumps(F)) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F = FreeAlgebra(GF(5),3,'x') + sage: TestSuite(F).run() + sage: F is loads(dumps(F)) True - sage: F = FreeAlgebra(GF(5),3,'x', implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings - sage: TestSuite(F).run() # optional - sage.libs.singular sage.rings.finite_rings - sage: F is loads(dumps(F)) # optional - sage.libs.singular sage.rings.finite_rings + sage: F = FreeAlgebra(GF(5),3,'x', implementation='letterplace') # needs sage.libs.singular + sage: TestSuite(F).run() # needs sage.libs.singular + sage: F is loads(dumps(F)) # needs sage.libs.singular True :: - sage: F. = FreeAlgebra(GF(5),3) # optional - sage.rings.finite_rings - sage: TestSuite(F).run() # optional - sage.rings.finite_rings - sage: F is loads(dumps(F)) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = FreeAlgebra(GF(5),3) + sage: TestSuite(F).run() + sage: F is loads(dumps(F)) True - sage: F. = FreeAlgebra(GF(5),3, implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings - sage: TestSuite(F).run() # optional - sage.libs.singular sage.rings.finite_rings - sage: F is loads(dumps(F)) # optional - sage.libs.singular sage.rings.finite_rings + sage: F. = FreeAlgebra(GF(5),3, implementation='letterplace') # needs sage.libs.singular + sage: TestSuite(F).run() # needs sage.libs.singular + sage: F is loads(dumps(F)) # needs sage.libs.singular True :: - sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y']) # optional - sage.rings.finite_rings - sage: TestSuite(F).run() # optional - sage.rings.finite_rings - sage: F is loads(dumps(F)) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y']) + sage: TestSuite(F).run() + sage: F is loads(dumps(F)) True - sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y'], implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings - sage: TestSuite(F).run() # optional - sage.libs.singular sage.rings.finite_rings - sage: F is loads(dumps(F)) # optional - sage.libs.singular sage.rings.finite_rings + sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y'], implementation='letterplace') # needs sage.libs.singular + sage: TestSuite(F).run() # needs sage.libs.singular + sage: F is loads(dumps(F)) # needs sage.libs.singular True :: - sage: F = FreeAlgebra(GF(5),3, 'abc') # optional - sage.rings.finite_rings - sage: TestSuite(F).run() # optional - sage.rings.finite_rings - sage: F is loads(dumps(F)) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F = FreeAlgebra(GF(5),3, 'abc') + sage: TestSuite(F).run() + sage: F is loads(dumps(F)) True - sage: F = FreeAlgebra(GF(5),3, 'abc', implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings - sage: TestSuite(F).run() # optional - sage.libs.singular sage.rings.finite_rings - sage: F is loads(dumps(F)) # optional - sage.libs.singular sage.rings.finite_rings + sage: F = FreeAlgebra(GF(5),3, 'abc', implementation='letterplace') # needs sage.libs.singular + sage: TestSuite(F).run() # needs sage.libs.singular + sage: F is loads(dumps(F)) # needs sage.libs.singular True :: @@ -121,7 +127,7 @@ Note that the letterplace implementation can only be used if the corresponding (multivariate) polynomial ring has an implementation in Singular:: - sage: FreeAlgebra(FreeAlgebra(ZZ,2,'ab'), 2, 'x', implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings + sage: FreeAlgebra(FreeAlgebra(ZZ,2,'ab'), 2, 'x', implementation='letterplace') # needs sage.libs.singular sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: polynomials over Free Algebra on 2 generators (a, b) over Integer Ring are not supported in Singular @@ -168,18 +174,18 @@ class FreeAlgebraFactory(UniqueFactory): EXAMPLES:: - sage: FreeAlgebra(GF(5),3,'x') # optional - sage.rings.finite_rings + sage: FreeAlgebra(GF(5),3,'x') # needs sage.rings.finite_rings Free Algebra on 3 generators (x0, x1, x2) over Finite Field of size 5 - sage: F. = FreeAlgebra(GF(5),3) # optional - sage.rings.finite_rings - sage: (x+y+z)^2 # optional - sage.rings.finite_rings + sage: F. = FreeAlgebra(GF(5),3) # needs sage.rings.finite_rings + sage: (x+y+z)^2 # needs sage.rings.finite_rings x^2 + x*y + x*z + y*x + y^2 + y*z + z*x + z*y + z^2 - sage: FreeAlgebra(GF(5),3, 'xx, zba, Y') # optional - sage.rings.finite_rings + sage: FreeAlgebra(GF(5),3, 'xx, zba, Y') # needs sage.rings.finite_rings Free Algebra on 3 generators (xx, zba, Y) over Finite Field of size 5 - sage: FreeAlgebra(GF(5),3, 'abc') # optional - sage.rings.finite_rings + sage: FreeAlgebra(GF(5),3, 'abc') # needs sage.rings.finite_rings Free Algebra on 3 generators (a, b, c) over Finite Field of size 5 - sage: FreeAlgebra(GF(5),1, 'z') # optional - sage.rings.finite_rings + sage: FreeAlgebra(GF(5),1, 'z') # needs sage.rings.finite_rings Free Algebra on 1 generators (z,) over Finite Field of size 5 - sage: FreeAlgebra(GF(5),1, ['alpha']) # optional - sage.rings.finite_rings + sage: FreeAlgebra(GF(5),1, ['alpha']) # needs sage.rings.finite_rings Free Algebra on 1 generators (alpha,) over Finite Field of size 5 sage: FreeAlgebra(FreeAlgebra(ZZ,1,'a'), 2, 'x') Free Algebra on 2 generators (x0, x1) over @@ -191,14 +197,14 @@ class FreeAlgebraFactory(UniqueFactory): sage: G = FreeAlgebra(ZZ,3,'x,y,z') sage: F is G True - sage: F. = FreeAlgebra(GF(5),3) # indirect doctest # optional - sage.rings.finite_rings - sage: F is loads(dumps(F)) # optional - sage.rings.finite_rings + sage: F. = FreeAlgebra(GF(5),3) # indirect doctest # needs sage.rings.finite_rings + sage: F is loads(dumps(F)) # needs sage.rings.finite_rings True - sage: F is FreeAlgebra(GF(5),['x','y','z']) # optional - sage.rings.finite_rings + sage: F is FreeAlgebra(GF(5),['x','y','z']) # needs sage.rings.finite_rings True - sage: copy(F) is F is loads(dumps(F)) # optional - sage.rings.finite_rings + sage: copy(F) is F is loads(dumps(F)) # needs sage.rings.finite_rings True - sage: TestSuite(F).run() # optional - sage.rings.finite_rings + sage: TestSuite(F).run() # needs sage.rings.finite_rings By :trac:`7797`, we provide a different implementation of free algebras, based on Singular's "letterplace rings". Our letterplace @@ -207,27 +213,29 @@ class FreeAlgebraFactory(UniqueFactory): elements are supported. Of course, isomorphic algebras in different implementations are not identical:: - sage: G = FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings - sage: F == G # optional - sage.libs.singular sage.rings.finite_rings + sage: # needs sage.libs.singular sage.rings.finite_rings + sage: G = FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace') + sage: F == G False - sage: G is FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings + sage: G is FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace') True - sage: copy(G) is G is loads(dumps(G)) # optional - sage.libs.singular sage.rings.finite_rings + sage: copy(G) is G is loads(dumps(G)) True - sage: TestSuite(G).run() # optional - sage.libs.singular sage.rings.finite_rings + sage: TestSuite(G).run() :: - sage: H = FreeAlgebra(GF(5), ['x','y','z'], implementation='letterplace', # optional - sage.libs.singular sage.rings.finite_rings + sage: # needs sage.libs.singular sage.rings.finite_rings + sage: H = FreeAlgebra(GF(5), ['x','y','z'], implementation='letterplace', ....: degrees=[1,2,3]) - sage: F != H != G # optional - sage.libs.singular sage.rings.finite_rings + sage: F != H != G True - sage: H is FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace', # optional - sage.libs.singular sage.rings.finite_rings + sage: H is FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace', ....: degrees=[1,2,3]) True - sage: copy(H) is H is loads(dumps(H)) # optional - sage.libs.singular sage.rings.finite_rings + sage: copy(H) is H is loads(dumps(H)) True - sage: TestSuite(H).run() # optional - sage.libs.singular sage.rings.finite_rings + sage: TestSuite(H).run() Free algebras commute with their base ring. :: @@ -255,22 +263,23 @@ def create_key(self, base_ring, arg1=None, arg2=None, TESTS:: - sage: FreeAlgebra.create_key(GF(5),['x','y','z']) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: FreeAlgebra.create_key(GF(5),['x','y','z']) (Finite Field of size 5, ('x', 'y', 'z')) - sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3) # optional - sage.rings.finite_rings + sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3) (Finite Field of size 5, ('x', 'y', 'z')) - sage: FreeAlgebra.create_key(GF(5),3,'xyz') # optional - sage.rings.finite_rings + sage: FreeAlgebra.create_key(GF(5),3,'xyz') (Finite Field of size 5, ('x', 'y', 'z')) - sage: FreeAlgebra.create_key(GF(5),['x','y','z'], # optional - sage.libs.singular sage.rings.finite_rings + sage: FreeAlgebra.create_key(GF(5),['x','y','z'], # needs sage.libs.singular ....: implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) - sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3, # optional - sage.libs.singular sage.rings.finite_rings + sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3, # needs sage.libs.singular ....: implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) - sage: FreeAlgebra.create_key(GF(5),3,'xyz', # optional - sage.libs.singular sage.rings.finite_rings + sage: FreeAlgebra.create_key(GF(5),3,'xyz', # needs sage.libs.singular ....: implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) - sage: FreeAlgebra.create_key(GF(5),3,'xyz', # optional - sage.libs.singular sage.rings.finite_rings + sage: FreeAlgebra.create_key(GF(5),3,'xyz', # needs sage.libs.singular ....: implementation='letterplace', degrees=[1,2,3]) ((1, 2, 3), Multivariate Polynomial Ring in x, y, z, x_ over Finite Field of size 5) @@ -553,21 +562,23 @@ def _element_constructor_(self, x): TESTS:: - sage: F. = FreeAlgebra(GF(5),3) # optional - sage.rings.finite_rings - sage: L. = FreeAlgebra(ZZ,3,implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings - sage: F(x) # indirect doctest # optional - sage.libs.singular sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = FreeAlgebra(GF(5),3) + sage: L. = FreeAlgebra(ZZ,3,implementation='letterplace') # needs sage.libs.singular + sage: F(x) # indirect doctest # needs sage.libs.singular x - sage: F.1*L.2 # optional - sage.libs.singular sage.rings.finite_rings + sage: F.1*L.2 # needs sage.libs.singular y*z - sage: (F.1*L.2).parent() is F # optional - sage.libs.singular sage.rings.finite_rings + sage: (F.1*L.2).parent() is F # needs sage.libs.singular True :: - sage: K. = GF(25) # optional - sage.rings.finite_rings - sage: F. = FreeAlgebra(K,3) # optional - sage.rings.finite_rings - sage: L. = FreeAlgebra(K,3, implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings - sage: F.1+(z+1)*L.2 # optional - sage.libs.singular sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K. = GF(25) + sage: F. = FreeAlgebra(K,3) + sage: L. = FreeAlgebra(K,3, implementation='letterplace') # needs sage.libs.singular + sage: F.1+(z+1)*L.2 # needs sage.libs.singular b + (z+1)*c Check that :trac:`15169` is fixed:: @@ -677,23 +688,23 @@ def _coerce_map_from_(self, R): sage: F.has_coerce_map_from(PolynomialRing(ZZ, 3, 'x,y,z')) False - sage: K. = GF(25) # optional - sage.rings.finite_rings - sage: F. = FreeAlgebra(K,3) # optional - sage.rings.finite_rings - sage: F._coerce_map_from_(ZZ) # optional - sage.rings.finite_rings + sage: K. = GF(25) # needs sage.rings.finite_rings + sage: F. = FreeAlgebra(K,3) # needs sage.rings.finite_rings + sage: F._coerce_map_from_(ZZ) # needs sage.rings.finite_rings True - sage: F._coerce_map_from_(QQ) # optional - sage.rings.finite_rings + sage: F._coerce_map_from_(QQ) # needs sage.rings.finite_rings False - sage: F._coerce_map_from_(F.monoid()) # optional - sage.rings.finite_rings + sage: F._coerce_map_from_(F.monoid()) # needs sage.rings.finite_rings True - sage: F._coerce_map_from_(F.pbw_basis()) # optional - sage.rings.finite_rings + sage: F._coerce_map_from_(F.pbw_basis()) # needs sage.rings.finite_rings True sage: G = FreeAlgebra(ZZ, 3, 'a,b,c') - sage: F._coerce_map_from_(G) # optional - sage.rings.finite_rings + sage: F._coerce_map_from_(G) # needs sage.rings.finite_rings True - sage: G._coerce_map_from_(F) # optional - sage.rings.finite_rings + sage: G._coerce_map_from_(F) # needs sage.rings.finite_rings False - sage: L. = FreeAlgebra(K,3, implementation='letterplace') # optional - sage.libs.singular sage.rings.finite_rings - sage: F.1 + (z+1) * L.2 # optional - sage.libs.singular sage.rings.finite_rings + sage: L. = FreeAlgebra(K,3, implementation='letterplace') # needs sage.libs.singular sage.rings.finite_rings + sage: F.1 + (z+1) * L.2 # needs sage.libs.singular sage.rings.finite_rings b + (z+1)*c """ if self._indices.has_coerce_map_from(R): diff --git a/src/sage/algebras/free_algebra_quotient.py b/src/sage/algebras/free_algebra_quotient.py index 21284681549..b0f0efed0cd 100644 --- a/src/sage/algebras/free_algebra_quotient.py +++ b/src/sage/algebras/free_algebra_quotient.py @@ -191,7 +191,7 @@ def _coerce_map_from_(self, S): True sage: H._coerce_map_from_(QQ) True - sage: H._coerce_map_from_(GF(7)) # optional - sage.rings.finite_rings + sage: H._coerce_map_from_(GF(7)) # needs sage.rings.finite_rings False """ return S == self or self.__free_algebra.has_coerce_map_from(S) diff --git a/src/sage/algebras/free_zinbiel_algebra.py b/src/sage/algebras/free_zinbiel_algebra.py index 3f4a41ea751..cee797e37c4 100644 --- a/src/sage/algebras/free_zinbiel_algebra.py +++ b/src/sage/algebras/free_zinbiel_algebra.py @@ -540,14 +540,14 @@ def _coerce_map_from_(self, R): EXAMPLES:: - sage: F = algebras.FreeZinbiel(GF(7), 'x,y,z'); F # optional - sage.rings.finite_rings + sage: F = algebras.FreeZinbiel(GF(7), 'x,y,z'); F # needs sage.rings.finite_rings Free Zinbiel algebra on generators (Z[x], Z[y], Z[z]) over Finite Field of size 7 Elements of the free Zinbiel algebra canonically coerce in:: - sage: x, y, z = F.gens() # optional - sage.rings.finite_rings - sage: F.coerce(x+y) == x+y # optional - sage.rings.finite_rings + sage: x, y, z = F.gens() # needs sage.rings.finite_rings + sage: F.coerce(x+y) == x+y # needs sage.rings.finite_rings True The free Zinbiel algebra over `\ZZ` on `x, y, z` coerces in, since @@ -555,15 +555,15 @@ def _coerce_map_from_(self, R): sage: G = algebras.FreeZinbiel(ZZ, 'x,y,z') sage: Gx,Gy,Gz = G.gens() - sage: z = F.coerce(Gx+Gy); z # optional - sage.rings.finite_rings + sage: z = F.coerce(Gx+Gy); z # needs sage.rings.finite_rings Z[x] + Z[y] - sage: z.parent() is F # optional - sage.rings.finite_rings + sage: z.parent() is F # needs sage.rings.finite_rings True However, `\GF{7}` does not coerce to `\ZZ`, so the free Zinbiel algebra over `\GF{7}` does not coerce to the one over `\ZZ`:: - sage: G.coerce(y) # optional - sage.rings.finite_rings + sage: G.coerce(y) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no canonical coercion from Free Zinbiel algebra on @@ -642,18 +642,18 @@ class ZinbielFunctor(ConstructionFunctor): sage: F = P.construction()[0]; F Zinbiel[x,y] - sage: A = GF(5)['a,b'] # optional - sage.rings.finite_rings - sage: a, b = A.gens() # optional - sage.rings.finite_rings - sage: F(A) # optional - sage.rings.finite_rings + sage: A = GF(5)['a,b'] # needs sage.rings.finite_rings + sage: a, b = A.gens() # needs sage.rings.finite_rings + sage: F(A) # needs sage.rings.finite_rings Free Zinbiel algebra on generators (Z[x], Z[y]) over Multivariate Polynomial Ring in a, b over Finite Field of size 5 - sage: f = A.hom([a+b,a-b],A) # optional - sage.rings.finite_rings - sage: F(f) # optional - sage.rings.finite_rings + sage: f = A.hom([a+b,a-b],A) # needs sage.rings.finite_rings + sage: F(f) # needs sage.rings.finite_rings Generic endomorphism of Free Zinbiel algebra on generators (Z[x], Z[y]) over Multivariate Polynomial Ring in a, b over Finite Field of size 5 - sage: F(f)(a * F(A)(x)) # optional - sage.rings.finite_rings + sage: F(f)(a * F(A)(x)) # needs sage.rings.finite_rings (a+b)*Z[x] """ rank = 9 @@ -706,7 +706,7 @@ def _apply_functor_to_morphism(self, f): TESTS:: sage: R = algebras.FreeZinbiel(ZZ, 'x').construction()[0] - sage: R(ZZ.hom(GF(3))) # indirect doctest # optional - sage.rings.finite_rings + sage: R(ZZ.hom(GF(3))) # indirect doctest # needs sage.rings.finite_rings Generic morphism: From: Free Zinbiel algebra on generators (Z[x],) over Integer Ring diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py index df4b748dca4..c0c055ccc65 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py @@ -93,14 +93,15 @@ initializing. However, you can do calculations inside the infinite algebra as well:: - sage: CHA6 = algebras.CubicHecke(6) # optional - database_cubic_hecke - sage: CHA6.inject_variables() # optional - database_cubic_hecke + sage: # optional - database_cubic_hecke + sage: CHA6 = algebras.CubicHecke(6) + sage: CHA6.inject_variables() Defining c0, c1, c2, c3, c4 - sage: s = c0*c1*c2*c3*c4; s # optional - database_cubic_hecke + sage: s = c0*c1*c2*c3*c4; s c0*c1*c2*c3*c4 - sage: s^2 # optional - database_cubic_hecke + sage: s^2 (c0*c1*c2*c3*c4)^2 - sage: t = CHA6.an_element() * c4; t # optional - database_cubic_hecke + sage: t = CHA6.an_element() * c4; t (-w)*c0*c1^-1*c4 + v*c0*c2^-1*c4 + u*c2*c1*c4 + ((-v*w+u)/w)*c4 REFERENCES: @@ -1833,18 +1834,19 @@ def _init_basis_extension(self): EXAMPLES:: - sage: CHA5 = algebras.CubicHecke(5) # optional - database_cubic_hecke # indirect doctest - sage: fc = CHA5._filecache # optional - database_cubic_hecke - sage: be = fc.section.basis_extensions # optional - database_cubic_hecke - sage: CHA5.reset_filecache(be) # optional - database_cubic_hecke - sage: fc.read(be) # optional - database_cubic_hecke + sage: # optional - database_cubic_hecke + sage: CHA5 = algebras.CubicHecke(5) + sage: fc = CHA5._filecache + sage: be = fc.section.basis_extensions + sage: CHA5.reset_filecache(be) + sage: fc.read(be) [[4], [-4]] - sage: ele = CHA5.an_element() # optional - database_cubic_hecke - sage: CHA5.inject_variables() # optional - database_cubic_hecke + sage: ele = CHA5.an_element() + sage: CHA5.inject_variables() Defining c0, c1, c2, c3 - sage: ele2 = ele * c3 # optional - database_cubic_hecke - sage: bex = fc.read(be) # optional - database_cubic_hecke - sage: bex.sort(); bex # optional - database_cubic_hecke + sage: ele2 = ele * c3 + sage: bex = fc.read(be) + sage: bex.sort(); bex [[-4], [1, -3, 4], [1, -2, 4], [3, 2, 4], [4]] """ self._basis_extension = [] @@ -2220,14 +2222,15 @@ def _braid_image_by_basis_extension(self, braid_tietze): EXAMPLES:: - sage: CHA5 = algebras.CubicHecke(5) # optional - database_cubic_hecke - sage: be = CHA5.filecache_section().basis_extensions # optional - database_cubic_hecke - sage: CHA5.reset_filecache(be) # optional - database_cubic_hecke - sage: CHA5._basis_extension # optional - database_cubic_hecke + sage: # optional - database_cubic_hecke + sage: CHA5 = algebras.CubicHecke(5) + sage: be = CHA5.filecache_section().basis_extensions + sage: CHA5.reset_filecache(be) + sage: CHA5._basis_extension [[4], [-4]] - sage: CHA5._braid_image_by_basis_extension((4,1)) # optional - database_cubic_hecke + sage: CHA5._braid_image_by_basis_extension((4,1)) c3*c0 - sage: CHA5._basis_extension # optional - database_cubic_hecke + sage: CHA5._basis_extension [[4], [-4], [4, 1]] case where the braid already has an corresponding basis element:: @@ -2524,15 +2527,16 @@ def _cubic_braid_append_to_basis(self, cubic_braid): EXAMPLES:: - sage: CHA5 = algebras.CubicHecke(5) # optional - database_cubic_hecke - sage: be = CHA5.filecache_section().basis_extensions # optional - database_cubic_hecke - sage: CHA5.reset_filecache(be) # optional - database_cubic_hecke - sage: CHA5._basis_extension # optional - database_cubic_hecke + sage: # optional - database_cubic_hecke + sage: CHA5 = algebras.CubicHecke(5) + sage: be = CHA5.filecache_section().basis_extensions + sage: CHA5.reset_filecache(be) + sage: CHA5._basis_extension [[4], [-4]] - sage: CBG = CHA5.cubic_braid_group() # optional - database_cubic_hecke - sage: CHA5._cubic_braid_append_to_basis(CBG((4,1))) # optional - database_cubic_hecke + sage: CBG = CHA5.cubic_braid_group() + sage: CHA5._cubic_braid_append_to_basis(CBG((4,1))) c3*c0 - sage: CHA5._basis_extension # optional - database_cubic_hecke + sage: CHA5._basis_extension [[4], [-4], [4, 1]] """ @@ -2807,12 +2811,13 @@ def reset_filecache(self, section=None, commit=True): EXAMPLES:: - sage: CHA5 = algebras.CubicHecke(5) # optional - database_cubic_hecke - sage: be = CHA5.filecache_section().basis_extensions # optional - database_cubic_hecke - sage: CHA5.is_filecache_empty(be) # optional - database_cubic_hecke + sage: # optional - database_cubic_hecke + sage: CHA5 = algebras.CubicHecke(5) + sage: be = CHA5.filecache_section().basis_extensions + sage: CHA5.is_filecache_empty(be) False - sage: CHA5.reset_filecache(be) # optional - database_cubic_hecke - sage: CHA5.is_filecache_empty(be) # optional - database_cubic_hecke + sage: CHA5.reset_filecache(be) + sage: CHA5.is_filecache_empty(be) True """ fc = self._filecache diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py b/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py index 99e359b518f..90d6657d309 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py @@ -298,14 +298,15 @@ def _element_constructor_(self, x, mon=None): EXAMPLES:: - sage: CHA3 = algebras.CubicHecke(3) # optional gap3 - sage: GER = CHA3.extension_ring(generic=True) # optional gap3 - sage: sch7 = CHA3.chevie().SchurElements()[7] # optional gap3 - sage: GER(sch7) # optional gap3 + sage: # optional - gap3 + sage: CHA3 = algebras.CubicHecke(3) + sage: GER = CHA3.extension_ring(generic=True) + sage: sch7 = CHA3.chevie().SchurElements()[7] + sage: GER(sch7) a*b*c^-2 + a^2*b^-1*c^-1 + a^-1*b^2*c^-1 + 2 + a*b^-2*c + a^-2*b*c + a^-1*b^-1*c^2 - sage: rep4_gap3 = CHA3.chevie().Representations(4) # optional gap3 - sage: matrix(GER, rep4_gap3[1]) # optional gap3 + sage: rep4_gap3 = CHA3.chevie().Representations(4) + sage: matrix(GER, rep4_gap3[1]) [ b 0] [-b c] """ diff --git a/src/sage/algebras/iwahori_hecke_algebra.py b/src/sage/algebras/iwahori_hecke_algebra.py index d0141592724..9608d684409 100644 --- a/src/sage/algebras/iwahori_hecke_algebra.py +++ b/src/sage/algebras/iwahori_hecke_algebra.py @@ -1955,12 +1955,13 @@ class Cp(_KLHeckeBasis): implemented with ``coxeter3`` to avoid unnecessary conversions, as in the following example with the same product computed in the last one:: - sage: R = LaurentPolynomialRing(QQ, 'v') # optional - coxeter3 - sage: v = R.gen(0) # optional - coxeter3 - sage: W = CoxeterGroup('A9', implementation='coxeter3') # optional - coxeter3 - sage: H = IwahoriHeckeAlgebra(W, v**2) # optional - coxeter3 - sage: Cp = H.Cp() # optional - coxeter3 - sage: Cp[1,2,1,8,9,8]*Cp[1,2,3,7,8,9] # optional - coxeter3 + sage: # optional - coxeter3 + sage: R = LaurentPolynomialRing(QQ, 'v') + sage: v = R.gen(0) + sage: W = CoxeterGroup('A9', implementation='coxeter3') + sage: H = IwahoriHeckeAlgebra(W, v**2) + sage: Cp = H.Cp() + sage: Cp[1,2,1,8,9,8]*Cp[1,2,3,7,8,9] (v^-2+2+v^2)*Cp[1,2,1,3,7,8,7,9,8,7] + (v^-2+2+v^2)*Cp[1,2,1,3,8,9,8,7] + (v^-3+3*v^-1+3*v+v^3)*Cp[1,2,1,3,8,9,8] @@ -1984,17 +1985,18 @@ def __init__(self, IHAlgebra, prefix=None): r""" TESTS:: - sage: R. = LaurentPolynomialRing(QQ) # optional - coxeter3 - sage: W = CoxeterGroup('A3', implementation='coxeter3') # optional - coxeter3 - sage: H = IwahoriHeckeAlgebra(W, v**2) # optional - coxeter3 - sage: Cp = H.Cp() # optional - coxeter3 - sage: Cp._delta == v + ~v # optional - coxeter3 + sage: # optional - coxeter3 + sage: R. = LaurentPolynomialRing(QQ) + sage: W = CoxeterGroup('A3', implementation='coxeter3') + sage: H = IwahoriHeckeAlgebra(W, v**2) + sage: Cp = H.Cp() + sage: Cp._delta == v + ~v True - sage: Cp._W_Coxeter3 == H._W # optional - coxeter3 + sage: Cp._W_Coxeter3 == H._W True - sage: H = IwahoriHeckeAlgebra(W, QQ(1)) # optional - coxeter3 - sage: Cp = H.Cp() # optional - coxeter3 - sage: Cp._W_Coxeter3 is None # optional - coxeter3 + sage: H = IwahoriHeckeAlgebra(W, QQ(1)) + sage: Cp = H.Cp() + sage: Cp._W_Coxeter3 is None True """ super().__init__(IHAlgebra, prefix) @@ -2128,12 +2130,13 @@ def product_on_basis(self, w1, w2): EXAMPLES:: - sage: R. = LaurentPolynomialRing(ZZ, 'v') # optional - coxeter3 - sage: W = CoxeterGroup('A3', implementation='coxeter3') # optional - coxeter3 - sage: H = IwahoriHeckeAlgebra(W, v**2); Cp=H.Cp() # optional - coxeter3 - sage: Cp.product_on_basis(W([1,2,1]), W([3,1])) # optional - coxeter3 + sage: # optional - coxeter3 + sage: R. = LaurentPolynomialRing(ZZ, 'v') + sage: W = CoxeterGroup('A3', implementation='coxeter3') + sage: H = IwahoriHeckeAlgebra(W, v**2); Cp=H.Cp() + sage: Cp.product_on_basis(W([1,2,1]), W([3,1])) (v^-1+v)*Cp[1,2,1,3] - sage: Cp.product_on_basis(W([1,2,1]), W([3,1,2])) # optional - coxeter3 + sage: Cp.product_on_basis(W([1,2,1]), W([3,1,2])) (v^-1+v)*Cp[1,2,1,3,2] + (v^-1+v)*Cp[1,2,1] """ if self._W_Coxeter3 is None: @@ -2195,14 +2198,15 @@ def _product_with_generator_on_basis(self, s, w, side='left'): EXAMPLES:: - sage: R. = LaurentPolynomialRing(ZZ, 'v') # optional - coxeter3 - sage: W = CoxeterGroup('A3', implementation='coxeter3') # optional - coxeter3 - sage: H = IwahoriHeckeAlgebra(W, v**2); Cp = H.Cp() # optional - coxeter3 - sage: Cp._product_with_generator_on_basis(1, W([2,1]), 'left') # optional - coxeter3 + sage: # optional - coxeter3 + sage: R. = LaurentPolynomialRing(ZZ, 'v') + sage: W = CoxeterGroup('A3', implementation='coxeter3') + sage: H = IwahoriHeckeAlgebra(W, v**2); Cp = H.Cp() + sage: Cp._product_with_generator_on_basis(1, W([2,1]), 'left') Cp[1,2,1] + Cp[1] - sage: Cp._product_with_generator_on_basis(1, W([2,1]), 'right') # optional - coxeter3 + sage: Cp._product_with_generator_on_basis(1, W([2,1]), 'right') (v^-1+v)*Cp[2,1] - sage: Cp._product_with_generator_on_basis(2, W([1,3,2,1,3]), 'right') # optional - coxeter3 + sage: Cp._product_with_generator_on_basis(2, W([1,3,2,1,3]), 'right') Cp[1,2,1,3,2,1] + Cp[1,2,3,2] + Cp[1,3,2,1] """ # use the product formula described in the class' documentation @@ -2237,12 +2241,13 @@ def _product_with_generator(self, s, x, side='left'): EXAMPLES:: - sage: R. = LaurentPolynomialRing(ZZ, 'v') # optional - coxeter3 - sage: W = CoxeterGroup('A3', implementation='coxeter3') # optional - coxeter3 - sage: H = IwahoriHeckeAlgebra(W, v**2); Cp = H.Cp() # optional - coxeter3 - sage: Cp._product_with_generator(1, Cp[1]+Cp[2], 'left') # optional - coxeter3 + sage: # optional - coxeter3 + sage: R. = LaurentPolynomialRing(ZZ, 'v') + sage: W = CoxeterGroup('A3', implementation='coxeter3') + sage: H = IwahoriHeckeAlgebra(W, v**2); Cp = H.Cp() + sage: Cp._product_with_generator(1, Cp[1]+Cp[2], 'left') Cp[1,2] + (v^-1+v)*Cp[1] - sage: Cp._product_with_generator(1, Cp[1]+Cp[2], 'right') # optional - coxeter3 + sage: Cp._product_with_generator(1, Cp[1]+Cp[2], 'right') Cp[2,1] + (v^-1+v)*Cp[1] """ return self.linear_combination((self._product_with_generator_on_basis(s, w, side), coeff) for (w, coeff) in x) diff --git a/src/sage/algebras/lie_algebras/morphism.py b/src/sage/algebras/lie_algebras/morphism.py index 2d04a5e6b65..3fa39f8ff78 100644 --- a/src/sage/algebras/lie_algebras/morphism.py +++ b/src/sage/algebras/lie_algebras/morphism.py @@ -461,8 +461,8 @@ class LieAlgebraMorphism_from_generators(LieAlgebraHomomorphism_im_gens): A quotient type Lie algebra morphism:: - sage: K. = LieAlgebra(SR, abelian=True) # optional - sage.symbolic - sage: L.morphism({X: A, Y: B}) # optional - sage.symbolic + sage: K. = LieAlgebra(SR, abelian=True) # needs sage.symbolic + sage: L.morphism({X: A, Y: B}) # needs sage.symbolic Lie algebra morphism: From: Lie algebra on 4 generators (X, Y, Z, W) over Rational Field To: Abelian Lie algebra on 2 generators (A, B) over Symbolic Ring @@ -623,17 +623,17 @@ def _call_(self, x): EXAMPLES:: sage: L. = LieAlgebra(QQ, {('X','Y'): {'Z':1}, ('X','Z'): {'W':1}}) - sage: K. = LieAlgebra(SR, abelian=True) # optional - sage.symbolic - sage: phi = L.morphism({X: A, Y: B}) # optional - sage.symbolic - sage: phi(X) # optional - sage.symbolic + sage: K. = LieAlgebra(SR, abelian=True) # needs sage.symbolic + sage: phi = L.morphism({X: A, Y: B}) # needs sage.symbolic + sage: phi(X) # needs sage.symbolic A - sage: phi(Y) # optional - sage.symbolic + sage: phi(Y) # needs sage.symbolic B - sage: phi(Z) # optional - sage.symbolic + sage: phi(Z) # needs sage.symbolic 0 - sage: phi(W) # optional - sage.symbolic + sage: phi(W) # needs sage.symbolic 0 - sage: phi(-X + 3*Y) # optional - sage.symbolic + sage: phi(-X + 3*Y) # needs sage.symbolic -A + 3*B sage: K. = LieAlgebra(QQ, {('A','B'): {'C':2}}) diff --git a/src/sage/algebras/lie_algebras/quotient.py b/src/sage/algebras/lie_algebras/quotient.py index a0400221af6..ed64e6ee279 100644 --- a/src/sage/algebras/lie_algebras/quotient.py +++ b/src/sage/algebras/lie_algebras/quotient.py @@ -242,11 +242,12 @@ def __init__(self, I, L, names, index_set, category=None): TESTS:: - sage: L. = LieAlgebra(SR, {('x','y'): {'x':1}}) # optional - sage.symbolic - sage: K = L.quotient(y) # optional - sage.symbolic - sage: K.dimension() # optional - sage.symbolic + sage: # needs sage.symbolic + sage: L. = LieAlgebra(SR, {('x','y'): {'x':1}}) + sage: K = L.quotient(y) + sage: K.dimension() 1 - sage: TestSuite(K).run() # optional - sage.symbolic + sage: TestSuite(K).run() """ B = L.basis() sm = L.module().submodule_with_basis([I.reduce(B[i]).to_vector() diff --git a/src/sage/algebras/lie_algebras/structure_coefficients.py b/src/sage/algebras/lie_algebras/structure_coefficients.py index 48b1bbecf41..ed200875e32 100644 --- a/src/sage/algebras/lie_algebras/structure_coefficients.py +++ b/src/sage/algebras/lie_algebras/structure_coefficients.py @@ -411,8 +411,8 @@ def change_ring(self, R): sage: LQQ = L.change_ring(QQ) sage: LQQ.structure_coefficients() Finite family {('x', 'y'): z} - sage: LSR = LQQ.change_ring(SR) # optional - sage.symbolic - sage: LSR.structure_coefficients() # optional - sage.symbolic + sage: LSR = LQQ.change_ring(SR) # needs sage.symbolic + sage: LSR.structure_coefficients() # needs sage.symbolic Finite family {('x', 'y'): z} """ return LieAlgebraWithStructureCoefficients( diff --git a/src/sage/algebras/lie_algebras/subalgebra.py b/src/sage/algebras/lie_algebras/subalgebra.py index ab7b6922083..7dc6e8ef37e 100644 --- a/src/sage/algebras/lie_algebras/subalgebra.py +++ b/src/sage/algebras/lie_algebras/subalgebra.py @@ -75,32 +75,34 @@ class LieSubalgebra_finite_dimensional_with_basis(Parent, UniqueRepresentation): Elements of the ambient Lie algebra can be reduced modulo an ideal or subalgebra:: - sage: L. = LieAlgebra(SR, {('X','Y'): {'Z': 1}}) # optional - sage.symbolic - sage: I = L.ideal(Y) # optional - sage.symbolic - sage: I.reduce(X + 2*Y + 3*Z) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: L. = LieAlgebra(SR, {('X','Y'): {'Z': 1}}) + sage: I = L.ideal(Y) + sage: I.reduce(X + 2*Y + 3*Z) X - sage: S = L.subalgebra(Y) # optional - sage.symbolic - sage: S.reduce(X + 2*Y + 3*Z) # optional - sage.symbolic + sage: S = L.subalgebra(Y) + sage: S.reduce(X + 2*Y + 3*Z) X + 3*Z The reduction gives elements in a fixed complementary subspace. When the base ring is a field, the complementary subspace is spanned by those basis elements which are not leading supports of the basis:: - sage: I = L.ideal(X + Y) # optional - sage.symbolic - sage: I.basis() # optional - sage.symbolic + sage: # needs sage.symbolic + sage: I = L.ideal(X + Y) + sage: I.basis() Family (X + Y, Z) - sage: el = var('x')*X + var('y')*Y + var('z')*Z; el # optional - sage.symbolic + sage: el = var('x')*X + var('y')*Y + var('z')*Z; el x*X + y*Y + z*Z - sage: I.reduce(el) # optional - sage.symbolic + sage: I.reduce(el) (x-y)*X Giving a different ``order`` may change the reduction of elements:: - sage: I = L.ideal(X + Y, order=lambda s: ['Z','Y','X'].index(s)) # optional - sage.symbolic - sage: I.basis() # optional - sage.symbolic + sage: I = L.ideal(X + Y, order=lambda s: ['Z','Y','X'].index(s)) # needs sage.symbolic + sage: I.basis() # needs sage.symbolic Family (Z, X + Y) - sage: I.reduce(el) # optional - sage.symbolic + sage: I.reduce(el) # needs sage.symbolic (-x+y)*Y A subalgebra of a subalgebra is a subalgebra of the original:: diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index f92a93c7e21..2cb2dcb8299 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -624,11 +624,12 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): Next, we look at the same matroid but with an `S_3 \times S_3` action (here realized as a Young subgroup of `S_6`):: - sage: H = G.young_subgroup([3, 3]) # needs sage.graphs sage.groups - sage: OSH = M.orlik_solomon_algebra(QQ, invariant=H) # needs sage.graphs sage.groups - sage: OSH.basis() # needs sage.graphs sage.groups + sage: # needs sage.graphs sage.groups + sage: H = G.young_subgroup([3, 3]) + sage: OSH = M.orlik_solomon_algebra(QQ, invariant=H) + sage: OSH.basis() Finite family {0: B[0], 1: B[1], 2: B[2]} - sage: [OSH.lift(b) for b in OSH.basis()] # needs sage.graphs sage.groups + sage: [OSH.lift(b) for b in OSH.basis()] [OS{}, OS{4} + OS{5} + OS{6}, OS{1} + OS{2} + OS{3}] We implement an `S_4` action on the vertices:: @@ -648,10 +649,11 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): We use this to describe the Young subgroup `S_2 \times S_2` action:: - sage: H = G.young_subgroup([2,2]) # needs sage.graphs sage.groups - sage: OSH = M.orlik_solomon_algebra(QQ, invariant=(H, vert_action)) # needs sage.graphs sage.groups - sage: B = OSH.basis() # needs sage.graphs sage.groups - sage: [OSH.lift(b) for b in B] # needs sage.graphs sage.groups + sage: # needs sage.graphs sage.groups + sage: H = G.young_subgroup([2,2]) + sage: OSH = M.orlik_solomon_algebra(QQ, invariant=(H, vert_action)) + sage: B = OSH.basis() + sage: [OSH.lift(b) for b in B] [OS{}, OS{5}, OS{1} + OS{2} + OS{3} + OS{4}, OS{0}, -1/2*OS{1, 2} + OS{1, 5} - 1/2*OS{3, 4} + OS{3, 5}, OS{0, 5}, OS{0, 1} + OS{0, 2} + OS{0, 3} + OS{0, 4}, @@ -790,12 +792,13 @@ def _basis_action(self, g, f): We also check that the ordering is respected:: - sage: fset = frozenset({1,2}) # needs sage.graphs sage.groups - sage: OS1 = M.orlik_solomon_algebra(QQ) # needs sage.graphs sage.groups - sage: OS1.subset_image(fset) # needs sage.graphs sage.groups + sage: # needs sage.graphs sage.groups + sage: fset = frozenset({1,2}) + sage: OS1 = M.orlik_solomon_algebra(QQ) + sage: OS1.subset_image(fset) -OS{0, 1} + OS{0, 2} - sage: OS2 = M.orlik_solomon_algebra(QQ, range(2,-1,-1)) # needs sage.graphs sage.groups - sage: OS2.subset_image(fset) # needs sage.graphs sage.groups + sage: OS2 = M.orlik_solomon_algebra(QQ, range(2,-1,-1)) + sage: OS2.subset_image(fset) OS{1, 2} sage: OSG2 = M.orlik_solomon_algebra(QQ, # needs sage.graphs sage.groups diff --git a/src/sage/algebras/quatalg/quaternion_algebra.py b/src/sage/algebras/quatalg/quaternion_algebra.py index f0a31dca349..9c1562041e4 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra.py +++ b/src/sage/algebras/quatalg/quaternion_algebra.py @@ -119,10 +119,10 @@ class QuaternionAlgebraFactory(UniqueFactory): Quaternion Algebra (2, 3) with base ring Finite Field of size 5 sage: QuaternionAlgebra(2, GF(5)(3)) Quaternion Algebra (2, 3) with base ring Finite Field of size 5 - sage: QuaternionAlgebra(QQ[sqrt(2)](-1), -5) # optional - sage.symbolic + sage: QuaternionAlgebra(QQ[sqrt(2)](-1), -5) # needs sage.symbolic Quaternion Algebra (-1, -5) with base ring Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? - sage: QuaternionAlgebra(sqrt(-1), sqrt(-3)) # optional - sage.symbolic + sage: QuaternionAlgebra(sqrt(-1), sqrt(-3)) # needs sage.symbolic Quaternion Algebra (I, sqrt(-3)) with base ring Symbolic Ring sage: QuaternionAlgebra(1r,1) Quaternion Algebra (1, 1) with base ring Rational Field @@ -162,7 +162,7 @@ class QuaternionAlgebraFactory(UniqueFactory): sage: QuaternionAlgebra(QQ, -7, -21) Quaternion Algebra (-7, -21) with base ring Rational Field - sage: QuaternionAlgebra(QQ[sqrt(2)], -2,-3) # optional - sage.symbolic + sage: QuaternionAlgebra(QQ[sqrt(2)], -2,-3) # needs sage.symbolic Quaternion Algebra (-2, -3) with base ring Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? @@ -545,8 +545,8 @@ def random_element(self, *args, **kwds): EXAMPLES:: - sage: g = QuaternionAlgebra(QQ[sqrt(2)], -3, 7).random_element() # optional - sage.symbolic - sage: g.parent() is QuaternionAlgebra(QQ[sqrt(2)], -3, 7) # optional - sage.symbolic + sage: g = QuaternionAlgebra(QQ[sqrt(2)], -3, 7).random_element() # needs sage.symbolic + sage: g.parent() is QuaternionAlgebra(QQ[sqrt(2)], -3, 7) # needs sage.symbolic True sage: g = QuaternionAlgebra(-3, 19).random_element() sage: g.parent() is QuaternionAlgebra(-3, 19) @@ -1048,7 +1048,7 @@ def discriminant(self): sage: B.discriminant() Fractional ideal (2) - sage: QuaternionAlgebra(QQ[sqrt(2)], 3, 19).discriminant() # optional - sage.symbolic + sage: QuaternionAlgebra(QQ[sqrt(2)], 3, 19).discriminant() # needs sage.symbolic Fractional ideal (1) """ if not is_RationalField(self.base_ring()): @@ -1093,13 +1093,13 @@ def _magma_init_(self, magma): A more complicated example involving a quaternion algebra over a number field:: - sage: K. = QQ[sqrt(2)]; Q = QuaternionAlgebra(K,-1,a); Q # optional - sage.symbolic + sage: K. = QQ[sqrt(2)]; Q = QuaternionAlgebra(K,-1,a); Q # needs sage.symbolic Quaternion Algebra (-1, sqrt2) with base ring Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? - sage: magma(Q) # optional - magma sage.symbolic + sage: magma(Q) # optional - magma, needs sage.symbolic Quaternion Algebra with base ring Number Field with defining polynomial x^2 - 2 over the Rational Field, defined by i^2 = -1, j^2 = sqrt2 - sage: Q._magma_init_(magma) # optional - magma sage.symbolic + sage: Q._magma_init_(magma) # optional - magma, needs sage.symbolic 'QuaternionAlgebra(_sage_[...],(_sage_[...]![-1, 0]),(_sage_[...]![0, 1]))' """ R = magma(self.base_ring()) @@ -2546,12 +2546,13 @@ def norm(self): sage: [I.norm() for I in C] [16, 32, 32] - sage: (a,b) = M.quaternion_algebra().invariants() # optional - magma - sage: magma.eval('A := QuaternionAlgebra' % (a,b)) # optional - magma + sage: # optional - magma + sage: (a,b) = M.quaternion_algebra().invariants() + sage: magma.eval('A := QuaternionAlgebra' % (a,b)) '' - sage: magma.eval('O := QuaternionOrder(%s)' % str(list(C[0].right_order().basis()))) # optional - magma + sage: magma.eval('O := QuaternionOrder(%s)' % str(list(C[0].right_order().basis()))) '' - sage: [ magma('rideal' % str(list(I.basis()))).Norm() for I in C] # optional - magma + sage: [ magma('rideal' % str(list(I.basis()))).Norm() for I in C] [16, 32, 32] sage: A. = QuaternionAlgebra(-1,-1) diff --git a/src/sage/algebras/quatalg/quaternion_algebra_element.pyx b/src/sage/algebras/quatalg/quaternion_algebra_element.pyx index 71188038aa9..b4c5eed5b49 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra_element.pyx +++ b/src/sage/algebras/quatalg/quaternion_algebra_element.pyx @@ -1658,8 +1658,8 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra EXAMPLES:: - sage: K. = QQ[2^(1/5)]; Q. = QuaternionAlgebra(K,-a,a*17/3) # optional - sage.symbolic - sage: Q([a,-2/3,a^2-1/2,a*2]) # implicit doctest # optional - sage.symbolic + sage: K. = QQ[2^(1/5)]; Q. = QuaternionAlgebra(K,-a,a*17/3) # needs sage.symbolic + sage: Q([a,-2/3,a^2-1/2,a*2]) # implicit doctest # needs sage.symbolic a + (-2/3)*i + (a^2 - 1/2)*j + 2*a*k """ fmpz_poly_init(self.x) @@ -1688,8 +1688,8 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra """ EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K,-a,a+1) # optional - sage.symbolic - sage: Q([a,-2/3,a^2-1/2,a*2]) # implicit doctest # optional - sage.symbolic + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K,-a,a+1) # needs sage.symbolic + sage: Q([a,-2/3,a^2-1/2,a*2]) # implicit doctest # needs sage.symbolic a + (-2/3)*i + (a^2 - 1/2)*j + 2*a*k """ self._parent = parent @@ -1732,21 +1732,22 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra """ EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K,-a,a+1) # optional - sage.symbolic - sage: Q([a,-2/3,a^2-1/2,a*2]) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K,-a,a+1) + sage: Q([a,-2/3,a^2-1/2,a*2]) a + (-2/3)*i + (a^2 - 1/2)*j + 2*a*k - sage: x = Q([a,-2/3,a^2-1/2,a*2]) # optional - sage.symbolic - sage: type(x) # optional - sage.symbolic + sage: x = Q([a,-2/3,a^2-1/2,a*2]) + sage: type(x) - sage: x[0] # optional - sage.symbolic + sage: x[0] a - sage: x[1] # optional - sage.symbolic + sage: x[1] -2/3 - sage: x[2] # optional - sage.symbolic + sage: x[2] a^2 - 1/2 - sage: x[3] # optional - sage.symbolic + sage: x[3] 2*a - sage: list(x) # optional - sage.symbolic + sage: list(x) [a, -2/3, a^2 - 1/2, 2*a] """ # general number -- this code assumes that the number field is not quadratic!! @@ -1773,13 +1774,14 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra """ EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) # optional - sage.symbolic - sage: z = (i+j+k+a)^2; z # optional - sage.symbolic + sage: # needs sage.symbolic + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) + sage: z = (i+j+k+a)^2; z a^2 + 4*a - 3 + 2*a*i + 2*a*j + 2*a*k - sage: f, t = z.__reduce__() # optional - sage.symbolic - sage: f(*t) # optional - sage.symbolic + sage: f, t = z.__reduce__() + sage: f(*t) a^2 + 4*a - 3 + 2*a*i + 2*a*j + 2*a*k - sage: loads(dumps(z)) == z # optional - sage.symbolic + sage: loads(dumps(z)) == z True """ return (unpickle_QuaternionAlgebraElement_number_field_v0, @@ -1791,12 +1793,13 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) # optional - sage.symbolic - sage: z = a + i + (2/3)*a^3*j + (1+a)*k # optional - sage.symbolic - sage: w = a - i - (2/3)*a^3*j + (1/3+a)*k # optional - sage.symbolic - sage: type(z) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) + sage: z = a + i + (2/3)*a^3*j + (1+a)*k + sage: w = a - i - (2/3)*a^3*j + (1/3+a)*k + sage: type(z) - sage: z._add_(w) # optional - sage.symbolic + sage: z._add_(w) 2*a + (2*a + 4/3)*k Check that the fix in :trac:`17099` is correct:: @@ -1864,12 +1867,13 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) # optional - sage.symbolic - sage: z = a + i + (2/3)*a^3*j + (1+a)*k # optional - sage.symbolic - sage: w = a - i - (2/3)*a^3*j + (1/3+a)*k # optional - sage.symbolic - sage: type(z) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) + sage: z = a + i + (2/3)*a^3*j + (1+a)*k + sage: w = a - i - (2/3)*a^3*j + (1/3+a)*k + sage: type(z) - sage: z._sub_(w) # optional - sage.symbolic + sage: z._sub_(w) 2*i + 8/3*j + 2/3*k """ # Implementation Note: To obtain _sub_, we simply replace every occurrence of @@ -1914,12 +1918,13 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) # optional - sage.symbolic - sage: z = a + i + (2/3)*a^3*j + (1+a)*k # optional - sage.symbolic - sage: w = a - i - (2/3)*a^3*j + (1/3+a)*k # optional - sage.symbolic - sage: type(z) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a) + sage: z = a + i + (2/3)*a^3*j + (1+a)*k + sage: w = a - i - (2/3)*a^3*j + (1/3+a)*k + sage: type(z) - sage: z._mul_(w) # optional - sage.symbolic + sage: z._mul_(w) 5*a^2 - 7/9*a + 9 + (-8/3*a^2 - 16/9*a)*i + (-6*a - 4)*j + (2*a^2 + 4/3*a)*k """ # We use the following formula for multiplication: @@ -2063,10 +2068,11 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra TESTS:: - sage: F = QQ[3^(1/3)] # optional - sage.symbolic - sage: a = F.gen() # optional - sage.symbolic - sage: K. = QuaternionAlgebra(F, -10 + a, -7 - a) # optional - sage.symbolic - sage: ((1/4 + 1/2 * i + a^3/7 * j + a/28 * k)*14*i)^3 # implicit doctest # optional - sage.symbolic + sage: # needs sage.symbolic + sage: F = QQ[3^(1/3)] + sage: a = F.gen() + sage: K. = QuaternionAlgebra(F, -10 + a, -7 - a) + sage: ((1/4 + 1/2 * i + a^3/7 * j + a/28 * k)*14*i)^3 # implicit doctest 34503/2*a^2 + 132195/2*a + 791399/4 + (203/8*a^2 - 10591*a + 169225/4)*i + (-84695/4*a^2 + 483413/8*a + 18591/4)*j + (-87/2*a^2 + 18156*a - 72525)*k """ @@ -2141,11 +2147,12 @@ def unpickle_QuaternionAlgebraElement_number_field_v0(*args): """ EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a); z = i + j # optional - sage.symbolic - sage: f, t = z.__reduce__() # optional - sage.symbolic - sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a); z = i + j + sage: f, t = z.__reduce__() + sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) i + j - sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) == z # optional - sage.symbolic + sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) == z True """ return QuaternionAlgebraElement_number_field(*args, check=False) diff --git a/src/sage/algebras/quaternion_algebra_element.py b/src/sage/algebras/quaternion_algebra_element.py index dbd70e25856..ed0baaf0152 100644 --- a/src/sage/algebras/quaternion_algebra_element.py +++ b/src/sage/algebras/quaternion_algebra_element.py @@ -39,12 +39,13 @@ def unpickle_QuaternionAlgebraElement_number_field_v0(*args): """ EXAMPLES:: - sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a); z = i + j # optional - sage.symbolic - sage: f, t = z.__reduce__() # optional - sage.symbolic + sage: # needs sage.symbolic + sage: K. = QQ[2^(1/3)]; Q. = QuaternionAlgebra(K, -3, a); z = i + j + sage: f, t = z.__reduce__() sage: import sage.algebras.quaternion_algebra_element - sage: sage.algebras.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) # optional - sage.symbolic + sage: sage.algebras.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) i + j - sage: sage.algebras.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) == z # optional - sage.symbolic + sage: sage.algebras.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) == z True """ return QuaternionAlgebraElement_number_field(*args) diff --git a/src/sage/algebras/steenrod/steenrod_algebra_bases.py b/src/sage/algebras/steenrod/steenrod_algebra_bases.py index 367c854249e..d2a8760581e 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_bases.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_bases.py @@ -132,12 +132,12 @@ def convert_to_milnor_matrix(n, basis, p=2, generic='auto'): EXAMPLES:: sage: from sage.algebras.steenrod.steenrod_algebra_bases import convert_to_milnor_matrix - sage: convert_to_milnor_matrix(5, 'adem') # indirect doctest # optional - sage.modules sage.rings.finite_rings + sage: convert_to_milnor_matrix(5, 'adem') # indirect doctest # needs sage.modules sage.rings.finite_rings [0 1] [1 1] - sage: convert_to_milnor_matrix(45, 'milnor') # optional - sage.modules sage.rings.finite_rings + sage: convert_to_milnor_matrix(45, 'milnor') # needs sage.modules sage.rings.finite_rings 111 x 111 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries) - sage: convert_to_milnor_matrix(12,'wall') # optional - sage.modules sage.rings.finite_rings + sage: convert_to_milnor_matrix(12,'wall') # needs sage.modules sage.rings.finite_rings [1 0 0 1 0 0 0] [1 1 0 0 0 1 0] [0 1 0 1 0 0 0] @@ -149,15 +149,15 @@ def convert_to_milnor_matrix(n, basis, p=2, generic='auto'): The function takes an optional argument, the prime `p` over which to work:: - sage: convert_to_milnor_matrix(17,'adem',3) # optional - sage.modules sage.rings.finite_rings + sage: convert_to_milnor_matrix(17,'adem',3) # needs sage.modules sage.rings.finite_rings [0 0 1 1] [0 0 0 1] [1 1 1 1] [0 1 0 1] - sage: convert_to_milnor_matrix(48,'adem',5) # optional - sage.modules sage.rings.finite_rings + sage: convert_to_milnor_matrix(48,'adem',5) # needs sage.modules sage.rings.finite_rings [0 1] [1 1] - sage: convert_to_milnor_matrix(36,'adem',3) # optional - sage.modules sage.rings.finite_rings + sage: convert_to_milnor_matrix(36,'adem',3) # needs sage.modules sage.rings.finite_rings [0 0 1] [0 1 0] [1 2 0] @@ -206,7 +206,7 @@ def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): EXAMPLES:: sage: from sage.algebras.steenrod.steenrod_algebra_bases import convert_from_milnor_matrix, convert_to_milnor_matrix - sage: convert_from_milnor_matrix(12,'wall') # optional - sage.modules sage.rings.finite_rings + sage: convert_from_milnor_matrix(12,'wall') # needs sage.modules sage.rings.finite_rings [1 0 0 1 0 0 0] [0 0 1 1 0 0 0] [0 0 0 1 0 1 1] @@ -214,11 +214,11 @@ def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): [1 0 1 0 1 0 0] [1 1 1 0 0 0 0] [1 0 1 0 1 0 1] - sage: convert_from_milnor_matrix(38,'serre_cartan') # optional - sage.modules sage.rings.finite_rings + sage: convert_from_milnor_matrix(38,'serre_cartan') # needs sage.modules sage.rings.finite_rings 72 x 72 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries) - sage: x = convert_to_milnor_matrix(20,'wood_y') # optional - sage.modules sage.rings.finite_rings - sage: y = convert_from_milnor_matrix(20,'wood_y') # optional - sage.modules sage.rings.finite_rings - sage: x*y + sage: x = convert_to_milnor_matrix(20,'wood_y') # needs sage.modules sage.rings.finite_rings + sage: y = convert_from_milnor_matrix(20,'wood_y') # needs sage.modules sage.rings.finite_rings + sage: x*y # needs sage.modules sage.rings.finite_rings [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] @@ -240,7 +240,7 @@ def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): The function takes an optional argument, the prime `p` over which to work:: - sage: convert_from_milnor_matrix(17,'adem',3) # optional - sage.modules sage.rings.finite_rings + sage: convert_from_milnor_matrix(17,'adem',3) # needs sage.modules sage.rings.finite_rings [2 1 1 2] [0 2 0 1] [1 2 0 0] @@ -1108,11 +1108,12 @@ def steenrod_basis_error_check(dim, p, **kwds): EXAMPLES:: + sage: # long time sage: from sage.algebras.steenrod.steenrod_algebra_bases import steenrod_basis_error_check - sage: steenrod_basis_error_check(15,2) # long time - sage: steenrod_basis_error_check(15,2,generic=True) # long time - sage: steenrod_basis_error_check(40,3) # long time - sage: steenrod_basis_error_check(80,5) # long time + sage: steenrod_basis_error_check(15,2) + sage: steenrod_basis_error_check(15,2,generic=True) + sage: steenrod_basis_error_check(40,3) + sage: steenrod_basis_error_check(80,5) """ from sage.misc.verbose import verbose generic = kwds.get('generic', p != 2) diff --git a/src/sage/algebras/weyl_algebra.py b/src/sage/algebras/weyl_algebra.py index 14ae670b00e..b033a24065c 100644 --- a/src/sage/algebras/weyl_algebra.py +++ b/src/sage/algebras/weyl_algebra.py @@ -54,12 +54,12 @@ def repr_from_monomials(monomials, term_repr, use_latex=False): sage: from sage.algebras.weyl_algebra import repr_from_monomials sage: R. = QQ[] - sage: d = [(z, 4/7), (y, sqrt(2)), (x, -5)] # optional - sage.symbolic - sage: repr_from_monomials(d, lambda m: repr(m)) # optional - sage.symbolic + sage: d = [(z, 4/7), (y, sqrt(2)), (x, -5)] # needs sage.symbolic + sage: repr_from_monomials(d, lambda m: repr(m)) # needs sage.symbolic '4/7*z + sqrt(2)*y - 5*x' - sage: a = repr_from_monomials(d, lambda m: latex(m), True); a # optional - sage.symbolic + sage: a = repr_from_monomials(d, lambda m: latex(m), True); a # needs sage.symbolic \frac{4}{7} z + \sqrt{2} y - 5 x - sage: type(a) # optional - sage.symbolic + sage: type(a) # needs sage.symbolic The zero element:: @@ -91,12 +91,13 @@ def repr_from_monomials(monomials, term_repr, use_latex=False): Leading minus signs are dealt with appropriately:: - sage: d = [(z, -4/7), (y, -sqrt(2)), (x, -5)] # optional - sage.symbolic - sage: repr_from_monomials(d, lambda m: repr(m)) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: d = [(z, -4/7), (y, -sqrt(2)), (x, -5)] + sage: repr_from_monomials(d, lambda m: repr(m)) '-4/7*z - sqrt(2)*y - 5*x' - sage: a = repr_from_monomials(d, lambda m: latex(m), True); a # optional - sage.symbolic + sage: a = repr_from_monomials(d, lambda m: latex(m), True); a -\frac{4}{7} z - \sqrt{2} y - 5 x - sage: type(a) # optional - sage.symbolic + sage: type(a) Indirect doctests using a class that uses this function:: From 28588b78a4bb66f4786a59235443a853c4e53e79 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 12 Aug 2023 21:49:25 -0700 Subject: [PATCH 115/463] Add # needs --- src/sage/algebras/clifford_algebra_element.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/algebras/clifford_algebra_element.pyx b/src/sage/algebras/clifford_algebra_element.pyx index ce4708313b4..2e6ad0a8547 100644 --- a/src/sage/algebras/clifford_algebra_element.pyx +++ b/src/sage/algebras/clifford_algebra_element.pyx @@ -945,7 +945,7 @@ cdef class CohomologyRAAGElement(CliffordAlgebraElement): EXAMPLES:: - sage: # needs sage.graphs + sage: # needs sage.graphs sage.groups sage: C4 = graphs.CycleGraph(4) sage: A = groups.misc.RightAngledArtin(C4) sage: H = A.cohomology() From 78dfa45507859af40a7e5a64acf80ec1603c9d6d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 2 Sep 2023 14:28:28 -0700 Subject: [PATCH 116/463] src/sage/algebras/schur_algebra.py: Update # needs --- src/sage/algebras/schur_algebra.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/algebras/schur_algebra.py b/src/sage/algebras/schur_algebra.py index 0df04485a2a..4fca609ecf7 100644 --- a/src/sage/algebras/schur_algebra.py +++ b/src/sage/algebras/schur_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.groups sage.modules r""" Schur algebras for `GL_n` From b528606d24464e1891b7dbd758df3df11402b15e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 2 Sep 2023 17:23:19 -0700 Subject: [PATCH 117/463] src/sage/algebras: Add file-level tags; src/sage/rings/finite_rings: Add tags --- src/sage/algebras/iwahori_hecke_algebra.py | 2 +- src/sage/algebras/q_commuting_polynomials.py | 2 +- src/sage/algebras/q_system.py | 2 +- src/sage/algebras/quantum_groups/representations.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/algebras/iwahori_hecke_algebra.py b/src/sage/algebras/iwahori_hecke_algebra.py index 9608d684409..5ff849c8786 100644 --- a/src/sage/algebras/iwahori_hecke_algebra.py +++ b/src/sage/algebras/iwahori_hecke_algebra.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.graphs sage.modules r""" Iwahori-Hecke Algebras diff --git a/src/sage/algebras/q_commuting_polynomials.py b/src/sage/algebras/q_commuting_polynomials.py index 0b23a756fd5..10f5f55a987 100644 --- a/src/sage/algebras/q_commuting_polynomials.py +++ b/src/sage/algebras/q_commuting_polynomials.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.modules +# sage.doctest: needs sage.combinat sage.groups sage.modules r""" `q`-Commuting Polynomials diff --git a/src/sage/algebras/q_system.py b/src/sage/algebras/q_system.py index 74bf87c2787..d35c51a32a5 100644 --- a/src/sage/algebras/q_system.py +++ b/src/sage/algebras/q_system.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.graphs sage.modules r""" Q-Systems diff --git a/src/sage/algebras/quantum_groups/representations.py b/src/sage/algebras/quantum_groups/representations.py index cb026008d6d..cea110137db 100644 --- a/src/sage/algebras/quantum_groups/representations.py +++ b/src/sage/algebras/quantum_groups/representations.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.combinat sage.modules +# sage.doctest: needs sage.combinat sage.graphs sage.modules r""" Quantum Group Representations From 26fc8187d436bdb5e68d47ecc2e6fa76fb178b78 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 2 Sep 2023 17:49:04 -0700 Subject: [PATCH 118/463] src/sage/algebras/steenrod/steenrod_algebra_bases.py: Update # needs, doctest cosmetics --- .../steenrod/steenrod_algebra_bases.py | 233 +++++++++--------- 1 file changed, 119 insertions(+), 114 deletions(-) diff --git a/src/sage/algebras/steenrod/steenrod_algebra_bases.py b/src/sage/algebras/steenrod/steenrod_algebra_bases.py index d2a8760581e..9c8cc0935c8 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_bases.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_bases.py @@ -20,29 +20,29 @@ Monks [Mon1998]_ and Wood [Woo1998]_ for more information about them. For commutator bases, see the preprint by Palmieri and Zhang [PZ2008]_. -- 'milnor': Milnor basis. +- ``'milnor'``: Milnor basis. -- 'serre-cartan' or 'adem' or 'admissible': Serre-Cartan basis. +- ``'serre-cartan'`` or ``'adem'`` or ``'admissible'``: Serre-Cartan basis. Most of the rest of the bases are only defined when `p=2`. The only exceptions are the `P^s_t`-bases and the commutator bases, which are defined at all primes. -- 'wood_y': Wood's Y basis. +- ``'wood_y'``: Wood's Y basis. -- 'wood_z': Wood's Z basis. +- ``'wood_z'``: Wood's Z basis. -- 'wall', 'wall_long': Wall's basis. +- ``'wall'``, ``'wall_long'``: Wall's basis. -- 'arnon_a', 'arnon_a_long': Arnon's A basis. +- ``'arnon_a'``, ``'arnon_a_long'``: Arnon's A basis. -- 'arnon_c': Arnon's C basis. +- ``'arnon_c'``: Arnon's C basis. -- 'pst', 'pst_rlex', 'pst_llex', 'pst_deg', 'pst_revz': +- ``'pst'``, ``'pst_rlex'``, ``'pst_llex'``, ``'pst_deg'``, ``'pst_revz'``: various `P^s_t`-bases. -- 'comm', 'comm_rlex', 'comm_llex', 'comm_deg', 'comm_revz', - or these with '_long' appended: various commutator bases. +- ``'comm'``, ``'comm_rlex'``, ``'comm_llex'``, ``'comm_deg'``, ``'comm_revz'``, + or these with ``'_long'`` appended: various commutator bases. The main functions provided here are @@ -121,23 +121,24 @@ def convert_to_milnor_matrix(n, basis, p=2, generic='auto'): INPUT: - - ``n`` - non-negative integer, the dimension - - ``basis`` - string, the basis from which to convert - - ``p`` - positive prime number (optional, default 2) + - ``n`` -- non-negative integer, the dimension + - ``basis`` -- string, the basis from which to convert + - ``p`` -- positive prime number (optional, default 2) OUTPUT: - ``matrix`` - change-of-basis matrix, a square matrix over ``GF(p)`` + ``matrix`` -- change-of-basis matrix, a square matrix over `\GF{p}` EXAMPLES:: + sage: # needs sage.modules sage: from sage.algebras.steenrod.steenrod_algebra_bases import convert_to_milnor_matrix - sage: convert_to_milnor_matrix(5, 'adem') # indirect doctest # needs sage.modules sage.rings.finite_rings + sage: convert_to_milnor_matrix(5, 'adem') # indirect doctest [0 1] [1 1] - sage: convert_to_milnor_matrix(45, 'milnor') # needs sage.modules sage.rings.finite_rings + sage: convert_to_milnor_matrix(45, 'milnor') 111 x 111 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries) - sage: convert_to_milnor_matrix(12,'wall') # needs sage.modules sage.rings.finite_rings + sage: convert_to_milnor_matrix(12, 'wall') [1 0 0 1 0 0 0] [1 1 0 0 0 1 0] [0 1 0 1 0 0 0] @@ -149,15 +150,16 @@ def convert_to_milnor_matrix(n, basis, p=2, generic='auto'): The function takes an optional argument, the prime `p` over which to work:: - sage: convert_to_milnor_matrix(17,'adem',3) # needs sage.modules sage.rings.finite_rings + sage: # needs sage.modules + sage: convert_to_milnor_matrix(17, 'adem', 3) [0 0 1 1] [0 0 0 1] [1 1 1 1] [0 1 0 1] - sage: convert_to_milnor_matrix(48,'adem',5) # needs sage.modules sage.rings.finite_rings + sage: convert_to_milnor_matrix(48, 'adem', 5) [0 1] [1 1] - sage: convert_to_milnor_matrix(36,'adem',3) # needs sage.modules sage.rings.finite_rings + sage: convert_to_milnor_matrix(36, 'adem', 3) [0 0 1] [0 1 0] [1 2 0] @@ -182,20 +184,19 @@ def convert_to_milnor_matrix(n, basis, p=2, generic='auto'): def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): r""" - Change-of-basis matrix, Milnor to 'basis', in dimension - `n`. + Change-of-basis matrix, Milnor to ``basis``, in dimension `n`. INPUT: - - ``n`` - non-negative integer, the dimension + - ``n`` -- non-negative integer, the dimension - - ``basis`` - string, the basis to which to convert + - ``basis`` -- string, the basis to which to convert - - ``p`` - positive prime number (optional, default 2) + - ``p`` -- positive prime number (optional, default 2) OUTPUT: - ``matrix`` - change-of-basis matrix, a square matrix over GF(p) + ``matrix`` -- change-of-basis matrix, a square matrix over `\GF{p}` .. note:: @@ -205,8 +206,9 @@ def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): EXAMPLES:: + sage: # needs sage.modules sage: from sage.algebras.steenrod.steenrod_algebra_bases import convert_from_milnor_matrix, convert_to_milnor_matrix - sage: convert_from_milnor_matrix(12,'wall') # needs sage.modules sage.rings.finite_rings + sage: convert_from_milnor_matrix(12, 'wall') [1 0 0 1 0 0 0] [0 0 1 1 0 0 0] [0 0 0 1 0 1 1] @@ -214,11 +216,11 @@ def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): [1 0 1 0 1 0 0] [1 1 1 0 0 0 0] [1 0 1 0 1 0 1] - sage: convert_from_milnor_matrix(38,'serre_cartan') # needs sage.modules sage.rings.finite_rings + sage: convert_from_milnor_matrix(38, 'serre_cartan') 72 x 72 dense matrix over Finite Field of size 2 (use the '.str()' method to see the entries) - sage: x = convert_to_milnor_matrix(20,'wood_y') # needs sage.modules sage.rings.finite_rings - sage: y = convert_from_milnor_matrix(20,'wood_y') # needs sage.modules sage.rings.finite_rings - sage: x*y # needs sage.modules sage.rings.finite_rings + sage: x = convert_to_milnor_matrix(20, 'wood_y') + sage: y = convert_from_milnor_matrix(20, 'wood_y') + sage: x*y [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] @@ -240,7 +242,7 @@ def convert_from_milnor_matrix(n, basis, p=2, generic='auto'): The function takes an optional argument, the prime `p` over which to work:: - sage: convert_from_milnor_matrix(17,'adem',3) # needs sage.modules sage.rings.finite_rings + sage: convert_from_milnor_matrix(17, 'adem', 3) # needs sage.modules [2 1 1 2] [0 2 0 1] [1 2 0 0] @@ -259,17 +261,17 @@ def steenrod_algebra_basis(n, basis='milnor', p=2, **kwds): INPUT: - - ``n`` - non-negative integer - - ``basis`` - string, which basis to use (optional, default = 'milnor') - - ``p`` - positive prime number (optional, default = 2) - - ``profile`` - profile function (optional, default None). This + - ``n`` -- non-negative integer + - ``basis`` -- string, which basis to use (optional, default: ``'milnor'``) + - ``p`` -- positive prime number (optional, default: 2) + - ``profile`` -- profile function (optional, default: ``None``). This is just passed on to the functions :func:`milnor_basis` and :func:`pst_basis`. - - ``truncation_type`` - truncation type, either 0 or Infinity + - ``truncation_type`` -- truncation type, either 0 or Infinity (optional, default Infinity if no profile function is specified, 0 otherwise). This is just passed on to the function :func:`milnor_basis`. - - ``generic`` - boolean (optional, default = None) + - ``generic`` -- boolean (optional, default: ``None``) OUTPUT: @@ -280,25 +282,25 @@ def steenrod_algebra_basis(n, basis='milnor', p=2, **kwds): documentation for :mod:`sage.algebras.steenrod.steenrod_algebra` for details on each basis: - - 'milnor': Milnor basis. - - 'serre-cartan' or 'adem' or 'admissible': Serre-Cartan basis. - - 'pst', 'pst_rlex', 'pst_llex', 'pst_deg', 'pst_revz': + - ``'milnor'``: Milnor basis. + - ``'serre-cartan'`` or ``'adem'`` or ``'admissible'``: Serre-Cartan basis. + - ``'pst'``, ``'pst_rlex'``, ``'pst_llex'``, ``'pst_deg'``, ``'pst_revz'``: various `P^s_t`-bases. - - 'comm', 'comm_rlex', 'comm_llex', 'comm_deg', 'comm_revz', or - any of these with '_long' appended: various commutator bases. + - ``'comm'``, ``'comm_rlex'``, ``'comm_llex'``, ``'comm_deg'``, ``'comm_revz'``, or + any of these with ``'_long'`` appended: various commutator bases. The rest of these bases are only defined when `p=2`. - - 'wood_y': Wood's Y basis. - - 'wood_z': Wood's Z basis. - - 'wall' or 'wall_long': Wall's basis. - - 'arnon_a' or 'arnon_a_long': Arnon's A basis. - - 'arnon_c': Arnon's C basis. + - ``'wood_y'``: Wood's Y basis. + - ``'wood_z'``: Wood's Z basis. + - ``'wall'`` or ``'wall_long'``: Wall's basis. + - ``'arnon_a'`` or ``'arnon_a_long'``: Arnon's A basis. + - ``'arnon_c'``: Arnon's C basis. EXAMPLES:: sage: from sage.algebras.steenrod.steenrod_algebra_bases import steenrod_algebra_basis - sage: steenrod_algebra_basis(7,'milnor') # indirect doctest + sage: steenrod_algebra_basis(7, 'milnor') # indirect doctest ((0, 0, 1), (1, 2), (4, 1), (7,)) sage: steenrod_algebra_basis(5) # milnor basis is the default ((2, 1), (5,)) @@ -320,15 +322,15 @@ def steenrod_algebra_basis(n, basis='milnor', p=2, **kwds): Other bases:: - sage: steenrod_algebra_basis(7,'admissible') + sage: steenrod_algebra_basis(7, 'admissible') ((7,), (6, 1), (4, 2, 1), (5, 2)) - sage: steenrod_algebra_basis(13,'admissible',p=3) + sage: steenrod_algebra_basis(13, 'admissible', p=3) ((1, 3, 0), (0, 3, 1)) - sage: steenrod_algebra_basis(5,'wall') + sage: steenrod_algebra_basis(5, 'wall') (((2, 2), (0, 0)), ((1, 1), (1, 0))) - sage: steenrod_algebra_basis(5,'wall_long') + sage: steenrod_algebra_basis(5, 'wall_long') (((2, 2), (0, 0)), ((1, 1), (1, 0))) - sage: steenrod_algebra_basis(5,'pst-rlex') + sage: steenrod_algebra_basis(5, 'pst-rlex') (((0, 1), (2, 1)), ((1, 1), (0, 2))) """ from .steenrod_algebra_misc import get_basis_name @@ -375,14 +377,14 @@ def steenrod_algebra_basis(n, basis='milnor', p=2, **kwds): def restricted_partitions(n, l, no_repeats=False): """ - List of 'restricted' partitions of n: partitions with parts taken - from list. + List of 'restricted' partitions of `n`: partitions with parts taken + from list `l`. INPUT: - - ``n`` - non-negative integer - - ``l`` - list of positive integers - - ``no_repeats`` - boolean (optional, default = False), if True, + - ``n`` -- non-negative integer + - ``l`` -- list of positive integers + - ``no_repeats`` -- boolean (optional, default: ``False``), if ``True``, only return partitions with no repeated parts OUTPUT: list of lists @@ -406,10 +408,10 @@ def restricted_partitions(n, l, no_repeats=False): sage: restricted_partitions(10, [6,4,2], no_repeats=True) [[6, 4]] - 'l' may have repeated elements. If 'no_repeats' is False, this - has no effect. If 'no_repeats' is True, and if the repeated - elements appear consecutively in 'l', then each element may be - used only as many times as it appears in 'l':: + ``l`` may have repeated elements. If ``no_repeats`` is ``False``, this + has no effect. If ``no_repeats`` is ``True``, and if the repeated + elements appear consecutively in ``l``, then each element may be + used only as many times as it appears in ``l``:: sage: restricted_partitions(10, [6,4,2,2], no_repeats=True) [[6, 4], [6, 2, 2]] @@ -420,7 +422,7 @@ def restricted_partitions(n, l, no_repeats=False): are likely meaningless, containing several partitions more than once, for example.) - In the following examples, 'no_repeats' is False:: + In the following examples, ``no_repeats`` is ``False``:: sage: restricted_partitions(10, [6,4,2]) [[6, 4], [6, 2, 2], [4, 4, 2], [4, 2, 2, 2], [2, 2, 2, 2, 2]] @@ -448,25 +450,25 @@ def restricted_partitions(n, l, no_repeats=False): old_i = i return results -def xi_degrees(n,p=2, reverse=True): +def xi_degrees(n, p=2, reverse=True): r""" - Decreasing list of degrees of the xi_i's, starting in degree n. + Decreasing list of degrees of the `\xi_i`'s, starting in degree `n`. INPUT: - - `n` - integer - - `p` - prime number, optional (default 2) - - ``reverse`` - bool, optional (default True) + - ``n`` -- integer + - ``p`` -- prime number, optional (default: 2) + - ``reverse`` -- bool, optional (default: ``True``) - OUTPUT: ``list`` - list of integers + OUTPUT: ``list`` -- list of integers When `p=2`: decreasing list of the degrees of the `\xi_i`'s with - degree at most n. + degree at most `n`. At odd primes: decreasing list of these degrees, each divided by `2(p-1)`. - If ``reverse`` is False, then return an increasing list rather + If ``reverse`` is ``False``, then return an increasing list rather than a decreasing one. EXAMPLES:: @@ -475,9 +477,9 @@ def xi_degrees(n,p=2, reverse=True): [15, 7, 3, 1] sage: sage.algebras.steenrod.steenrod_algebra_bases.xi_degrees(17, reverse=False) [1, 3, 7, 15] - sage: sage.algebras.steenrod.steenrod_algebra_bases.xi_degrees(17,p=3) + sage: sage.algebras.steenrod.steenrod_algebra_bases.xi_degrees(17, p=3) [13, 4, 1] - sage: sage.algebras.steenrod.steenrod_algebra_bases.xi_degrees(400,p=17) + sage: sage.algebras.steenrod.steenrod_algebra_bases.xi_degrees(400, p=17) [307, 18, 1] """ from sage.rings.integer import Integer @@ -505,23 +507,23 @@ def milnor_basis(n, p=2, **kwds): INPUT: - - ``n`` - non-negative integer + - ``n`` -- non-negative integer - - ``p`` - positive prime number (optional, default 2) + - ``p`` -- positive prime number (optional, default 2) - - ``profile`` - profile function (optional, default None). + - ``profile`` - profile function (optional, default ``None``). Together with ``truncation_type``, specify the profile function - to be used; None means the profile function for the entire + to be used; ``None`` means the profile function for the entire Steenrod algebra. See :mod:`sage.algebras.steenrod.steenrod_algebra` and :func:`SteenrodAlgebra ` for information on profile functions. - - ``truncation_type`` - truncation type, either 0 or Infinity + - ``truncation_type`` -- truncation type, either 0 or Infinity (optional, default Infinity if no profile function is specified, 0 otherwise) - OUTPUT: tuple of mod p Milnor basis elements in dimension n + OUTPUT: tuple of mod `p` Milnor basis elements in dimension `n` At the prime 2, the Milnor basis consists of symbols of the form `\text{Sq}(m_1, m_2, ..., m_t)`, where each @@ -669,11 +671,11 @@ def serre_cartan_basis(n, p=2, bound=1, **kwds): INPUT: - - ``n`` - non-negative integer - - ``bound`` - positive integer (optional) - - ``prime`` - positive prime number (optional, default 2) + - ``n`` -- non-negative integer + - ``bound`` -- positive integer (optional) + - ``prime`` -- positive prime number (optional, default 2) - OUTPUT: tuple of mod p Serre-Cartan basis elements in dimension n + OUTPUT: tuple of mod `p` Serre-Cartan basis elements in dimension `n` The Serre-Cartan basis consists of 'admissible monomials in the Steenrod squares'. Thus at the prime 2, it consists of monomials @@ -694,8 +696,8 @@ def serre_cartan_basis(n, p=2, bound=1, **kwds): ((1, 5, 0, 1, 1), (1, 6, 1)) If optional argument ``bound`` is present, include only those monomials - whose last term is at least ``bound`` (when p=2), or those for which - `s_k - e_k \geq bound` (when p is odd). :: + whose last term is at least ``bound`` (when `p=2`), or those for which + `s_k - e_k \geq bound` (when `p` is odd). :: sage: serre_cartan_basis(7, bound=2) ((7,), (5, 2)) @@ -753,27 +755,28 @@ def atomic_basis(n, basis, **kwds): INPUT: - - ``n`` - non-negative integer - - ``basis`` - string, the name of the basis + - ``n`` -- non-negative integer - - ``profile`` - profile function (optional, default None). + - ``basis`` -- string, the name of the basis + + - ``profile`` -- profile function (optional, default: ``None``). Together with ``truncation_type``, specify the profile function - to be used; None means the profile function for the entire + to be used; ``None`` means the profile function for the entire Steenrod algebra. See :mod:`sage.algebras.steenrod.steenrod_algebra` and :func:`SteenrodAlgebra` for information on profile functions. - - ``truncation_type`` - truncation type, either 0 or Infinity + - ``truncation_type`` -- truncation type, either 0 or Infinity (optional, default Infinity if no profile function is specified, 0 otherwise). - OUTPUT: tuple of basis elements in dimension n + OUTPUT: tuple of basis elements in dimension `n` The atomic bases include Wood's Y and Z bases, Wall's basis, Arnon's A basis, the `P^s_t`-bases, and the commutator bases. (All of these bases are constructed similarly, hence their constructions have been consolidated into a single function. Also, - see the documentation for 'steenrod_algebra_basis' for + see the documentation for :func:`steenrod_algebra_basis` for descriptions of them.) For `P^s_t`-bases, you may also specify a profile function and truncation type; profile functions are ignored for the other bases. @@ -824,12 +827,12 @@ def atomic_basis(n, basis, **kwds): """ def degree_dictionary(n, basis): """ - Dictionary of atomic degrees for basis up to degree n. + Dictionary of atomic degrees for basis up to degree `n`. - The keys for the dictionary are the atomic degrees - the numbers of - the form 2^i (2^j - 1) - which are less than or equal to n. The value + The keys for the dictionary are the atomic degrees -- the numbers of + the form `2^i (2^j - 1)` -- which are less than or equal to `n`. The value associated to such a degree depends on basis; it has the form - (s,t), where (s,t) is a pair of integers which indexes the + `(s,t)`, where `(s,t)` is a pair of integers which indexes the corresponding element. """ dict = {} @@ -931,11 +934,11 @@ def arnonC_basis(n,bound=1): INPUT: - - ``n`` - non-negative integer + - ``n`` -- non-negative integer - - ``bound`` - positive integer (optional) + - ``bound`` -- positive integer (optional) - OUTPUT: tuple of basis elements in dimension n + OUTPUT: tuple of basis elements in dimension `n` The elements of Arnon's C basis are monomials of the form `\text{Sq}^{t_1} ... \text{Sq}^{t_m}` where for each @@ -978,22 +981,24 @@ def atomic_basis_odd(n, basis, p, **kwds): INPUT: - - ``n`` - non-negative integer - - ``basis`` - string, the name of the basis - - ``p`` - positive prime number + - ``n`` -- non-negative integer + + - ``basis`` -- string, the name of the basis + + - ``p`` -- positive prime number - - ``profile`` - profile function (optional, default None). + - ``profile`` -- profile function (optional, default: ``None``). Together with ``truncation_type``, specify the profile function - to be used; None means the profile function for the entire + to be used; ``None`` means the profile function for the entire Steenrod algebra. See :mod:`sage.algebras.steenrod.steenrod_algebra` and :func:`SteenrodAlgebra` for information on profile functions. - - ``truncation_type`` - truncation type, either 0 or Infinity + - ``truncation_type`` -- truncation type, either 0 or Infinity (optional, default Infinity if no profile function is specified, 0 otherwise). - OUTPUT: tuple of basis elements in dimension n + OUTPUT: tuple of basis elements in dimension `n` The only possible difference in the implementations for `P^s_t` bases and commutator bases is that the former make sense, and @@ -1091,8 +1096,8 @@ def steenrod_basis_error_check(dim, p, **kwds): INPUT: - - ``dim`` - non-negative integer - - ``p`` - positive prime number + - ``dim`` -- non-negative integer + - ``p`` -- positive prime number OUTPUT: None @@ -1100,7 +1105,7 @@ def steenrod_basis_error_check(dim, p, **kwds): if the change-of-basis matrices are invertible. If something goes wrong, an error message is printed. - This function checks at the prime ``p`` as the dimension goes up + This function checks at the prime `p` as the dimension goes up from 0 to ``dim``. If you set the Sage verbosity level to a positive integer (using @@ -1110,10 +1115,10 @@ def steenrod_basis_error_check(dim, p, **kwds): sage: # long time sage: from sage.algebras.steenrod.steenrod_algebra_bases import steenrod_basis_error_check - sage: steenrod_basis_error_check(15,2) - sage: steenrod_basis_error_check(15,2,generic=True) - sage: steenrod_basis_error_check(40,3) - sage: steenrod_basis_error_check(80,5) + sage: steenrod_basis_error_check(15, 2) + sage: steenrod_basis_error_check(15, 2, generic=True) + sage: steenrod_basis_error_check(40, 3) + sage: steenrod_basis_error_check(80, 5) """ from sage.misc.verbose import verbose generic = kwds.get('generic', p != 2) From a20a928d7b9a12cfbfec424e2fa3cdaaa72c72ce Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 2 Sep 2023 22:42:26 -0700 Subject: [PATCH 119/463] sage.algebras: Docstring cosmetics, update # needs --- src/sage/algebras/down_up_algebra.py | 5 +- .../finite_dimensional_algebra.py | 2 +- .../finite_dimensional_algebra_element.pyx | 2 +- src/sage/algebras/finite_gca.py | 2 +- src/sage/algebras/free_algebra.py | 125 ++++++++++-------- src/sage/algebras/free_algebra_quotient.py | 2 +- src/sage/algebras/free_zinbiel_algebra.py | 26 ++-- .../hecke_algebras/ariki_koike_algebra.py | 2 + src/sage/algebras/iwahori_hecke_algebra.py | 28 ++-- src/sage/algebras/orlik_solomon.py | 66 ++++----- .../algebras/steenrod/steenrod_algebra.py | 69 +++++----- 11 files changed, 176 insertions(+), 153 deletions(-) diff --git a/src/sage/algebras/down_up_algebra.py b/src/sage/algebras/down_up_algebra.py index d5fe1c257eb..088e7ac30ad 100644 --- a/src/sage/algebras/down_up_algebra.py +++ b/src/sage/algebras/down_up_algebra.py @@ -540,12 +540,13 @@ class VermaModule(CombinatorialFreeModule): construction of the irreducible representation `V(5)` (but they are different as `\mathfrak{gl}_2` weights):: - sage: B = crystals.Tableaux(['A',1], shape=[5]) - sage: [b.weight() for b in B] + sage: B = crystals.Tableaux(['A',1], shape=[5]) # needs sage.graphs + sage: [b.weight() for b in B] # needs sage.graphs [(5, 0), (4, 1), (3, 2), (2, 3), (1, 4), (0, 5)] An example with periodic weights (see Theorem 2.13 of [BR1998]_):: + sage: # needs sage.rings.number_field sage: k. = CyclotomicField(6) sage: al = z6 + 1 sage: (al - 1)^6 == 1 diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py index 448c1916aed..a3b8742b4e0 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py @@ -210,7 +210,7 @@ def _coerce_map_from_(self, S): True sage: A.has_coerce_map_from(GF(3)) True - sage: A.has_coerce_map_from(GF(5)) # needs sage.rings.finite_rings + sage: A.has_coerce_map_from(GF(5)) False sage: A.has_coerce_map_from(QQ) False diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx index f953a9fab7c..d58e1ac8647 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx @@ -375,7 +375,7 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): True sage: A(2) == 3 False - sage: A(2) == GF(5)(2) # needs sage.rings.finite_rings + sage: A(2) == GF(5)(2) False sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0,0], [0,1,0], [0,0,0]]), diff --git a/src/sage/algebras/finite_gca.py b/src/sage/algebras/finite_gca.py index f2e7d9af301..08ebb27616e 100644 --- a/src/sage/algebras/finite_gca.py +++ b/src/sage/algebras/finite_gca.py @@ -127,7 +127,7 @@ class FiniteGCAlgebra(CombinatorialFreeModule, Algebra): omitted, an instance of the class :class:`sage.algebras.commutative_dga.GCAlgebra` is created instead:: - sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,2,6,6)) + sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,2,6,6)) # needs sage.libs.singular sage: type(A) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index d1a536a7043..61fc6175a8c 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -71,50 +71,54 @@ TESTS:: - sage: # needs sage.rings.finite_rings sage: F = FreeAlgebra(GF(5),3,'x') sage: TestSuite(F).run() sage: F is loads(dumps(F)) True - sage: F = FreeAlgebra(GF(5),3,'x', implementation='letterplace') # needs sage.libs.singular - sage: TestSuite(F).run() # needs sage.libs.singular - sage: F is loads(dumps(F)) # needs sage.libs.singular + + sage: # needs sage.libs.singular + sage: F = FreeAlgebra(GF(5),3,'x', implementation='letterplace') + sage: TestSuite(F).run() + sage: F is loads(dumps(F)) True :: - sage: # needs sage.rings.finite_rings sage: F. = FreeAlgebra(GF(5),3) sage: TestSuite(F).run() sage: F is loads(dumps(F)) True - sage: F. = FreeAlgebra(GF(5),3, implementation='letterplace') # needs sage.libs.singular - sage: TestSuite(F).run() # needs sage.libs.singular - sage: F is loads(dumps(F)) # needs sage.libs.singular + + sage: # needs sage.libs.singular + sage: F. = FreeAlgebra(GF(5),3, implementation='letterplace') + sage: TestSuite(F).run() + sage: F is loads(dumps(F)) True :: - sage: # needs sage.rings.finite_rings sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y']) sage: TestSuite(F).run() sage: F is loads(dumps(F)) True - sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y'], implementation='letterplace') # needs sage.libs.singular - sage: TestSuite(F).run() # needs sage.libs.singular - sage: F is loads(dumps(F)) # needs sage.libs.singular + + sage: # needs sage.libs.singular + sage: F = FreeAlgebra(GF(5),3, ['xx', 'zba', 'Y'], implementation='letterplace') + sage: TestSuite(F).run() + sage: F is loads(dumps(F)) True :: - sage: # needs sage.rings.finite_rings sage: F = FreeAlgebra(GF(5),3, 'abc') sage: TestSuite(F).run() sage: F is loads(dumps(F)) True - sage: F = FreeAlgebra(GF(5),3, 'abc', implementation='letterplace') # needs sage.libs.singular - sage: TestSuite(F).run() # needs sage.libs.singular - sage: F is loads(dumps(F)) # needs sage.libs.singular + + sage: # needs sage.libs.singular + sage: F = FreeAlgebra(GF(5),3, 'abc', implementation='letterplace') + sage: TestSuite(F).run() + sage: F is loads(dumps(F)) True :: @@ -127,10 +131,11 @@ Note that the letterplace implementation can only be used if the corresponding (multivariate) polynomial ring has an implementation in Singular:: - sage: FreeAlgebra(FreeAlgebra(ZZ,2,'ab'), 2, 'x', implementation='letterplace') # needs sage.libs.singular sage.rings.finite_rings + sage: FreeAlgebra(FreeAlgebra(ZZ,2,'ab'), 2, 'x', implementation='letterplace') # needs sage.libs.singular Traceback (most recent call last): ... - NotImplementedError: polynomials over Free Algebra on 2 generators (a, b) over Integer Ring are not supported in Singular + NotImplementedError: polynomials over Free Algebra on 2 generators (a, b) + over Integer Ring are not supported in Singular """ #***************************************************************************** @@ -174,18 +179,18 @@ class FreeAlgebraFactory(UniqueFactory): EXAMPLES:: - sage: FreeAlgebra(GF(5),3,'x') # needs sage.rings.finite_rings + sage: FreeAlgebra(GF(5),3,'x') Free Algebra on 3 generators (x0, x1, x2) over Finite Field of size 5 - sage: F. = FreeAlgebra(GF(5),3) # needs sage.rings.finite_rings - sage: (x+y+z)^2 # needs sage.rings.finite_rings + sage: F. = FreeAlgebra(GF(5),3) + sage: (x+y+z)^2 x^2 + x*y + x*z + y*x + y^2 + y*z + z*x + z*y + z^2 - sage: FreeAlgebra(GF(5),3, 'xx, zba, Y') # needs sage.rings.finite_rings + sage: FreeAlgebra(GF(5),3, 'xx, zba, Y') Free Algebra on 3 generators (xx, zba, Y) over Finite Field of size 5 - sage: FreeAlgebra(GF(5),3, 'abc') # needs sage.rings.finite_rings + sage: FreeAlgebra(GF(5),3, 'abc') Free Algebra on 3 generators (a, b, c) over Finite Field of size 5 - sage: FreeAlgebra(GF(5),1, 'z') # needs sage.rings.finite_rings + sage: FreeAlgebra(GF(5),1, 'z') Free Algebra on 1 generators (z,) over Finite Field of size 5 - sage: FreeAlgebra(GF(5),1, ['alpha']) # needs sage.rings.finite_rings + sage: FreeAlgebra(GF(5),1, ['alpha']) Free Algebra on 1 generators (alpha,) over Finite Field of size 5 sage: FreeAlgebra(FreeAlgebra(ZZ,1,'a'), 2, 'x') Free Algebra on 2 generators (x0, x1) over @@ -197,14 +202,14 @@ class FreeAlgebraFactory(UniqueFactory): sage: G = FreeAlgebra(ZZ,3,'x,y,z') sage: F is G True - sage: F. = FreeAlgebra(GF(5),3) # indirect doctest # needs sage.rings.finite_rings - sage: F is loads(dumps(F)) # needs sage.rings.finite_rings + sage: F. = FreeAlgebra(GF(5),3) # indirect doctest + sage: F is loads(dumps(F)) True - sage: F is FreeAlgebra(GF(5),['x','y','z']) # needs sage.rings.finite_rings + sage: F is FreeAlgebra(GF(5),['x','y','z']) True - sage: copy(F) is F is loads(dumps(F)) # needs sage.rings.finite_rings + sage: copy(F) is F is loads(dumps(F)) True - sage: TestSuite(F).run() # needs sage.rings.finite_rings + sage: TestSuite(F).run() By :trac:`7797`, we provide a different implementation of free algebras, based on Singular's "letterplace rings". Our letterplace @@ -213,7 +218,7 @@ class FreeAlgebraFactory(UniqueFactory): elements are supported. Of course, isomorphic algebras in different implementations are not identical:: - sage: # needs sage.libs.singular sage.rings.finite_rings + sage: # needs sage.libs.singular sage: G = FreeAlgebra(GF(5),['x','y','z'], implementation='letterplace') sage: F == G False @@ -225,7 +230,7 @@ class FreeAlgebraFactory(UniqueFactory): :: - sage: # needs sage.libs.singular sage.rings.finite_rings + sage: # needs sage.libs.singular sage: H = FreeAlgebra(GF(5), ['x','y','z'], implementation='letterplace', ....: degrees=[1,2,3]) sage: F != H != G @@ -263,23 +268,24 @@ def create_key(self, base_ring, arg1=None, arg2=None, TESTS:: - sage: # needs sage.rings.finite_rings sage: FreeAlgebra.create_key(GF(5),['x','y','z']) (Finite Field of size 5, ('x', 'y', 'z')) sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3) (Finite Field of size 5, ('x', 'y', 'z')) sage: FreeAlgebra.create_key(GF(5),3,'xyz') (Finite Field of size 5, ('x', 'y', 'z')) - sage: FreeAlgebra.create_key(GF(5),['x','y','z'], # needs sage.libs.singular + + sage: # needs sage.libs.singular + sage: FreeAlgebra.create_key(GF(5),['x','y','z'], ....: implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) - sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3, # needs sage.libs.singular + sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3, ....: implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) - sage: FreeAlgebra.create_key(GF(5),3,'xyz', # needs sage.libs.singular + sage: FreeAlgebra.create_key(GF(5),3,'xyz', ....: implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) - sage: FreeAlgebra.create_key(GF(5),3,'xyz', # needs sage.libs.singular + sage: FreeAlgebra.create_key(GF(5),3,'xyz', ....: implementation='letterplace', degrees=[1,2,3]) ((1, 2, 3), Multivariate Polynomial Ring in x, y, z, x_ over Finite Field of size 5) @@ -370,7 +376,8 @@ def is_FreeAlgebra(x): True sage: is_FreeAlgebra(FreeAlgebra(ZZ,10,'x',implementation='letterplace')) True - sage: is_FreeAlgebra(FreeAlgebra(ZZ,10,'x',implementation='letterplace', degrees=list(range(1,11)))) + sage: is_FreeAlgebra(FreeAlgebra(ZZ,10,'x',implementation='letterplace', + ....: degrees=list(range(1,11)))) True """ @@ -562,23 +569,23 @@ def _element_constructor_(self, x): TESTS:: - sage: # needs sage.rings.finite_rings + sage: # needs sage.libs.singular sage: F. = FreeAlgebra(GF(5),3) - sage: L. = FreeAlgebra(ZZ,3,implementation='letterplace') # needs sage.libs.singular - sage: F(x) # indirect doctest # needs sage.libs.singular + sage: L. = FreeAlgebra(ZZ,3,implementation='letterplace') + sage: F(x) # indirect doctest x - sage: F.1*L.2 # needs sage.libs.singular + sage: F.1*L.2 y*z - sage: (F.1*L.2).parent() is F # needs sage.libs.singular + sage: (F.1*L.2).parent() is F True :: - sage: # needs sage.rings.finite_rings + sage: # needs sage.libs.singular sage.rings.finite_rings sage: K. = GF(25) sage: F. = FreeAlgebra(K,3) - sage: L. = FreeAlgebra(K,3, implementation='letterplace') # needs sage.libs.singular - sage: F.1+(z+1)*L.2 # needs sage.libs.singular + sage: L. = FreeAlgebra(K,3, implementation='letterplace') + sage: F.1 + (z+1)*L.2 b + (z+1)*c Check that :trac:`15169` is fixed:: @@ -688,23 +695,24 @@ def _coerce_map_from_(self, R): sage: F.has_coerce_map_from(PolynomialRing(ZZ, 3, 'x,y,z')) False - sage: K. = GF(25) # needs sage.rings.finite_rings - sage: F. = FreeAlgebra(K,3) # needs sage.rings.finite_rings - sage: F._coerce_map_from_(ZZ) # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K. = GF(25) + sage: F. = FreeAlgebra(K,3) + sage: F._coerce_map_from_(ZZ) True - sage: F._coerce_map_from_(QQ) # needs sage.rings.finite_rings + sage: F._coerce_map_from_(QQ) False - sage: F._coerce_map_from_(F.monoid()) # needs sage.rings.finite_rings + sage: F._coerce_map_from_(F.monoid()) True - sage: F._coerce_map_from_(F.pbw_basis()) # needs sage.rings.finite_rings + sage: F._coerce_map_from_(F.pbw_basis()) True sage: G = FreeAlgebra(ZZ, 3, 'a,b,c') - sage: F._coerce_map_from_(G) # needs sage.rings.finite_rings + sage: F._coerce_map_from_(G) True - sage: G._coerce_map_from_(F) # needs sage.rings.finite_rings + sage: G._coerce_map_from_(F) False - sage: L. = FreeAlgebra(K,3, implementation='letterplace') # needs sage.libs.singular sage.rings.finite_rings - sage: F.1 + (z+1) * L.2 # needs sage.libs.singular sage.rings.finite_rings + sage: L. = FreeAlgebra(K,3, implementation='letterplace') # needs sage.libs.singular + sage: F.1 + (z+1) * L.2 # needs sage.libs.singular b + (z+1)*c """ if self._indices.has_coerce_map_from(R): @@ -854,6 +862,7 @@ def g_algebra(self, relations, names=None, order='degrevlex', check=True): EXAMPLES:: + sage: # needs sage.libs.singular sage: A. = FreeAlgebra(QQ,3) sage: G = A.g_algebra({y*x: -x*y}) sage: (x,y,z) = G.gens() @@ -864,12 +873,12 @@ def g_algebra(self, relations, names=None, order='degrevlex', check=True): sage: z*x x*z sage: (x,y,z) = A.gens() - sage: G = A.g_algebra({y*x: -x*y+1}) + sage: G = A.g_algebra({y*x: -x*y + 1}) sage: (x,y,z) = G.gens() sage: y*x -x*y + 1 sage: (x,y,z) = A.gens() - sage: G = A.g_algebra({y*x: -x*y+z}) + sage: G = A.g_algebra({y*x: -x*y + z}) sage: (x,y,z) = G.gens() sage: y*x -x*y + z diff --git a/src/sage/algebras/free_algebra_quotient.py b/src/sage/algebras/free_algebra_quotient.py index b0f0efed0cd..e41e9c877c5 100644 --- a/src/sage/algebras/free_algebra_quotient.py +++ b/src/sage/algebras/free_algebra_quotient.py @@ -191,7 +191,7 @@ def _coerce_map_from_(self, S): True sage: H._coerce_map_from_(QQ) True - sage: H._coerce_map_from_(GF(7)) # needs sage.rings.finite_rings + sage: H._coerce_map_from_(GF(7)) False """ return S == self or self.__free_algebra.has_coerce_map_from(S) diff --git a/src/sage/algebras/free_zinbiel_algebra.py b/src/sage/algebras/free_zinbiel_algebra.py index cee797e37c4..d421b2d7aee 100644 --- a/src/sage/algebras/free_zinbiel_algebra.py +++ b/src/sage/algebras/free_zinbiel_algebra.py @@ -540,14 +540,14 @@ def _coerce_map_from_(self, R): EXAMPLES:: - sage: F = algebras.FreeZinbiel(GF(7), 'x,y,z'); F # needs sage.rings.finite_rings + sage: F = algebras.FreeZinbiel(GF(7), 'x,y,z'); F Free Zinbiel algebra on generators (Z[x], Z[y], Z[z]) over Finite Field of size 7 Elements of the free Zinbiel algebra canonically coerce in:: - sage: x, y, z = F.gens() # needs sage.rings.finite_rings - sage: F.coerce(x+y) == x+y # needs sage.rings.finite_rings + sage: x, y, z = F.gens() + sage: F.coerce(x+y) == x+y True The free Zinbiel algebra over `\ZZ` on `x, y, z` coerces in, since @@ -555,15 +555,15 @@ def _coerce_map_from_(self, R): sage: G = algebras.FreeZinbiel(ZZ, 'x,y,z') sage: Gx,Gy,Gz = G.gens() - sage: z = F.coerce(Gx+Gy); z # needs sage.rings.finite_rings + sage: z = F.coerce(Gx+Gy); z Z[x] + Z[y] - sage: z.parent() is F # needs sage.rings.finite_rings + sage: z.parent() is F True However, `\GF{7}` does not coerce to `\ZZ`, so the free Zinbiel algebra over `\GF{7}` does not coerce to the one over `\ZZ`:: - sage: G.coerce(y) # needs sage.rings.finite_rings + sage: G.coerce(y) Traceback (most recent call last): ... TypeError: no canonical coercion from Free Zinbiel algebra on @@ -642,18 +642,18 @@ class ZinbielFunctor(ConstructionFunctor): sage: F = P.construction()[0]; F Zinbiel[x,y] - sage: A = GF(5)['a,b'] # needs sage.rings.finite_rings - sage: a, b = A.gens() # needs sage.rings.finite_rings - sage: F(A) # needs sage.rings.finite_rings + sage: A = GF(5)['a,b'] + sage: a, b = A.gens() + sage: F(A) Free Zinbiel algebra on generators (Z[x], Z[y]) over Multivariate Polynomial Ring in a, b over Finite Field of size 5 - sage: f = A.hom([a+b,a-b],A) # needs sage.rings.finite_rings - sage: F(f) # needs sage.rings.finite_rings + sage: f = A.hom([a+b,a-b],A) + sage: F(f) Generic endomorphism of Free Zinbiel algebra on generators (Z[x], Z[y]) over Multivariate Polynomial Ring in a, b over Finite Field of size 5 - sage: F(f)(a * F(A)(x)) # needs sage.rings.finite_rings + sage: F(f)(a * F(A)(x)) (a+b)*Z[x] """ rank = 9 @@ -706,7 +706,7 @@ def _apply_functor_to_morphism(self, f): TESTS:: sage: R = algebras.FreeZinbiel(ZZ, 'x').construction()[0] - sage: R(ZZ.hom(GF(3))) # indirect doctest # needs sage.rings.finite_rings + sage: R(ZZ.hom(GF(3))) # indirect doctest Generic morphism: From: Free Zinbiel algebra on generators (Z[x],) over Integer Ring diff --git a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py index df2818d5dd5..f34beb5a1f8 100644 --- a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py +++ b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py @@ -234,6 +234,7 @@ class ArikiKoikeAlgebra(Parent, UniqueRepresentation): We construct an Ariki-Koike algebra with `u = (1, \zeta_3, \zeta_3^2)`, where `\zeta_3` is a primitive third root of unity:: + sage: # needs sage.rings.number_field sage: F = CyclotomicField(3) sage: zeta3 = F.gen() sage: R. = LaurentPolynomialRing(F) @@ -248,6 +249,7 @@ class ArikiKoikeAlgebra(Parent, UniqueRepresentation): Next, we additionally take `q = 1` to obtain the group algebra of `G(r, 1, n)`:: + sage: # needs sage.rings.number_field sage: F = CyclotomicField(3) sage: zeta3 = F.gen() sage: H = algebras.ArikiKoike(3, 4, q=1, u=[1, zeta3, zeta3^2], R=F) diff --git a/src/sage/algebras/iwahori_hecke_algebra.py b/src/sage/algebras/iwahori_hecke_algebra.py index 5ff849c8786..a599c28a488 100644 --- a/src/sage/algebras/iwahori_hecke_algebra.py +++ b/src/sage/algebras/iwahori_hecke_algebra.py @@ -52,15 +52,15 @@ def normalized_laurent_polynomial(R, p): the base ring. This function is a hack to recover from this. This occurs somewhat haphazardly with Laurent polynomial rings:: - sage: R.=LaurentPolynomialRing(ZZ) + sage: R. = LaurentPolynomialRing(ZZ) sage: [type(c) for c in (q**-1).coefficients()] [] It also happens in any ring when dividing by units:: - sage: type ( 3/1 ) + sage: type(3/1) - sage: type ( -1/-1 ) + sage: type(-1/-1) This function is a variation on a suggested workaround of Nils Bruin. @@ -68,19 +68,19 @@ def normalized_laurent_polynomial(R, p): EXAMPLES:: sage: from sage.algebras.iwahori_hecke_algebra import normalized_laurent_polynomial - sage: type ( normalized_laurent_polynomial(ZZ, 3/1) ) + sage: type(normalized_laurent_polynomial(ZZ, 3/1)) - sage: R.=LaurentPolynomialRing(ZZ) + sage: R. = LaurentPolynomialRing(ZZ) sage: [type(c) for c in normalized_laurent_polynomial(R, q**-1).coefficients()] [] - sage: R.=LaurentPolynomialRing(ZZ,2) - sage: p=normalized_laurent_polynomial(R, 2*u**-1*v**-1+u*v) - sage: ui=normalized_laurent_polynomial(R, u^-1) - sage: vi=normalized_laurent_polynomial(R, v^-1) - sage: p(ui,vi) + sage: R. = LaurentPolynomialRing(ZZ,2) + sage: p = normalized_laurent_polynomial(R, 2*u**-1*v**-1 + u*v) + sage: ui = normalized_laurent_polynomial(R, u^-1) + sage: vi = normalized_laurent_polynomial(R, v^-1) + sage: p(ui, vi) 2*u*v + u^-1*v^-1 - sage: q= u+v+ui - sage: q(ui,vi) + sage: q = u+v+ui + sage: q(ui, vi) u + v^-1 + u^-1 """ try: @@ -208,8 +208,8 @@ class IwahoriHeckeAlgebra(Parent, UniqueRepresentation): The Kazhdan-Lusztig bases are implemented inside `H` whenever `-q_1 q_2` has a square root:: - sage: H = IwahoriHeckeAlgebra('A3', u^2,-v^2) - sage: T=H.T(); Cp= H.Cp(); C=H.C() + sage: H = IwahoriHeckeAlgebra('A3', u^2, -v^2) + sage: T = H.T(); Cp = H.Cp(); C = H.C() sage: T(Cp[1]) (u^-1*v^-1)*T[1] + (u^-1*v) sage: T(C[1]) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 2cb2dcb8299..7cb469f09cc 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -459,7 +459,7 @@ def as_gca(self): EXAMPLES:: - sage: # needs sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron sage.graphs sage: H = hyperplane_arrangements.braid(3) sage: O = H.orlik_solomon_algebra(QQ) sage: O.as_gca() @@ -470,7 +470,7 @@ def as_gca(self): sage: N = matroids.named_matroids.Fano() sage: O = N.orlik_solomon_algebra(QQ) - sage: O.as_gca() + sage: O.as_gca() # needs sage.libs.singular Graded Commutative Algebra with generators ('e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6') in degrees (1, 1, 1, 1, 1, 1, 1) with relations [e1*e2 - e1*e3 + e2*e3, e0*e1*e3 - e0*e1*e4 + e0*e3*e4 - e1*e3*e4, @@ -524,7 +524,7 @@ def as_cdga(self): EXAMPLES:: - sage: # needs sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron sage.graphs sage: H = hyperplane_arrangements.braid(3) sage: O = H.orlik_solomon_algebra(QQ) sage: O.as_cdga() @@ -605,20 +605,21 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): easier, we'll start the indexing at `1` so that the `S_6` action on the groundset is simply calling `g`:: - sage: M = matroids.CompleteGraphic(4); M.groundset() # needs sage.graphs + sage: # needs sage.graphs sage.groups + sage: M = matroids.CompleteGraphic(4); M.groundset() frozenset({0, 1, 2, 3, 4, 5}) - sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] # needs sage.graphs - sage: M = Matroid(bases=new_bases); M.groundset() # needs sage.graphs + sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] + sage: M = Matroid(bases=new_bases); M.groundset() frozenset({1, 2, 3, 4, 5, 6}) - sage: G = SymmetricGroup(6) # needs sage.groups - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) # needs sage.graphs sage.groups - sage: OSG.basis() # needs sage.graphs sage.groups + sage: G = SymmetricGroup(6) + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) + sage: OSG.basis() Finite family {0: B[0], 1: B[1]} - sage: [OSG.lift(b) for b in OSG.basis()] # needs sage.graphs sage.groups + sage: [OSG.lift(b) for b in OSG.basis()] [OS{}, OS{1} + OS{2} + OS{3} + OS{4} + OS{5} + OS{6}] - sage: (OSG.basis()[1])^2 # needs sage.graphs sage.groups + sage: (OSG.basis()[1])^2 0 - sage: 5 * OSG.basis()[1] # needs sage.graphs sage.groups + sage: 5 * OSG.basis()[1] 5*B[1] Next, we look at the same matroid but with an `S_3 \times S_3` action @@ -634,17 +635,18 @@ class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): We implement an `S_4` action on the vertices:: - sage: M = matroids.CompleteGraphic(4) # needs sage.graphs - sage: G = SymmetricGroup(4) # needs sage.groups - sage: edge_map = {i: M.groundset_to_edges([i])[0][:2] # needs sage.graphs + sage: # needs sage.graphs sage.groups + sage: M = matroids.CompleteGraphic(4) + sage: G = SymmetricGroup(4) + sage: edge_map = {i: M.groundset_to_edges([i])[0][:2] ....: for i in M.groundset()} - sage: inv_map = {v: k for k, v in edge_map.items()} # needs sage.graphs + sage: inv_map = {v: k for k, v in edge_map.items()} sage: def vert_action(g, x): ....: a, b = edge_map[x] ....: return inv_map[tuple(sorted([g(a+1)-1, g(b+1)-1]))] - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G, vert_action)) # needs sage.graphs sage.groups - sage: B = OSG.basis() # needs sage.graphs sage.groups - sage: [OSG.lift(b) for b in B] # needs sage.graphs sage.groups + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G, vert_action)) + sage: B = OSG.basis() + sage: [OSG.lift(b) for b in B] [OS{}, OS{0} + OS{1} + OS{2} + OS{3} + OS{4} + OS{5}] We use this to describe the Young subgroup `S_2 \times S_2` action:: @@ -684,12 +686,13 @@ def __init__(self, R, M, G, action_on_groundset=None, *args, **kwargs): EXAMPLES:: - sage: M = matroids.CompleteGraphic(4) # needs sage.graphs - sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] # needs sage.graphs - sage: M = Matroid(bases=new_bases) # needs sage.graphs - sage: G = SymmetricGroup(6) # needs sage.groups - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) # needs sage.graphs sage.groups - sage: TestSuite(OSG).run() # needs sage.graphs sage.groups + sage: # needs sage.graphs sage.groups + sage: M = matroids.CompleteGraphic(4) + sage: new_bases = [frozenset(i+1 for i in j) for j in M.bases()] + sage: M = Matroid(bases=new_bases) + sage: G = SymmetricGroup(6) + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=G) + sage: TestSuite(OSG).run() """ ordering = kwargs.pop('ordering', None) OS = OrlikSolomonAlgebra(R, M, ordering) @@ -772,17 +775,17 @@ def _basis_action(self, g, f): EXAMPLES:: - sage: # needs sage.graphs + sage: # needs sage.graphs sage.groups sage: M = matroids.CompleteGraphic(3) sage: M.groundset() frozenset({0, 1, 2}) - sage: G = SymmetricGroup(3) # needs sage.groups + sage: G = SymmetricGroup(3) sage: def on_groundset(g, x): ....: return g(x+1)-1 - sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G,on_groundset)) # needs sage.groups + sage: OSG = M.orlik_solomon_algebra(QQ, invariant=(G,on_groundset)) sage: act = lambda g: (OSG._basis_action(g,frozenset({0,1})), ....: OSG._basis_action(g,frozenset({0,2}))) - sage: [act(g) for g in G] # needs sage.groups + sage: [act(g) for g in G] [(OS{0, 1}, OS{0, 2}), (-OS{0, 2}, OS{0, 1} - OS{0, 2}), (-OS{0, 1} + OS{0, 2}, -OS{0, 1}), @@ -800,11 +803,10 @@ def _basis_action(self, g, f): sage: OS2 = M.orlik_solomon_algebra(QQ, range(2,-1,-1)) sage: OS2.subset_image(fset) OS{1, 2} - - sage: OSG2 = M.orlik_solomon_algebra(QQ, # needs sage.graphs sage.groups + sage: OSG2 = M.orlik_solomon_algebra(QQ, ....: invariant=(G,on_groundset), ....: ordering=range(2,-1,-1)) - sage: g = G.an_element(); g # needs sage.graphs sage.groups + sage: g = G.an_element(); g (2,3) This choice of ``g`` acting on this choice of ``fset`` reverses diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index ce764f0a258..993e94dc828 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -552,8 +552,8 @@ def __init__(self, p=2, basis='milnor', **kwds): sage: TestSuite(SteenrodAlgebra(profile=[4,3,2,2,1])).run() sage: TestSuite(SteenrodAlgebra(basis='adem')).run() sage: TestSuite(SteenrodAlgebra(basis='wall')).run() - sage: TestSuite(SteenrodAlgebra(basis='arnonc')).run() # long time - sage: TestSuite(SteenrodAlgebra(basis='woody')).run() # long time + sage: TestSuite(SteenrodAlgebra(basis='arnonc')).run() # long time + sage: TestSuite(SteenrodAlgebra(basis='woody')).run() # long time sage: A3 = SteenrodAlgebra(3) sage: A3.category() Category of supercocommutative super hopf algebras @@ -562,7 +562,7 @@ def __init__(self, p=2, basis='milnor', **kwds): sage: TestSuite(SteenrodAlgebra(basis='adem', p=3)).run() sage: TestSuite(SteenrodAlgebra(basis='pst_llex', p=7)).run() # long time sage: TestSuite(SteenrodAlgebra(basis='comm_deg', p=5)).run() # long time - sage: TestSuite(SteenrodAlgebra(p=2, generic=True)).run() # long time + sage: TestSuite(SteenrodAlgebra(p=2, generic=True)).run() # long time Two Steenrod algebras are equal iff their associated primes, bases, and profile functions (if present) are equal. Because @@ -753,8 +753,8 @@ def _repr_(self): mod 3 Steenrod algebra, milnor basis sage: SteenrodAlgebra(2, basis='adem') mod 2 Steenrod algebra, serre-cartan basis - sage: B = SteenrodAlgebra(2003) - sage: B._repr_() + sage: B = SteenrodAlgebra(2003) # needs sage.rings.finite_rings + sage: B._repr_() # needs sage.rings.finite_rings 'mod 2003 Steenrod algebra, milnor basis' sage: SteenrodAlgebra(generic=True, basis='adem') generic mod 2 Steenrod algebra, serre-cartan basis @@ -1393,14 +1393,14 @@ def coproduct(self, x, algorithm='milnor'): INPUT: - - ``x`` -- element of self + - ``x`` -- element of ``self`` - - ``algorithm`` -- ``None`` or a string, either 'milnor' or - 'serre-cartan' (or anything which will be converted to one + - ``algorithm`` -- ``None`` or a string, either ``'milnor'`` or + ``'serre-cartan'`` (or anything which will be converted to one of these by the function :func:`get_basis_name `. - If ``None``, default to 'serre-cartan' if current basis is - 'serre-cartan'; otherwise use 'milnor'. + If ``None``, default to ``'serre-cartan'`` if current basis is + ``'serre-cartan'``; otherwise use ``'milnor'``. This calls :meth:`coproduct_on_basis` on the summands of ``x`` and extends linearly. @@ -1440,12 +1440,12 @@ def antipode_on_basis(self, t): INPUT: - - ``t`` -- tuple, the index of a basis element of self + - ``t`` -- tuple, the index of a basis element of ``self`` OUTPUT: the antipode of the corresponding basis element, - as an element of self. + as an element of ``self``. ALGORITHM: according to a result of Milnor's, the antipode of `\text{Sq}(n)` is the sum of all of the Milnor basis elements @@ -1490,7 +1490,7 @@ def antipode_on_basis(self, t): TESTS:: sage: Milnor = SteenrodAlgebra() - sage: all(x.antipode().antipode() == x for x in Milnor.basis(11)) # long time + sage: all(x.antipode().antipode() == x for x in Milnor.basis(11)) # long time True sage: A5 = SteenrodAlgebra(p=5, basis='adem') sage: all(x.antipode().antipode() == x for x in A5.basis(25)) @@ -1531,7 +1531,7 @@ def counit_on_basis(self, t): INPUT: - - ``t`` -- tuple, the index of a basis element of self + - ``t`` -- tuple, the index of a basis element of ``self`` EXAMPLES:: @@ -2237,7 +2237,9 @@ def basis(self, d=None): This does not print in a very helpful way, unfortunately:: sage: A7.basis() - Lazy family (Term map from basis key family of mod 7 Steenrod algebra, milnor basis to mod 7 Steenrod algebra, milnor basis(i))_{i in basis key family of mod 7 Steenrod algebra, milnor basis} + Lazy family (Term map from basis key family of mod 7 Steenrod algebra, milnor basis + to mod 7 Steenrod algebra, milnor basis(i))_{i in basis key family + of mod 7 Steenrod algebra, milnor basis} sage: for (idx,a) in zip((1,..,9),A7.basis()): ....: print("{} {}".format(idx, a)) 1 1 @@ -2251,7 +2253,8 @@ def basis(self, d=None): 9 Q_0 P(2) sage: D = SteenrodAlgebra(p=3, profile=([1], [2,2])) sage: sorted(D.basis()) - [1, P(1), P(2), Q_0, Q_0 P(1), Q_0 P(2), Q_0 Q_1, Q_0 Q_1 P(1), Q_0 Q_1 P(2), Q_1, Q_1 P(1), Q_1 P(2)] + [1, P(1), P(2), Q_0, Q_0 P(1), Q_0 P(2), Q_0 Q_1, + Q_0 Q_1 P(1), Q_0 Q_1 P(2), Q_1, Q_1 P(1), Q_1 P(2)] """ from sage.sets.family import Family if d is None: @@ -2573,7 +2576,7 @@ def pst(self,s,t): def ngens(self): r""" - Number of generators of self. + Number of generators of ``self``. OUTPUT: number or Infinity @@ -2601,7 +2604,7 @@ def ngens(self): 3 sage: SteenrodAlgebra(profile=[3,2,1], basis='pst').ngens() 3 - sage: SteenrodAlgebra(p=3, profile=[[3,2,1], [2,2,2,2]]).ngens() # A(3) at p=3 + sage: SteenrodAlgebra(p=3, profile=[[3,2,1], [2,2,2,2]]).ngens() # A(3) at p=3 4 sage: SteenrodAlgebra(profile=[1,2,1,1]).ngens() 5 @@ -2647,7 +2650,8 @@ def gens(self): sage: A3 = SteenrodAlgebra(3, 'adem') sage: A3.gens() - Lazy family ((i))_{i in Non negative integers} + Lazy family ((i))_{i in Non negative integers} sage: A3.gens()[0] beta sage: A3.gens()[1] @@ -2666,7 +2670,9 @@ def gens(self): sage: SteenrodAlgebra(p=5, profile=[[2,1], [2,2,2]]).gens() Family (Q_0, P(1), P(5)) sage: SteenrodAlgebra(profile=lambda n: n).gens() - Lazy family ((i))_{i in Non negative integers} + Lazy family ((i))_{i in Non negative integers} You may also use ``algebra_generators`` instead of ``gens``:: @@ -2932,16 +2938,16 @@ def top_class(self): EXAMPLES:: - sage: SteenrodAlgebra(2,profile=(3,2,1)).top_class() + sage: SteenrodAlgebra(2, profile=(3,2,1)).top_class() Sq(7,3,1) - sage: SteenrodAlgebra(3,profile=((2,2,1),(1,2,2,2,2))).top_class() + sage: SteenrodAlgebra(3, profile=((2,2,1),(1,2,2,2,2))).top_class() Q_1 Q_2 Q_3 Q_4 P(8,8,2) TESTS:: - sage: SteenrodAlgebra(2,profile=(3,2,1),basis='pst').top_class() + sage: SteenrodAlgebra(2, profile=(3,2,1), basis='pst').top_class() P^0_1 P^0_2 P^1_1 P^0_3 P^1_2 P^2_1 - sage: SteenrodAlgebra(5,profile=((0,),(2,1,2,2))).top_class() + sage: SteenrodAlgebra(5, profile=((0,),(2,1,2,2))).top_class() Q_0 Q_2 Q_3 sage: SteenrodAlgebra(5).top_class() Traceback (most recent call last): @@ -2953,12 +2959,12 @@ def top_class(self): but far from optimal for the 'pst' basis. Occasionally, it also gives an awkward leading coefficient:: - sage: SteenrodAlgebra(3,profile=((2,1),(1,2,2)),basis='pst').top_class() + sage: SteenrodAlgebra(3, profile=((2,1),(1,2,2)), basis='pst').top_class() 2 Q_1 Q_2 (P^0_1)^2 (P^0_2)^2 (P^1_1)^2 TESTS:: - sage: A=SteenrodAlgebra(2,profile=(3,2,1),basis='pst') + sage: A=SteenrodAlgebra(2, profile=(3,2,1), basis='pst') sage: A.top_class().parent() is A True """ @@ -3080,7 +3086,7 @@ def is_generic(self): True sage: SteenrodAlgebra(2).is_generic() False - sage: SteenrodAlgebra(2,generic=True).is_generic() + sage: SteenrodAlgebra(2, generic=True).is_generic() True """ return self._generic @@ -4146,7 +4152,8 @@ def SteenrodAlgebra(p=2, basis='milnor', generic='auto', **kwds): sage: EA = SteenrodAlgebra(p=2,generic=True) ; EA generic mod 2 Steenrod algebra, milnor basis sage: EA[8] - Vector space spanned by (Q_0 Q_2, Q_0 Q_1 P(2), P(1,1), P(4)) over Finite Field of size 2 + Vector space spanned by (Q_0 Q_2, Q_0 Q_1 P(2), P(1,1), P(4)) + over Finite Field of size 2 TESTS: @@ -4201,9 +4208,11 @@ def AA(n=None, p=2): sage: A() mod 2 Steenrod algebra, milnor basis sage: A(2) - sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1] + sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, + profile function [3, 2, 1] sage: A(2, p=5) - sub-Hopf algebra of mod 5 Steenrod algebra, milnor basis, profile function ([2, 1], [2, 2, 2]) + sub-Hopf algebra of mod 5 Steenrod algebra, milnor basis, + profile function ([2, 1], [2, 2, 2]) """ if n is None: return SteenrodAlgebra(p=p) From 8f795cc2cc97053fb5578e70920d6304176bc570 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 3 Sep 2023 14:51:43 -0700 Subject: [PATCH 120/463] src/sage/algebras/lie_algebras/lie_algebra_element.pyx: # needs --- src/sage/algebras/lie_algebras/lie_algebra_element.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx index ed9680a0af5..f221fe6ab55 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx +++ b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: needs sage.combinat """ Lie Algebra Elements From 0b39a2b72da015f0b49b0c59c7d6c75582587736 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 3 Jun 2023 16:59:56 -0700 Subject: [PATCH 121/463] sage.combinat: Modularization fixes --- src/sage/combinat/species/generating_series.py | 7 ++++--- src/sage/combinat/species/misc.py | 12 +++++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index e7f7c8ee978..3d7e7e81341 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -53,11 +53,12 @@ from sage.rings.lazy_series_ring import LazyPowerSeriesRing, LazySymmetricFunctions from sage.rings.integer import Integer from sage.rings.rational_field import QQ -from sage.arith.misc import divisors +from sage.arith.misc import divisors, factorial from sage.combinat.partition import Partition, Partitions -from sage.combinat.sf.sf import SymmetricFunctions from sage.misc.cachefunc import cached_function -from sage.arith.misc import factorial +from sage.misc.lazy_import import lazy_import + +lazy_import('sage.combinat.sf.sf', 'SymmetricFunctions') class OrdinaryGeneratingSeries(LazyPowerSeries): diff --git a/src/sage/combinat/species/misc.py b/src/sage/combinat/species/misc.py index a516beb56ae..12a9b2c8f70 100644 --- a/src/sage/combinat/species/misc.py +++ b/src/sage/combinat/species/misc.py @@ -17,13 +17,15 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.groups.perm_gps.permgroup import PermutationGroup -from sage.groups.perm_gps.permgroup import PermutationGroup_generic -from sage.groups.perm_gps.constructor import PermutationGroupElement -from sage.groups.perm_gps.permgroup_named import SymmetricGroup -from sage.misc.misc_c import prod from functools import wraps +from sage.misc.misc_c import prod +from sage.misc.lazy_import import lazy_import + +lazy_import('sage.groups.perm_gps.permgroup', ['PermutationGroup', 'PermutationGroup_generic']) +lazy_import('sage.groups.perm_gps.constructor', 'PermutationGroupElement') +lazy_import('sage.groups.perm_gps.permgroup_named', 'SymmetricGroup') + def change_support(perm, support, change_perm=None): """ From c934842512612d049daf34902e30e4da365515fb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 8 Jun 2023 18:33:43 -0700 Subject: [PATCH 122/463] sage.combinat: More # optional --- .../combinat/species/generating_series.py | 56 +++++++++---------- src/sage/combinat/species/library.py | 12 ++-- .../combinat/species/recursive_species.py | 12 ++-- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 3d7e7e81341..88358916946 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -17,7 +17,7 @@ sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: p = SymmetricFunctions(QQ).power() # optional - sage.modules - sage: CIS = CycleIndexSeriesRing(QQ) + sage: CIS = CycleIndexSeriesRing(QQ) # optional - sage.modules sage: geo1 = CIS(lambda i: p([1])^i) # optional - sage.modules sage: geo2 = CIS(lambda i: p([2])^(i // 2) if is_even(i) else 0) # optional - sage.modules sage: s = geo1 * geo2 # optional - sage.modules @@ -294,7 +294,7 @@ def count(self, t): sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: p = SymmetricFunctions(QQ).power() # optional - sage.modules - sage: CIS = CycleIndexSeriesRing(QQ) + sage: CIS = CycleIndexSeriesRing(QQ) # optional - sage.modules sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) # optional - sage.modules sage: f.count([1]) # optional - sage.modules 1 @@ -314,7 +314,7 @@ def coefficient_cycle_type(self, t): sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: p = SymmetricFunctions(QQ).power() # optional - sage.modules - sage: CIS = CycleIndexSeriesRing(QQ) + sage: CIS = CycleIndexSeriesRing(QQ) # optional - sage.modules sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) # optional - sage.modules sage: f.coefficient_cycle_type([1]) # optional - sage.modules 1 @@ -334,9 +334,9 @@ def isotype_generating_series(self): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() - sage: f = cis.isotype_generating_series() - sage: f[:10] + sage: cis = P.cycle_index_series() # optional - sage.modules + sage: f = cis.isotype_generating_series() # optional - sage.modules + sage: f[:10] # optional - sage.modules [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ R = self.base_ring() @@ -352,8 +352,8 @@ def _ogs_gen(self, n, ao): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() - sage: [cis._ogs_gen(i, 0) for i in range(10)] + sage: cis = P.cycle_index_series() # optional - sage.modules + sage: [cis._ogs_gen(i, 0) for i in range(10)] # optional - sage.modules [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ if n < ao: @@ -367,9 +367,9 @@ def generating_series(self): EXAMPLES:: sage: P = species.PartitionSpecies() - sage: cis = P.cycle_index_series() - sage: f = cis.generating_series() - sage: f[:5] + sage: cis = P.cycle_index_series() # optional - sage.modules + sage: f = cis.generating_series() # optional - sage.modules + sage: f[:5] # optional - sage.modules [1, 1, 1, 5/6, 5/8] """ R = self.base_ring() @@ -385,8 +385,8 @@ def _egs_gen(self, n, ao): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() - sage: [cis._egs_gen(i, 0) for i in range(10)] + sage: cis = P.cycle_index_series() # optional - sage.modules + sage: [cis._egs_gen(i, 0) for i in range(10)] # optional - sage.modules [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ if n < ao: @@ -409,16 +409,16 @@ def derivative(self, n=1): The species `E` of sets satisfies the relationship `E' = E`:: - sage: E = species.SetSpecies().cycle_index_series() - sage: E[:8] == E.derivative()[:8] + sage: E = species.SetSpecies().cycle_index_series() # optional - sage.modules + sage: E[:8] == E.derivative()[:8] # optional - sage.modules True The species `C` of cyclic orderings and the species `L` of linear orderings satisfy the relationship `C' = L`:: - sage: C = species.CycleSpecies().cycle_index_series() - sage: L = species.LinearOrderSpecies().cycle_index_series() - sage: L[:8] == C.derivative()[:8] + sage: C = species.CycleSpecies().cycle_index_series() # optional - sage.modules + sage: L = species.LinearOrderSpecies().cycle_index_series() # optional - sage.modules + sage: L[:8] == C.derivative()[:8] # optional - sage.modules True """ return self.derivative_with_respect_to_p1(n=n) @@ -439,9 +439,9 @@ def pointing(self): The species `E^{\bullet}` of "pointed sets" satisfies `E^{\bullet} = X \cdot E`:: - sage: E = species.SetSpecies().cycle_index_series() - sage: X = species.SingletonSpecies().cycle_index_series() - sage: E.pointing()[:8] == (X*E)[:8] + sage: E = species.SetSpecies().cycle_index_series() # optional - sage.modules + sage: X = species.SingletonSpecies().cycle_index_series() # optional - sage.modules + sage: E.pointing()[:8] == (X*E)[:8] # optional - sage.modules True """ X = self.parent()([1], valuation=1) @@ -463,9 +463,9 @@ def exponential(self): Let `BT` be the species of binary trees, `BF` the species of binary forests, and `E` the species of sets. Then we have `BF = E \circ BT`:: - sage: BT = species.BinaryTreeSpecies().cycle_index_series() - sage: BF = species.BinaryForestSpecies().cycle_index_series() - sage: BT.exponential().isotype_generating_series()[:8] == BF.isotype_generating_series()[:8] + sage: BT = species.BinaryTreeSpecies().cycle_index_series() # optional - sage.modules + sage: BF = species.BinaryForestSpecies().cycle_index_series() # optional - sage.modules + sage: BT.exponential().isotype_generating_series()[:8] == BF.isotype_generating_series()[:8] # optional - sage.modules True """ base_ring = self.parent().base_ring().base_ring() @@ -490,10 +490,10 @@ def logarithm(self): Let `G` be the species of nonempty graphs and `CG` be the species of nonempty connected graphs. Then `G = E^{+} \circ CG`, so `CG = \Omega \circ G`:: - sage: G = species.SimpleGraphSpecies().cycle_index_series() - 1 + sage: G = species.SimpleGraphSpecies().cycle_index_series() - 1 # optional - sage.modules sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries - sage: CG = LogarithmCycleIndexSeries()(G) - sage: CG.isotype_generating_series()[0:8] + sage: CG = LogarithmCycleIndexSeries()(G) # optional - sage.modules + sage: CG.isotype_generating_series()[0:8] # optional - sage.modules [0, 1, 1, 2, 6, 21, 112, 853] """ base_ring = self.parent().base_ring().base_ring() @@ -546,7 +546,7 @@ class CycleIndexSeriesRing(LazySymmetricFunctions): We test to make sure that caching works:: - sage: R is CycleIndexSeriesRing(QQ) + sage: R is CycleIndexSeriesRing(QQ) # optional - sage.modules True """ Element = CycleIndexSeries diff --git a/src/sage/combinat/species/library.py b/src/sage/combinat/species/library.py index d4235273a9f..e9f7cf0c734 100644 --- a/src/sage/combinat/species/library.py +++ b/src/sage/combinat/species/library.py @@ -43,7 +43,7 @@ def SimpleGraphSpecies(): sage: S = species.SimpleGraphSpecies() sage: S.generating_series().counts(10) [1, 1, 2, 8, 64, 1024, 32768, 2097152, 268435456, 68719476736] - sage: S.cycle_index_series()[:5] + sage: S.cycle_index_series()[:5] # optional - sage.modules [p[], p[1], p[1, 1] + p[2], @@ -94,7 +94,7 @@ def BinaryTreeSpecies(): sage: B = species.BinaryTreeSpecies() sage: a = B.structures([1,2,3,4,5])[187]; a 2*((5*3)*(4*1)) - sage: a.automorphism_group() + sage: a.automorphism_group() # optional - sage.groups Permutation Group with generators [()] TESTS:: @@ -121,9 +121,9 @@ def BinaryForestSpecies(): sage: F = species.BinaryForestSpecies() sage: F.generating_series().counts(10) [1, 1, 3, 19, 193, 2721, 49171, 1084483, 28245729, 848456353] - sage: F.isotype_generating_series().counts(10) + sage: F.isotype_generating_series().counts(10) # optional - sage.modules [1, 1, 2, 4, 10, 26, 77, 235, 758, 2504] - sage: F.cycle_index_series()[:7] + sage: F.cycle_index_series()[:7] # optional - sage.modules [p[], p[1], 3/2*p[1, 1] + 1/2*p[2], @@ -134,8 +134,8 @@ def BinaryForestSpecies(): TESTS:: - sage: seq = F.isotype_generating_series().counts(10)[1:] - sage: oeis(seq)[0] # optional -- internet + sage: seq = F.isotype_generating_series().counts(10)[1:] # optional - sage.modules + sage: oeis(seq)[0] # optional -- internet # optional - sage.modules A052854: Number of forests of ordered trees on n total nodes. """ B = BinaryTreeSpecies() diff --git a/src/sage/combinat/species/recursive_species.py b/src/sage/combinat/species/recursive_species.py index 3cd073f9f9c..a87bb27866b 100644 --- a/src/sage/combinat/species/recursive_species.py +++ b/src/sage/combinat/species/recursive_species.py @@ -263,7 +263,7 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: F = CombinatorialSpecies() - sage: F.cycle_index_series() + sage: F.cycle_index_series() # optional - sage.modules Uninitialized Lazy Series """ if base_ring not in self._cycle_index_series: @@ -429,17 +429,17 @@ def _add_to_digraph(self, d): EXAMPLES:: - sage: d = DiGraph(multiedges=True) + sage: d = DiGraph(multiedges=True) # optional - sage.graphs sage: X = species.SingletonSpecies() sage: B = species.CombinatorialSpecies() sage: B.define(X+B*B) - sage: B._add_to_digraph(d); d + sage: B._add_to_digraph(d); d # optional - sage.graphs Multi-digraph on 4 vertices TESTS:: sage: C = species.CombinatorialSpecies() - sage: C._add_to_digraph(d) + sage: C._add_to_digraph(d) # optional - sage.graphs Traceback (most recent call last): ... NotImplementedError @@ -461,7 +461,7 @@ def _equation(self, var_mapping): EXAMPLES:: sage: C = species.CombinatorialSpecies() - sage: C.algebraic_equation_system() + sage: C.algebraic_equation_system() # optional - sage.graphs Traceback (most recent call last): ... NotImplementedError @@ -469,7 +469,7 @@ def _equation(self, var_mapping): :: sage: B = species.BinaryTreeSpecies() - sage: B.algebraic_equation_system() + sage: B.algebraic_equation_system() # optional - sage.graphs [-node3^2 + node1, -node1 + node3 + (-z)] """ try: From 36ee07472a1a2246e77f4d3b71b54280ca74dc00 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 9 Jun 2023 00:55:41 -0700 Subject: [PATCH 123/463] More # optional --- .../combinat/species/generating_series.py | 4 +- src/sage/combinat/species/library.py | 10 ++-- .../combinat/species/permutation_species.py | 6 +-- src/sage/combinat/species/product_species.py | 30 ++++++------ src/sage/combinat/species/set_species.py | 10 ++-- src/sage/combinat/species/species.py | 48 ++++++++++--------- src/sage/combinat/species/subset_species.py | 14 +++--- src/sage/combinat/species/sum_species.py | 4 +- 8 files changed, 65 insertions(+), 61 deletions(-) diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 88358916946..24830b17bcd 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -669,8 +669,8 @@ def LogarithmCycleIndexSeries(R=QQ): (that is, that composition with `E^{+}` in both directions yields the multiplicative identity `X`):: - sage: Eplus = sage.combinat.species.set_species.SetSpecies(min=1).cycle_index_series() - sage: LogarithmCycleIndexSeries()(Eplus)[0:4] # optional - sage.modules + sage: Eplus = sage.combinat.species.set_species.SetSpecies(min=1).cycle_index_series() # optional - sage.modules + sage: LogarithmCycleIndexSeries()(Eplus)[0:4] # optional - sage.modules [0, p[1], 0, 0] """ CIS = CycleIndexSeriesRing(R) diff --git a/src/sage/combinat/species/library.py b/src/sage/combinat/species/library.py index e9f7cf0c734..3e3025d87f6 100644 --- a/src/sage/combinat/species/library.py +++ b/src/sage/combinat/species/library.py @@ -49,19 +49,19 @@ def SimpleGraphSpecies(): p[1, 1] + p[2], 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] - sage: S.isotype_generating_series()[:6] + sage: S.isotype_generating_series()[:6] # optional - sage.modules [1, 1, 2, 4, 11, 34] TESTS:: - sage: seq = S.isotype_generating_series().counts(6)[1:] - sage: oeis(seq)[0] # optional -- internet + sage: seq = S.isotype_generating_series().counts(6)[1:] # optional - sage.modules + sage: oeis(seq)[0] # optional -- internet # optional - sage.modules A000088: Number of graphs on n unlabeled nodes. :: - sage: seq = S.generating_series().counts(10)[1:] - sage: oeis(seq)[0] # optional -- internet + sage: seq = S.generating_series().counts(10)[1:] # optional - sage.modules + sage: oeis(seq)[0] # optional -- internet # optional - sage.modules A006125: a(n) = 2^(n*(n-1)/2). """ E = SetSpecies() diff --git a/src/sage/combinat/species/permutation_species.py b/src/sage/combinat/species/permutation_species.py index 64534c9e8bb..470a766a2c4 100644 --- a/src/sage/combinat/species/permutation_species.py +++ b/src/sage/combinat/species/permutation_species.py @@ -225,8 +225,8 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: g = P.cycle_index_series() - sage: g[0:5] + sage: g = P.cycle_index_series() # optional - sage.modules + sage: g[0:5] # optional - sage.modules [p[], p[1], p[1, 1] + p[2], @@ -244,7 +244,7 @@ def _cis_gen(self, base_ring, m, n): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: [P._cis_gen(QQ, 2, i) for i in range(10)] + sage: [P._cis_gen(QQ, 2, i) for i in range(10)] # optional - sage.modules [p[], 0, p[2], 0, p[2, 2], 0, p[2, 2, 2], 0, p[2, 2, 2, 2], 0] """ from sage.combinat.sf.sf import SymmetricFunctions diff --git a/src/sage/combinat/species/product_species.py b/src/sage/combinat/species/product_species.py index 0989d2a8f8c..a3bcb3f4bb4 100644 --- a/src/sage/combinat/species/product_species.py +++ b/src/sage/combinat/species/product_species.py @@ -58,12 +58,12 @@ def transport(self, perm): """ EXAMPLES:: - sage: p = PermutationGroupElement((2,3)) - sage: S = species.SetSpecies() - sage: F = S * S - sage: a = F.structures(['a','b','c'])[4]; a + sage: p = PermutationGroupElement((2,3)) # optional - sage.groups + sage: S = species.SetSpecies() # optional - sage.groups + sage: F = S * S # optional - sage.groups + sage: a = F.structures(['a','b','c'])[4]; a # optional - sage.groups {'a', 'b'}*{'c'} - sage: a.transport(p) + sage: a.transport(p) # optional - sage.groups {'a', 'c'}*{'b'} """ left, right = self._list @@ -151,17 +151,17 @@ def automorphism_group(self): """ EXAMPLES:: - sage: p = PermutationGroupElement((2,3)) - sage: S = species.SetSpecies() - sage: F = S * S - sage: a = F.structures([1,2,3,4])[1]; a + sage: p = PermutationGroupElement((2,3)) # optional - sage.groups + sage: S = species.SetSpecies() # optional - sage.groups + sage: F = S * S # optional - sage.groups + sage: a = F.structures([1,2,3,4])[1]; a # optional - sage.groups {1}*{2, 3, 4} - sage: a.automorphism_group() + sage: a.automorphism_group() # optional - sage.groups Permutation Group with generators [(2,3), (2,3,4)] :: - sage: [a.transport(g) for g in a.automorphism_group()] + sage: [a.transport(g) for g in a.automorphism_group()] # optional - sage.groups [{1}*{2, 3, 4}, {1}*{2, 3, 4}, {1}*{2, 3, 4}, @@ -171,9 +171,9 @@ def automorphism_group(self): :: - sage: a = F.structures([1,2,3,4])[8]; a + sage: a = F.structures([1,2,3,4])[8]; a # optional - sage.groups {2, 3}*{1, 4} - sage: [a.transport(g) for g in a.automorphism_group()] + sage: [a.transport(g) for g in a.automorphism_group()] # optional - sage.groups [{2, 3}*{1, 4}, {2, 3}*{1, 4}, {2, 3}*{1, 4}, {2, 3}*{1, 4}] """ from sage.groups.perm_gps.constructor import PermutationGroupElement @@ -355,7 +355,7 @@ def _cis(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P * P - sage: F.cycle_index_series()[0:5] + sage: F.cycle_index_series()[0:5] # optional - sage.modules [p[], 2*p[1], 3*p[1, 1] + 2*p[2], @@ -409,7 +409,7 @@ def _equation(self, var_mapping): sage: X = species.SingletonSpecies() sage: S = X * X - sage: S.algebraic_equation_system() + sage: S.algebraic_equation_system() # optional - sage.graphs [node0 + (-z^2)] """ from sage.misc.misc_c import prod diff --git a/src/sage/combinat/species/set_species.py b/src/sage/combinat/species/set_species.py index daa7d7e5835..31020f8eb5e 100644 --- a/src/sage/combinat/species/set_species.py +++ b/src/sage/combinat/species/set_species.py @@ -57,8 +57,8 @@ def transport(self, perm): sage: F = species.SetSpecies() sage: a = F.structures(["a", "b", "c"]).random_element(); a {'a', 'b', 'c'} - sage: p = PermutationGroupElement((1,2)) - sage: a.transport(p) + sage: p = PermutationGroupElement((1,2)) # optional - sage.groups + sage: a.transport(p) # optional - sage.groups {'a', 'b', 'c'} """ return self @@ -74,7 +74,7 @@ def automorphism_group(self): sage: F = species.SetSpecies() sage: a = F.structures(["a", "b", "c"]).random_element(); a {'a', 'b', 'c'} - sage: a.automorphism_group() + sage: a.automorphism_group() # optional - sage.groups Symmetric group of order 3! as a permutation group """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -170,8 +170,8 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: S = species.SetSpecies() - sage: g = S.cycle_index_series() - sage: g[0:5] + sage: g = S.cycle_index_series() # optional - sage.modules + sage: g[0:5] # optional - sage.modules [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index 4cd3403ae61..9c3365f81b7 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -24,12 +24,12 @@ sage: L = species.LinearOrderSpecies(min=1) sage: T = species.CombinatorialSpecies(min=1) sage: T.define(leaf + internal_node*L(T)) - sage: T.isotype_generating_series()[0:6] + sage: T.isotype_generating_series()[0:6] # optional - sage.modules [0, 1, q, q^2 + q, q^3 + 3*q^2 + q, q^4 + 6*q^3 + 6*q^2 + q] Consider the following:: - sage: T.isotype_generating_series().coefficient(4) + sage: T.isotype_generating_series().coefficient(4) # optional - sage.modules q^3 + 3*q^2 + q This means that, among the trees on `4` nodes, one has a @@ -335,7 +335,7 @@ def functorial_composition(self, g): sage: WP = species.SubsetSpecies() sage: P2 = E2*E sage: G = WP.functorial_composition(P2) - sage: G.isotype_generating_series()[0:5] + sage: G.isotype_generating_series()[0:5] # optional - sage.modules [1, 1, 2, 4, 11] """ from .functorial_composition_species import FunctorialCompositionSpecies @@ -448,7 +448,7 @@ def __pow__(self, n): sage: X^1 is X True sage: A = X^32 - sage: A.digraph() + sage: A.digraph() # optional - sage.graphs Multi-digraph on 6 vertices TESTS:: @@ -643,8 +643,8 @@ def cycle_index_series(self, base_ring=None): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: g = P.cycle_index_series() - sage: g[0:4] + sage: g = P.cycle_index_series() # optional - sage.modules + sage: g[0:4] # optional - sage.modules [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] """ return self._get_series(CycleIndexSeriesRing, "cis", base_ring) @@ -710,19 +710,19 @@ def digraph(self): sage: X = species.SingletonSpecies() sage: B = species.CombinatorialSpecies() sage: B.define(X+B*B) - sage: g = B.digraph(); g + sage: g = B.digraph(); g # optional - sage.graphs Multi-digraph on 4 vertices - sage: sorted(g, key=str) + sage: sorted(g, key=str) # optional - sage.graphs [Combinatorial species, Product of (Combinatorial species) and (Combinatorial species), Singleton species, Sum of (Singleton species) and (Product of (Combinatorial species) and (Combinatorial species))] - sage: d = {sp: i for i, sp in enumerate(g)} - sage: g.relabel(d) - sage: g.canonical_label().edges(sort=True) + sage: d = {sp: i for i, sp in enumerate(g)} # optional - sage.graphs + sage: g.relabel(d) # optional - sage.graphs + sage: g.canonical_label().edges(sort=True) # optional - sage.graphs [(0, 3, None), (2, 0, None), (2, 0, None), (3, 1, None), (3, 2, None)] """ from sage.graphs.digraph import DiGraph @@ -739,13 +739,13 @@ def _add_to_digraph(self, d): EXAMPLES:: - sage: d = DiGraph(multiedges=True) - sage: X = species.SingletonSpecies() - sage: X._add_to_digraph(d); d + sage: d = DiGraph(multiedges=True) # optional - sage.graphs + sage: X = species.SingletonSpecies() # optional - sage.graphs + sage: X._add_to_digraph(d); d # optional - sage.graphs Multi-digraph on 1 vertex - sage: (X+X)._add_to_digraph(d); d + sage: (X+X)._add_to_digraph(d); d # optional - sage.graphs Multi-digraph on 2 vertices - sage: d.edges(sort=True) + sage: d.edges(sort=True) # optional - sage.graphs [(Sum of (Singleton species) and (Singleton species), Singleton species, None), (Sum of (Singleton species) and (Singleton species), Singleton species, None)] """ @@ -770,21 +770,25 @@ def algebraic_equation_system(self): EXAMPLES:: sage: B = species.BinaryTreeSpecies() - sage: B.algebraic_equation_system() + sage: B.algebraic_equation_system() # optional - sage.graphs [-node3^2 + node1, -node1 + node3 + (-z)] :: - sage: sorted(B.digraph().vertex_iterator(), key=str) + sage: sorted(B.digraph().vertex_iterator(), key=str) # optional - sage.graphs [Combinatorial species with min=1, - Product of (Combinatorial species with min=1) and (Combinatorial species with min=1), + Product of (Combinatorial species with min=1) + and (Combinatorial species with min=1), Singleton species, - Sum of (Singleton species) and (Product of (Combinatorial species with min=1) and (Combinatorial species with min=1))] + Sum of (Singleton species) + and (Product of (Combinatorial species with min=1) + and (Combinatorial species with min=1))] :: - sage: B.algebraic_equation_system()[0].parent() - Multivariate Polynomial Ring in node0, node1, node2, node3 over Fraction Field of Univariate Polynomial Ring in z over Rational Field + sage: B.algebraic_equation_system()[0].parent() # optional - sage.graphs + Multivariate Polynomial Ring in node0, node1, node2, node3 over + Fraction Field of Univariate Polynomial Ring in z over Rational Field """ d = self.digraph() diff --git a/src/sage/combinat/species/subset_species.py b/src/sage/combinat/species/subset_species.py index 81156e5183d..2d3b9f8dcb6 100644 --- a/src/sage/combinat/species/subset_species.py +++ b/src/sage/combinat/species/subset_species.py @@ -74,11 +74,11 @@ def transport(self, perm): sage: F = species.SubsetSpecies() sage: a = F.structures(["a", "b", "c"])[5]; a {'a', 'c'} - sage: p = PermutationGroupElement((1,2)) - sage: a.transport(p) + sage: p = PermutationGroupElement((1,2)) # optional - sage.groups + sage: a.transport(p) # optional - sage.groups {'b', 'c'} - sage: p = PermutationGroupElement((1,3)) - sage: a.transport(p) + sage: p = PermutationGroupElement((1,3)) # optional - sage.groups + sage: a.transport(p) # optional - sage.groups {'a', 'c'} """ l = sorted([perm(i) for i in self._list]) @@ -94,12 +94,12 @@ def automorphism_group(self): sage: F = species.SubsetSpecies() sage: a = F.structures([1,2,3,4])[6]; a {1, 3} - sage: a.automorphism_group() + sage: a.automorphism_group() # optional - sage.groups Permutation Group with generators [(2,4), (1,3)] :: - sage: [a.transport(g) for g in a.automorphism_group()] + sage: [a.transport(g) for g in a.automorphism_group()] # optional - sage.groups [{1, 3}, {1, 3}, {1, 3}, {1, 3}] """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -224,7 +224,7 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: S = species.SubsetSpecies() - sage: S.cycle_index_series()[0:5] + sage: S.cycle_index_series()[0:5] # optional - sage.modules [p[], 2*p[1], 2*p[1, 1] + p[2], diff --git a/src/sage/combinat/species/sum_species.py b/src/sage/combinat/species/sum_species.py index fe45a352943..ae877a64314 100644 --- a/src/sage/combinat/species/sum_species.py +++ b/src/sage/combinat/species/sum_species.py @@ -171,7 +171,7 @@ def _cis(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P + P - sage: F.cycle_index_series()[:5] + sage: F.cycle_index_series()[:5] # optional - sage.modules [2*p[], 2*p[1], 2*p[1, 1] + 2*p[2], @@ -214,7 +214,7 @@ def _equation(self, var_mapping): sage: X = species.SingletonSpecies() sage: S = X + X - sage: S.algebraic_equation_system() + sage: S.algebraic_equation_system() # optional - sage.graphs [node1 + (-2*z)] """ return sum(var_mapping[operand] for operand in self._state_info) From 6cb95c1d98c65fb692540ad7edba1955630b6871 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 17:49:30 -0700 Subject: [PATCH 124/463] More # optional --- .../species/characteristic_species.py | 27 +++++----- .../combinat/species/composition_species.py | 52 +++++++++---------- src/sage/combinat/species/cycle_species.py | 14 ++--- src/sage/combinat/species/empty_species.py | 6 +-- .../species/functorial_composition_species.py | 8 +-- .../combinat/species/linear_order_species.py | 6 +-- .../combinat/species/partition_species.py | 2 +- src/sage/combinat/species/product_species.py | 4 +- src/sage/combinat/species/species.py | 4 +- src/sage/combinat/species/structure.py | 6 +-- src/sage/combinat/species/sum_species.py | 6 +-- 11 files changed, 67 insertions(+), 68 deletions(-) diff --git a/src/sage/combinat/species/characteristic_species.py b/src/sage/combinat/species/characteristic_species.py index e529dc97bd1..ca88dd7e91b 100644 --- a/src/sage/combinat/species/characteristic_species.py +++ b/src/sage/combinat/species/characteristic_species.py @@ -60,16 +60,15 @@ def canonical_label(self): def transport(self, perm): """ - Returns the transport of this structure along the permutation - perm. + Return the transport of this structure along the permutation ``perm``. EXAMPLES:: sage: F = species.CharacteristicSpecies(3) sage: a = F.structures(["a", "b", "c"]).random_element(); a {'a', 'b', 'c'} - sage: p = PermutationGroupElement((1,2)) - sage: a.transport(p) + sage: p = PermutationGroupElement((1,2)) # optional - sage.groups + sage: a.transport(p) # optional - sage.groups {'a', 'b', 'c'} """ return self @@ -85,7 +84,7 @@ def automorphism_group(self): sage: F = species.CharacteristicSpecies(3) sage: a = F.structures(["a", "b", "c"]).random_element(); a {'a', 'b', 'c'} - sage: a.automorphism_group() + sage: a.automorphism_group() # optional - sage.groups Symmetric group of order 3! as a permutation group """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -111,7 +110,7 @@ def __init__(self, n, min=None, max=None, weight=None): [0, 1, 0, 0] sage: X.isotype_generating_series()[0:4] [0, 1, 0, 0] - sage: X.cycle_index_series()[0:4] + sage: X.cycle_index_series()[0:4] # optional - sage.modules [0, p[1], 0, 0] sage: F = species.CharacteristicSpecies(3) @@ -204,7 +203,7 @@ def _cis_term(self, base_ring): EXAMPLES:: sage: F = species.CharacteristicSpecies(2) - sage: g = F.cycle_index_series() + sage: g = F.cycle_index_series() # optional - sage.modules sage: g[0:5] [0, 0, 1/2*p[1, 1] + 1/2*p[2], 0, 0] """ @@ -220,11 +219,11 @@ def _equation(self, var_mapping): EXAMPLES:: sage: C = species.CharacteristicSpecies(2) - sage: Qz = QQ['z'] - sage: R. = Qz[] - sage: var_mapping = {'z':Qz.gen(), 'node0':R.gen()} - sage: C._equation(var_mapping) - z^2 + sage: Qz = QQ['z'] + sage: R. = Qz[] + sage: var_mapping = {'z':Qz.gen(), 'node0':R.gen()} + sage: C._equation(var_mapping) + z^2 """ return var_mapping['z']**(self._n) @@ -252,7 +251,7 @@ def __init__(self, min=None, max=None, weight=None): [1, 0, 0, 0] sage: X.isotype_generating_series()[0:4] [1, 0, 0, 0] - sage: X.cycle_index_series()[0:4] + sage: X.cycle_index_series()[0:4] # optional - sage.modules [p[], 0, 0, 0] TESTS:: @@ -296,7 +295,7 @@ def __init__(self, min=None, max=None, weight=None): [0, 1, 0, 0] sage: X.isotype_generating_series()[0:4] [0, 1, 0, 0] - sage: X.cycle_index_series()[0:4] + sage: X.cycle_index_series()[0:4] # optional - sage.modules [0, p[1], 0, 0] TESTS:: diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index c96f3161ba5..1937ead0811 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -28,8 +28,8 @@ def __init__(self, parent, labels, pi, f, gs): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: a = L.structures(['a','b','c']).random_element() - sage: a == loads(dumps(a)) + sage: a = L.structures(['a','b','c']).random_element() # optional - sage.libs.flint + sage: a == loads(dumps(a)) # optional - sage.libs.flint True """ self._partition = pi @@ -41,7 +41,7 @@ def __repr__(self): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.structures(['a','b','c'])[0] + sage: L.structures(['a','b','c'])[0] # optional - sage.libs.flint F-structure: {{'a', 'b', 'c'}}; G-structures: (('a', 'b', 'c'),) """ f, gs = self._list @@ -51,13 +51,13 @@ def transport(self, perm): """ EXAMPLES:: - sage: p = PermutationGroupElement((2,3)) + sage: p = PermutationGroupElement((2,3)) # optional - sage.groups sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: S = L.structures(['a','b','c']).list() - sage: a = S[2]; a + sage: S = L.structures(['a','b','c']).list() # optional - sage.libs.flint + sage: a = S[2]; a # optional - sage.libs.flint F-structure: {{'a', 'c'}, {'b'}}; G-structures: (('a', 'c'), ('b')) - sage: a.transport(p) + sage: a.transport(p) # optional - sage.groups sage.libs.flint F-structure: {{'a', 'b'}, {'c'}}; G-structures: (('a', 'c'), ('b')) """ f, gs = self._list @@ -83,10 +83,10 @@ def change_labels(self, labels): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: S = L.structures(['a','b','c']).list() - sage: a = S[2]; a + sage: S = L.structures(['a','b','c']).list() # optional - sage.libs.flint + sage: a = S[2]; a # optional - sage.libs.flint F-structure: {{'a', 'c'}, {'b'}}; G-structures: (('a', 'c'), ('b')) - sage: a.change_labels([1,2,3]) + sage: a.change_labels([1,2,3]) # optional - sage.libs.flint F-structure: {{1, 3}, {2}}; G-structures: [(1, 3), (2)] """ f, gs = self._list @@ -116,7 +116,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) sage: c = L.generating_series()[:3] - sage: L._check() #False due to isomorphism types not being implemented + sage: L._check() #False due to isomorphism types not being implemented # optional - sage.libs.flint False sage: L == loads(dumps(L)) True @@ -135,7 +135,7 @@ def _structures(self, structure_class, labels): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.structures(['a','b','c']).list() + sage: L.structures(['a','b','c']).list() # optional - sage.libs.flint [F-structure: {{'a', 'b', 'c'}}; G-structures: (('a', 'b', 'c'),), F-structure: {{'a', 'b', 'c'}}; G-structures: (('a', 'c', 'b'),), F-structure: {{'a', 'c'}, {'b'}}; G-structures: (('a', 'c'), ('b')), @@ -145,21 +145,21 @@ def _structures(self, structure_class, labels): TESTS:: - sage: a = _[2] - sage: f, gs = a._list - sage: f + sage: a = _[2] # optional - sage.libs.flint + sage: f, gs = a._list # optional - sage.libs.flint + sage: f # optional - sage.libs.flint {{'a', 'c'}, {'b'}} - sage: f.parent() + sage: f.parent() # optional - sage.libs.flint Set species - sage: f._list + sage: f._list # optional - sage.libs.flint [1, 2] - sage: f._labels + sage: f._labels # optional - sage.libs.flint [{'a', 'c'}, {'b'}] - sage: [g.parent() for g in gs] + sage: [g.parent() for g in gs] # optional - sage.libs.flint [Cyclic permutation species, Cyclic permutation species] - sage: [g._labels for g in gs] + sage: [g._labels for g in gs] # optional - sage.libs.flint [['a', 'c'], ['b']] - sage: [g._list for g in gs] + sage: [g._list for g in gs] # optional - sage.libs.flint [[1, 2], [1]] """ from itertools import product @@ -180,7 +180,7 @@ def _isotypes(self, structure_class, labels): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.isotypes(['a','b','c']).list() + sage: L.isotypes(['a','b','c']).list() # optional - sage.modules Traceback (most recent call last): ... NotImplementedError @@ -204,7 +204,7 @@ def _itgs(self, series_ring, base_ring): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.isotype_generating_series()[:10] + sage: L.isotype_generating_series()[:10] # optional - sage.modules [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ cis = self.cycle_index_series(base_ring) @@ -216,7 +216,7 @@ def _cis(self, series_ring, base_ring): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.cycle_index_series()[:5] + sage: L.cycle_index_series()[:5] # optional - sage.modules [p[], p[1], p[1, 1] + p[2], @@ -233,7 +233,7 @@ def _cis(self, series_ring, base_ring): sage: E = species.SetSpecies() sage: C = species.CycleSpecies(weight=t) sage: S = E(C) - sage: S.isotype_generating_series()[:5] #indirect + sage: S.isotype_generating_series()[:5] #indirect # optional - sage.modules [1, t, t^2 + t, t^3 + t^2 + t, t^4 + t^3 + 2*t^2 + t] We do the same thing with set partitions weighted by the number of @@ -245,7 +245,7 @@ def _cis(self, series_ring, base_ring): sage: E = species.SetSpecies() sage: E_t = species.SetSpecies(min=1,weight=t) sage: Par = E(E_t) - sage: Par.isotype_generating_series()[:5] + sage: Par.isotype_generating_series()[:5] # optional - sage.modules [1, t, t^2 + t, t^3 + t^2 + t, t^4 + t^3 + 2*t^2 + t] """ f_cis = self._F.cycle_index_series(base_ring) diff --git a/src/sage/combinat/species/cycle_species.py b/src/sage/combinat/species/cycle_species.py index ed442e75ba9..e1faab86c91 100644 --- a/src/sage/combinat/species/cycle_species.py +++ b/src/sage/combinat/species/cycle_species.py @@ -51,7 +51,7 @@ def permutation_group_element(self): sage: F = species.CycleSpecies() sage: a = F.structures(["a", "b", "c"])[0]; a ('a', 'b', 'c') - sage: a.permutation_group_element() + sage: a.permutation_group_element() # optional - sage.groups (1,2,3) """ from sage.groups.perm_gps.constructor import PermutationGroupElement @@ -67,8 +67,8 @@ def transport(self, perm): sage: F = species.CycleSpecies() sage: a = F.structures(["a", "b", "c"])[0]; a ('a', 'b', 'c') - sage: p = PermutationGroupElement((1,2)) - sage: a.transport(p) + sage: p = PermutationGroupElement((1,2)) # optional - sage.groups + sage: a.transport(p) # optional - sage.groups ('a', 'c', 'b') """ p = self.permutation_group_element() @@ -88,12 +88,12 @@ def automorphism_group(self): sage: P = species.CycleSpecies() sage: a = P.structures([1, 2, 3, 4])[0]; a (1, 2, 3, 4) - sage: a.automorphism_group() + sage: a.automorphism_group() # optional - sage.groups Permutation Group with generators [(1,2,3,4)] :: - sage: [a.transport(perm) for perm in a.automorphism_group()] + sage: [a.transport(perm) for perm in a.automorphism_group()] # optional - sage.groups [(1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 4)] """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -255,8 +255,8 @@ def _cis_callable(self, base_ring, n): EXAMPLES:: sage: P = species.CycleSpecies() - sage: cis = P.cycle_index_series() - sage: cis[0:7] + sage: cis = P.cycle_index_series() # optional - sage.modules + sage: cis[0:7] # optional - sage.modules [0, p[1], 1/2*p[1, 1] + 1/2*p[2], diff --git a/src/sage/combinat/species/empty_species.py b/src/sage/combinat/species/empty_species.py index e66019360ac..d3ddcad0cf3 100644 --- a/src/sage/combinat/species/empty_species.py +++ b/src/sage/combinat/species/empty_species.py @@ -38,7 +38,7 @@ class EmptySpecies(GenericCombinatorialSpecies, UniqueRepresentation): [0, 0, 0, 0] sage: X.isotype_generating_series()[0:4] [0, 0, 0, 0] - sage: X.cycle_index_series()[0:4] + sage: X.cycle_index_series()[0:4] # optional - sage.modules [0, 0, 0, 0] The empty species is the zero of the semi-ring of species. @@ -55,7 +55,7 @@ class EmptySpecies(GenericCombinatorialSpecies, UniqueRepresentation): sage: (X.isotype_generating_series()[0:4] == ....: S.isotype_generating_series()[0:4]) True - sage: (X.cycle_index_series()[0:4] == + sage: (X.cycle_index_series()[0:4] == # optional - sage.modules ....: S.cycle_index_series()[0:4]) True @@ -69,7 +69,7 @@ class EmptySpecies(GenericCombinatorialSpecies, UniqueRepresentation): [0, 0, 0, 0] sage: Y.isotype_generating_series()[0:4] [0, 0, 0, 0] - sage: Y.cycle_index_series()[0:4] + sage: Y.cycle_index_series()[0:4] # optional - sage.modules [0, 0, 0, 0] TESTS:: diff --git a/src/sage/combinat/species/functorial_composition_species.py b/src/sage/combinat/species/functorial_composition_species.py index 118e924d426..99da72c1d9c 100644 --- a/src/sage/combinat/species/functorial_composition_species.py +++ b/src/sage/combinat/species/functorial_composition_species.py @@ -35,7 +35,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: WP = species.SubsetSpecies() sage: P2 = E2*E sage: G = WP.functorial_composition(P2) - sage: G.isotype_generating_series()[0:5] + sage: G.isotype_generating_series()[0:5] # optional - sage.modules [1, 1, 2, 4, 11] sage: G = species.SimpleGraphSpecies() @@ -81,7 +81,7 @@ def _isotypes(self, structure_class, s): EXAMPLES:: sage: G = species.SimpleGraphSpecies() - sage: G.isotypes([1,2,3]).list() + sage: G.isotypes([1,2,3]).list() # optional - sage.modules Traceback (most recent call last): ... NotImplementedError @@ -103,7 +103,7 @@ def _itgs(self, series_ring, base_ring): EXAMPLES:: sage: G = species.SimpleGraphSpecies() - sage: G.isotype_generating_series()[0:5] + sage: G.isotype_generating_series()[0:5] # optional - sage.modules [1, 1, 2, 4, 11] """ return self.cycle_index_series(base_ring).isotype_generating_series() @@ -113,7 +113,7 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: G = species.SimpleGraphSpecies() - sage: G.cycle_index_series()[0:5] + sage: G.cycle_index_series()[0:5] # optional - sage.modules [p[], p[1], p[1, 1] + p[2], diff --git a/src/sage/combinat/species/linear_order_species.py b/src/sage/combinat/species/linear_order_species.py index 6203442ec8f..6b64178bdbc 100644 --- a/src/sage/combinat/species/linear_order_species.py +++ b/src/sage/combinat/species/linear_order_species.py @@ -43,7 +43,7 @@ def transport(self, perm): sage: F = species.LinearOrderSpecies() sage: a = F.structures(["a", "b", "c"])[0]; a ['a', 'b', 'c'] - sage: p = PermutationGroupElement((1,2)) + sage: p = PermutationGroupElement((1,2)) # optional - sage.groups sage: a.transport(p) ['b', 'a', 'c'] """ @@ -60,7 +60,7 @@ def automorphism_group(self): sage: F = species.LinearOrderSpecies() sage: a = F.structures(["a", "b", "c"])[0]; a ['a', 'b', 'c'] - sage: a.automorphism_group() + sage: a.automorphism_group() # optional - sage.groups Symmetric group of order 1! as a permutation group """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -155,7 +155,7 @@ def _cis_callable(self, base_ring, n): EXAMPLES:: sage: L = species.LinearOrderSpecies() - sage: g = L.cycle_index_series() + sage: g = L.cycle_index_series() # optional - sage.modules sage: g[0:5] [p[], p[1], p[1, 1], p[1, 1, 1], p[1, 1, 1, 1]] """ diff --git a/src/sage/combinat/species/partition_species.py b/src/sage/combinat/species/partition_species.py index f9044db7c73..f3038ad6ba2 100644 --- a/src/sage/combinat/species/partition_species.py +++ b/src/sage/combinat/species/partition_species.py @@ -272,7 +272,7 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: P = species.PartitionSpecies() - sage: g = P.cycle_index_series() + sage: g = P.cycle_index_series() # optional - sage.modules sage: g[0:5] [p[], p[1], diff --git a/src/sage/combinat/species/product_species.py b/src/sage/combinat/species/product_species.py index a3bcb3f4bb4..b1ce34596fd 100644 --- a/src/sage/combinat/species/product_species.py +++ b/src/sage/combinat/species/product_species.py @@ -215,7 +215,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): Product of (Permutation species) and (Permutation species) sage: F == loads(dumps(F)) True - sage: F._check() + sage: F._check() # optional - sage.libs.flint True TESTS:: @@ -340,7 +340,7 @@ def _itgs(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P * P - sage: F.isotype_generating_series()[0:5] + sage: F.isotype_generating_series()[0:5] # optional - sage.libs.flint [1, 2, 5, 10, 20] """ res = (self.left_factor().isotype_generating_series(base_ring) * diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index 9c3365f81b7..871a62009af 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -401,7 +401,7 @@ def _check(self, n=5): EXAMPLES:: sage: P = species.PartitionSpecies() - sage: P._check() + sage: P._check() # optional - sage.libs.flint True """ st = self.structures(range(n)) @@ -622,7 +622,7 @@ def isotype_generating_series(self, base_ring=None): sage: P = species.PermutationSpecies() sage: g = P.isotype_generating_series() - sage: g[0:4] + sage: g[0:4] # optional - sage.libs.flint [1, 1, 2, 3] sage: g.counts(4) [1, 1, 2, 3] diff --git a/src/sage/combinat/species/structure.py b/src/sage/combinat/species/structure.py index a4de6349c6d..d0ca053d632 100644 --- a/src/sage/combinat/species/structure.py +++ b/src/sage/combinat/species/structure.py @@ -277,9 +277,9 @@ def transport(self, perm): EXAMPLES:: sage: P = species.PartitionSpecies() - sage: s = (P+P).structures([1,2,3])[1]; s + sage: s = (P+P).structures([1,2,3])[1]; s # optional - sage.libs.flint {{1, 3}, {2}} - sage: s.transport(PermutationGroupElement((2,3))) + sage: s.transport(PermutationGroupElement((2,3))) # optional - sage.groups sage.libs.flint {{1, 2}, {3}} """ return self.__class__(self._parent, self._s.transport(perm), **self._options) @@ -289,7 +289,7 @@ def canonical_label(self): EXAMPLES:: sage: P = species.PartitionSpecies() - sage: s = (P+P).structures([1,2,3])[1]; s + sage: s = (P+P).structures([1,2,3])[1]; s # optional - sage.libs.flint {{1, 3}, {2}} sage: s.canonical_label() {{1, 2}, {3}} diff --git a/src/sage/combinat/species/sum_species.py b/src/sage/combinat/species/sum_species.py index ae877a64314..ac2e05943b3 100644 --- a/src/sage/combinat/species/sum_species.py +++ b/src/sage/combinat/species/sum_species.py @@ -38,7 +38,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: P = species.PermutationSpecies() sage: F = P + P - sage: F._check() + sage: F._check() # optional - sage.libs.flint True sage: F == loads(dumps(F)) True @@ -126,7 +126,7 @@ def _isotypes(self, structure_class, labels): sage: P = species.PermutationSpecies() sage: F = P + P - sage: F.isotypes([1,2]).list() + sage: F.isotypes([1,2]).list() # optional - sage.libs.flint [[2, 1], [1, 2], [2, 1], [1, 2]] """ for res in self._F.isotypes(labels): @@ -157,7 +157,7 @@ def _itgs(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P + P - sage: F.isotype_generating_series()[:5] + sage: F.isotype_generating_series()[:5] # optional - sage.libs.flint [2, 2, 4, 6, 10] """ return (self.left_summand().isotype_generating_series(base_ring) + From 7f205583588bc67af46c37e3ced399083af786c2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 23:46:00 -0700 Subject: [PATCH 125/463] sage.combinat: More # optional --- src/sage/combinat/species/characteristic_species.py | 2 +- src/sage/combinat/species/functorial_composition_species.py | 2 +- src/sage/combinat/species/linear_order_species.py | 4 ++-- src/sage/combinat/species/species.py | 6 +++--- src/sage/combinat/species/structure.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/combinat/species/characteristic_species.py b/src/sage/combinat/species/characteristic_species.py index ca88dd7e91b..c3e55239335 100644 --- a/src/sage/combinat/species/characteristic_species.py +++ b/src/sage/combinat/species/characteristic_species.py @@ -204,7 +204,7 @@ def _cis_term(self, base_ring): sage: F = species.CharacteristicSpecies(2) sage: g = F.cycle_index_series() # optional - sage.modules - sage: g[0:5] + sage: g[0:5] # optional - sage.modules [0, 0, 1/2*p[1, 1] + 1/2*p[2], 0, 0] """ cis = SetSpecies(weight=self._weight).cycle_index_series(base_ring) diff --git a/src/sage/combinat/species/functorial_composition_species.py b/src/sage/combinat/species/functorial_composition_species.py index 99da72c1d9c..68a07967671 100644 --- a/src/sage/combinat/species/functorial_composition_species.py +++ b/src/sage/combinat/species/functorial_composition_species.py @@ -44,7 +44,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: G == loads(dumps(G)) True - sage: G._check() #False due to isomorphism types not being implemented + sage: G._check() # False due to isomorphism types not being implemented # optional - sage.modules False """ self._F = F diff --git a/src/sage/combinat/species/linear_order_species.py b/src/sage/combinat/species/linear_order_species.py index 6b64178bdbc..a889c8ab6c2 100644 --- a/src/sage/combinat/species/linear_order_species.py +++ b/src/sage/combinat/species/linear_order_species.py @@ -44,7 +44,7 @@ def transport(self, perm): sage: a = F.structures(["a", "b", "c"])[0]; a ['a', 'b', 'c'] sage: p = PermutationGroupElement((1,2)) # optional - sage.groups - sage: a.transport(p) + sage: a.transport(p) # optional - sage.groups ['b', 'a', 'c'] """ return LinearOrderSpeciesStructure(self.parent(), self._labels, [perm(i) for i in self._list]) @@ -156,7 +156,7 @@ def _cis_callable(self, base_ring, n): sage: L = species.LinearOrderSpecies() sage: g = L.cycle_index_series() # optional - sage.modules - sage: g[0:5] + sage: g[0:5] # optional - sage.modules [p[], p[1], p[1, 1], p[1, 1, 1], p[1, 1, 1, 1]] """ from sage.combinat.sf.sf import SymmetricFunctions diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index 871a62009af..0efdb963981 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -624,11 +624,11 @@ def isotype_generating_series(self, base_ring=None): sage: g = P.isotype_generating_series() sage: g[0:4] # optional - sage.libs.flint [1, 1, 2, 3] - sage: g.counts(4) + sage: g.counts(4) # optional - sage.libs.flint [1, 1, 2, 3] - sage: P.isotypes([1,2,3]).list() + sage: P.isotypes([1,2,3]).list() # optional - sage.libs.flint [[2, 3, 1], [2, 1, 3], [1, 2, 3]] - sage: len(_) + sage: len(_) # optional - sage.libs.flint 3 """ return self._get_series(OrdinaryGeneratingSeriesRing, "itgs", base_ring) diff --git a/src/sage/combinat/species/structure.py b/src/sage/combinat/species/structure.py index d0ca053d632..6dc1fc2ea15 100644 --- a/src/sage/combinat/species/structure.py +++ b/src/sage/combinat/species/structure.py @@ -291,7 +291,7 @@ def canonical_label(self): sage: P = species.PartitionSpecies() sage: s = (P+P).structures([1,2,3])[1]; s # optional - sage.libs.flint {{1, 3}, {2}} - sage: s.canonical_label() + sage: s.canonical_label() # optional - sage.libs.flint {{1, 2}, {3}} """ return self.__class__(self._parent, self._s.canonical_label(), **self._options) From 7cdec9bc1bfcbd13c8594a5a1615575d1a0b8fd2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 12 Jul 2023 17:59:24 -0700 Subject: [PATCH 126/463] ./sage -fixdoctests --distribution sagemath-categories --only-tags src/sage/combinat --- .../species/characteristic_species.py | 16 +-- .../combinat/species/composition_species.py | 52 ++++---- src/sage/combinat/species/cycle_species.py | 14 +-- src/sage/combinat/species/empty_species.py | 6 +- .../species/functorial_composition_species.py | 10 +- .../combinat/species/generating_series.py | 116 +++++++++--------- src/sage/combinat/species/library.py | 22 ++-- .../combinat/species/linear_order_species.py | 10 +- .../combinat/species/partition_species.py | 2 +- .../combinat/species/permutation_species.py | 6 +- src/sage/combinat/species/product_species.py | 34 ++--- .../combinat/species/recursive_species.py | 12 +- src/sage/combinat/species/set_species.py | 10 +- src/sage/combinat/species/species.py | 48 ++++---- src/sage/combinat/species/structure.py | 12 +- src/sage/combinat/species/subset_species.py | 14 +-- src/sage/combinat/species/sum_species.py | 10 +- 17 files changed, 197 insertions(+), 197 deletions(-) diff --git a/src/sage/combinat/species/characteristic_species.py b/src/sage/combinat/species/characteristic_species.py index c3e55239335..37ce75abe28 100644 --- a/src/sage/combinat/species/characteristic_species.py +++ b/src/sage/combinat/species/characteristic_species.py @@ -67,8 +67,8 @@ def transport(self, perm): sage: F = species.CharacteristicSpecies(3) sage: a = F.structures(["a", "b", "c"]).random_element(); a {'a', 'b', 'c'} - sage: p = PermutationGroupElement((1,2)) # optional - sage.groups - sage: a.transport(p) # optional - sage.groups + sage: p = PermutationGroupElement((1,2)) # needs sage.groups + sage: a.transport(p) # needs sage.groups {'a', 'b', 'c'} """ return self @@ -84,7 +84,7 @@ def automorphism_group(self): sage: F = species.CharacteristicSpecies(3) sage: a = F.structures(["a", "b", "c"]).random_element(); a {'a', 'b', 'c'} - sage: a.automorphism_group() # optional - sage.groups + sage: a.automorphism_group() # needs sage.groups Symmetric group of order 3! as a permutation group """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -110,7 +110,7 @@ def __init__(self, n, min=None, max=None, weight=None): [0, 1, 0, 0] sage: X.isotype_generating_series()[0:4] [0, 1, 0, 0] - sage: X.cycle_index_series()[0:4] # optional - sage.modules + sage: X.cycle_index_series()[0:4] # needs sage.modules [0, p[1], 0, 0] sage: F = species.CharacteristicSpecies(3) @@ -203,8 +203,8 @@ def _cis_term(self, base_ring): EXAMPLES:: sage: F = species.CharacteristicSpecies(2) - sage: g = F.cycle_index_series() # optional - sage.modules - sage: g[0:5] # optional - sage.modules + sage: g = F.cycle_index_series() # needs sage.modules + sage: g[0:5] # needs sage.modules [0, 0, 1/2*p[1, 1] + 1/2*p[2], 0, 0] """ cis = SetSpecies(weight=self._weight).cycle_index_series(base_ring) @@ -251,7 +251,7 @@ def __init__(self, min=None, max=None, weight=None): [1, 0, 0, 0] sage: X.isotype_generating_series()[0:4] [1, 0, 0, 0] - sage: X.cycle_index_series()[0:4] # optional - sage.modules + sage: X.cycle_index_series()[0:4] # needs sage.modules [p[], 0, 0, 0] TESTS:: @@ -295,7 +295,7 @@ def __init__(self, min=None, max=None, weight=None): [0, 1, 0, 0] sage: X.isotype_generating_series()[0:4] [0, 1, 0, 0] - sage: X.cycle_index_series()[0:4] # optional - sage.modules + sage: X.cycle_index_series()[0:4] # needs sage.modules [0, p[1], 0, 0] TESTS:: diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index 1937ead0811..a60b0cbed89 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -28,8 +28,8 @@ def __init__(self, parent, labels, pi, f, gs): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: a = L.structures(['a','b','c']).random_element() # optional - sage.libs.flint - sage: a == loads(dumps(a)) # optional - sage.libs.flint + sage: a = L.structures(['a','b','c']).random_element() # needs sage.libs.flint + sage: a == loads(dumps(a)) # needs sage.libs.flint True """ self._partition = pi @@ -41,7 +41,7 @@ def __repr__(self): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.structures(['a','b','c'])[0] # optional - sage.libs.flint + sage: L.structures(['a','b','c'])[0] # needs sage.libs.flint F-structure: {{'a', 'b', 'c'}}; G-structures: (('a', 'b', 'c'),) """ f, gs = self._list @@ -51,13 +51,13 @@ def transport(self, perm): """ EXAMPLES:: - sage: p = PermutationGroupElement((2,3)) # optional - sage.groups + sage: p = PermutationGroupElement((2,3)) # needs sage.groups sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: S = L.structures(['a','b','c']).list() # optional - sage.libs.flint - sage: a = S[2]; a # optional - sage.libs.flint + sage: S = L.structures(['a','b','c']).list() # needs sage.libs.flint + sage: a = S[2]; a # needs sage.libs.flint F-structure: {{'a', 'c'}, {'b'}}; G-structures: (('a', 'c'), ('b')) - sage: a.transport(p) # optional - sage.groups sage.libs.flint + sage: a.transport(p) # needs sage.groups sage.libs.flint F-structure: {{'a', 'b'}, {'c'}}; G-structures: (('a', 'c'), ('b')) """ f, gs = self._list @@ -83,10 +83,10 @@ def change_labels(self, labels): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: S = L.structures(['a','b','c']).list() # optional - sage.libs.flint - sage: a = S[2]; a # optional - sage.libs.flint + sage: S = L.structures(['a','b','c']).list() # needs sage.libs.flint + sage: a = S[2]; a # needs sage.libs.flint F-structure: {{'a', 'c'}, {'b'}}; G-structures: (('a', 'c'), ('b')) - sage: a.change_labels([1,2,3]) # optional - sage.libs.flint + sage: a.change_labels([1,2,3]) # needs sage.libs.flint F-structure: {{1, 3}, {2}}; G-structures: [(1, 3), (2)] """ f, gs = self._list @@ -116,7 +116,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) sage: c = L.generating_series()[:3] - sage: L._check() #False due to isomorphism types not being implemented # optional - sage.libs.flint + sage: L._check() #False due to isomorphism types not being implemented # needs sage.libs.flint False sage: L == loads(dumps(L)) True @@ -135,7 +135,7 @@ def _structures(self, structure_class, labels): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.structures(['a','b','c']).list() # optional - sage.libs.flint + sage: L.structures(['a','b','c']).list() # needs sage.libs.flint [F-structure: {{'a', 'b', 'c'}}; G-structures: (('a', 'b', 'c'),), F-structure: {{'a', 'b', 'c'}}; G-structures: (('a', 'c', 'b'),), F-structure: {{'a', 'c'}, {'b'}}; G-structures: (('a', 'c'), ('b')), @@ -145,21 +145,21 @@ def _structures(self, structure_class, labels): TESTS:: - sage: a = _[2] # optional - sage.libs.flint - sage: f, gs = a._list # optional - sage.libs.flint - sage: f # optional - sage.libs.flint + sage: a = _[2] # needs sage.libs.flint + sage: f, gs = a._list # needs sage.libs.flint + sage: f # needs sage.libs.flint {{'a', 'c'}, {'b'}} - sage: f.parent() # optional - sage.libs.flint + sage: f.parent() # needs sage.libs.flint Set species - sage: f._list # optional - sage.libs.flint + sage: f._list # needs sage.libs.flint [1, 2] - sage: f._labels # optional - sage.libs.flint + sage: f._labels # needs sage.libs.flint [{'a', 'c'}, {'b'}] - sage: [g.parent() for g in gs] # optional - sage.libs.flint + sage: [g.parent() for g in gs] # needs sage.libs.flint [Cyclic permutation species, Cyclic permutation species] - sage: [g._labels for g in gs] # optional - sage.libs.flint + sage: [g._labels for g in gs] # needs sage.libs.flint [['a', 'c'], ['b']] - sage: [g._list for g in gs] # optional - sage.libs.flint + sage: [g._list for g in gs] # needs sage.libs.flint [[1, 2], [1]] """ from itertools import product @@ -180,7 +180,7 @@ def _isotypes(self, structure_class, labels): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.isotypes(['a','b','c']).list() # optional - sage.modules + sage: L.isotypes(['a','b','c']).list() # needs sage.modules Traceback (most recent call last): ... NotImplementedError @@ -204,7 +204,7 @@ def _itgs(self, series_ring, base_ring): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.isotype_generating_series()[:10] # optional - sage.modules + sage: L.isotype_generating_series()[:10] # needs sage.modules [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ cis = self.cycle_index_series(base_ring) @@ -216,7 +216,7 @@ def _cis(self, series_ring, base_ring): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.cycle_index_series()[:5] # optional - sage.modules + sage: L.cycle_index_series()[:5] # needs sage.modules [p[], p[1], p[1, 1] + p[2], @@ -233,7 +233,7 @@ def _cis(self, series_ring, base_ring): sage: E = species.SetSpecies() sage: C = species.CycleSpecies(weight=t) sage: S = E(C) - sage: S.isotype_generating_series()[:5] #indirect # optional - sage.modules + sage: S.isotype_generating_series()[:5] #indirect # needs sage.modules [1, t, t^2 + t, t^3 + t^2 + t, t^4 + t^3 + 2*t^2 + t] We do the same thing with set partitions weighted by the number of @@ -245,7 +245,7 @@ def _cis(self, series_ring, base_ring): sage: E = species.SetSpecies() sage: E_t = species.SetSpecies(min=1,weight=t) sage: Par = E(E_t) - sage: Par.isotype_generating_series()[:5] # optional - sage.modules + sage: Par.isotype_generating_series()[:5] # needs sage.modules [1, t, t^2 + t, t^3 + t^2 + t, t^4 + t^3 + 2*t^2 + t] """ f_cis = self._F.cycle_index_series(base_ring) diff --git a/src/sage/combinat/species/cycle_species.py b/src/sage/combinat/species/cycle_species.py index e1faab86c91..c808f6a0db1 100644 --- a/src/sage/combinat/species/cycle_species.py +++ b/src/sage/combinat/species/cycle_species.py @@ -51,7 +51,7 @@ def permutation_group_element(self): sage: F = species.CycleSpecies() sage: a = F.structures(["a", "b", "c"])[0]; a ('a', 'b', 'c') - sage: a.permutation_group_element() # optional - sage.groups + sage: a.permutation_group_element() # needs sage.groups (1,2,3) """ from sage.groups.perm_gps.constructor import PermutationGroupElement @@ -67,8 +67,8 @@ def transport(self, perm): sage: F = species.CycleSpecies() sage: a = F.structures(["a", "b", "c"])[0]; a ('a', 'b', 'c') - sage: p = PermutationGroupElement((1,2)) # optional - sage.groups - sage: a.transport(p) # optional - sage.groups + sage: p = PermutationGroupElement((1,2)) # needs sage.groups + sage: a.transport(p) # needs sage.groups ('a', 'c', 'b') """ p = self.permutation_group_element() @@ -88,12 +88,12 @@ def automorphism_group(self): sage: P = species.CycleSpecies() sage: a = P.structures([1, 2, 3, 4])[0]; a (1, 2, 3, 4) - sage: a.automorphism_group() # optional - sage.groups + sage: a.automorphism_group() # needs sage.groups Permutation Group with generators [(1,2,3,4)] :: - sage: [a.transport(perm) for perm in a.automorphism_group()] # optional - sage.groups + sage: [a.transport(perm) for perm in a.automorphism_group()] # needs sage.groups [(1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 4)] """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -255,8 +255,8 @@ def _cis_callable(self, base_ring, n): EXAMPLES:: sage: P = species.CycleSpecies() - sage: cis = P.cycle_index_series() # optional - sage.modules - sage: cis[0:7] # optional - sage.modules + sage: cis = P.cycle_index_series() # needs sage.modules + sage: cis[0:7] # needs sage.modules [0, p[1], 1/2*p[1, 1] + 1/2*p[2], diff --git a/src/sage/combinat/species/empty_species.py b/src/sage/combinat/species/empty_species.py index d3ddcad0cf3..5c4762cb34d 100644 --- a/src/sage/combinat/species/empty_species.py +++ b/src/sage/combinat/species/empty_species.py @@ -38,7 +38,7 @@ class EmptySpecies(GenericCombinatorialSpecies, UniqueRepresentation): [0, 0, 0, 0] sage: X.isotype_generating_series()[0:4] [0, 0, 0, 0] - sage: X.cycle_index_series()[0:4] # optional - sage.modules + sage: X.cycle_index_series()[0:4] # needs sage.modules [0, 0, 0, 0] The empty species is the zero of the semi-ring of species. @@ -55,7 +55,7 @@ class EmptySpecies(GenericCombinatorialSpecies, UniqueRepresentation): sage: (X.isotype_generating_series()[0:4] == ....: S.isotype_generating_series()[0:4]) True - sage: (X.cycle_index_series()[0:4] == # optional - sage.modules + sage: (X.cycle_index_series()[0:4] == # needs sage.modules ....: S.cycle_index_series()[0:4]) True @@ -69,7 +69,7 @@ class EmptySpecies(GenericCombinatorialSpecies, UniqueRepresentation): [0, 0, 0, 0] sage: Y.isotype_generating_series()[0:4] [0, 0, 0, 0] - sage: Y.cycle_index_series()[0:4] # optional - sage.modules + sage: Y.cycle_index_series()[0:4] # needs sage.modules [0, 0, 0, 0] TESTS:: diff --git a/src/sage/combinat/species/functorial_composition_species.py b/src/sage/combinat/species/functorial_composition_species.py index 68a07967671..b327492a54a 100644 --- a/src/sage/combinat/species/functorial_composition_species.py +++ b/src/sage/combinat/species/functorial_composition_species.py @@ -35,7 +35,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: WP = species.SubsetSpecies() sage: P2 = E2*E sage: G = WP.functorial_composition(P2) - sage: G.isotype_generating_series()[0:5] # optional - sage.modules + sage: G.isotype_generating_series()[0:5] # needs sage.modules [1, 1, 2, 4, 11] sage: G = species.SimpleGraphSpecies() @@ -44,7 +44,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: G == loads(dumps(G)) True - sage: G._check() # False due to isomorphism types not being implemented # optional - sage.modules + sage: G._check() # False due to isomorphism types not being implemented # needs sage.modules False """ self._F = F @@ -81,7 +81,7 @@ def _isotypes(self, structure_class, s): EXAMPLES:: sage: G = species.SimpleGraphSpecies() - sage: G.isotypes([1,2,3]).list() # optional - sage.modules + sage: G.isotypes([1,2,3]).list() # needs sage.modules Traceback (most recent call last): ... NotImplementedError @@ -103,7 +103,7 @@ def _itgs(self, series_ring, base_ring): EXAMPLES:: sage: G = species.SimpleGraphSpecies() - sage: G.isotype_generating_series()[0:5] # optional - sage.modules + sage: G.isotype_generating_series()[0:5] # needs sage.modules [1, 1, 2, 4, 11] """ return self.cycle_index_series(base_ring).isotype_generating_series() @@ -113,7 +113,7 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: G = species.SimpleGraphSpecies() - sage: G.cycle_index_series()[0:5] # optional - sage.modules + sage: G.cycle_index_series()[0:5] # needs sage.modules [p[], p[1], p[1, 1] + p[2], diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 24830b17bcd..9c0515bbead 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -16,18 +16,18 @@ TESTS:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() # optional - sage.modules - sage: CIS = CycleIndexSeriesRing(QQ) # optional - sage.modules - sage: geo1 = CIS(lambda i: p([1])^i) # optional - sage.modules - sage: geo2 = CIS(lambda i: p([2])^(i // 2) if is_even(i) else 0) # optional - sage.modules - sage: s = geo1 * geo2 # optional - sage.modules - sage: s[0] # optional - sage.modules + sage: p = SymmetricFunctions(QQ).power() # needs sage.modules + sage: CIS = CycleIndexSeriesRing(QQ) # needs sage.modules + sage: geo1 = CIS(lambda i: p([1])^i) # needs sage.modules + sage: geo2 = CIS(lambda i: p([2])^(i // 2) if is_even(i) else 0) # needs sage.modules + sage: s = geo1 * geo2 # needs sage.modules + sage: s[0] # needs sage.modules p[] - sage: s[1] # optional - sage.modules + sage: s[1] # needs sage.modules p[1] - sage: s[2] # optional - sage.modules + sage: s[2] # needs sage.modules p[1, 1] + p[2] - sage: s[3] # optional - sage.modules + sage: s[3] # needs sage.modules p[1, 1, 1] + p[2, 1] REFERENCES: @@ -293,14 +293,14 @@ def count(self, t): EXAMPLES:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() # optional - sage.modules - sage: CIS = CycleIndexSeriesRing(QQ) # optional - sage.modules - sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) # optional - sage.modules - sage: f.count([1]) # optional - sage.modules + sage: p = SymmetricFunctions(QQ).power() # needs sage.modules + sage: CIS = CycleIndexSeriesRing(QQ) # needs sage.modules + sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) # needs sage.modules + sage: f.count([1]) # needs sage.modules 1 - sage: f.count([1,1]) # optional - sage.modules + sage: f.count([1,1]) # needs sage.modules 4 - sage: f.count([2,1]) # optional - sage.modules + sage: f.count([2,1]) # needs sage.modules 6 """ t = Partition(t) @@ -313,14 +313,14 @@ def coefficient_cycle_type(self, t): EXAMPLES:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() # optional - sage.modules - sage: CIS = CycleIndexSeriesRing(QQ) # optional - sage.modules - sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) # optional - sage.modules - sage: f.coefficient_cycle_type([1]) # optional - sage.modules + sage: p = SymmetricFunctions(QQ).power() # needs sage.modules + sage: CIS = CycleIndexSeriesRing(QQ) # needs sage.modules + sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) # needs sage.modules + sage: f.coefficient_cycle_type([1]) # needs sage.modules 1 - sage: f.coefficient_cycle_type([1,1]) # optional - sage.modules + sage: f.coefficient_cycle_type([1,1]) # needs sage.modules 2 - sage: f.coefficient_cycle_type([2,1]) # optional - sage.modules + sage: f.coefficient_cycle_type([2,1]) # needs sage.modules 3 """ t = Partition(t) @@ -334,9 +334,9 @@ def isotype_generating_series(self): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() # optional - sage.modules - sage: f = cis.isotype_generating_series() # optional - sage.modules - sage: f[:10] # optional - sage.modules + sage: cis = P.cycle_index_series() # needs sage.modules + sage: f = cis.isotype_generating_series() # needs sage.modules + sage: f[:10] # needs sage.modules [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ R = self.base_ring() @@ -352,8 +352,8 @@ def _ogs_gen(self, n, ao): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() # optional - sage.modules - sage: [cis._ogs_gen(i, 0) for i in range(10)] # optional - sage.modules + sage: cis = P.cycle_index_series() # needs sage.modules + sage: [cis._ogs_gen(i, 0) for i in range(10)] # needs sage.modules [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ if n < ao: @@ -367,9 +367,9 @@ def generating_series(self): EXAMPLES:: sage: P = species.PartitionSpecies() - sage: cis = P.cycle_index_series() # optional - sage.modules - sage: f = cis.generating_series() # optional - sage.modules - sage: f[:5] # optional - sage.modules + sage: cis = P.cycle_index_series() # needs sage.modules + sage: f = cis.generating_series() # needs sage.modules + sage: f[:5] # needs sage.modules [1, 1, 1, 5/6, 5/8] """ R = self.base_ring() @@ -385,8 +385,8 @@ def _egs_gen(self, n, ao): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() # optional - sage.modules - sage: [cis._egs_gen(i, 0) for i in range(10)] # optional - sage.modules + sage: cis = P.cycle_index_series() # needs sage.modules + sage: [cis._egs_gen(i, 0) for i in range(10)] # needs sage.modules [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ if n < ao: @@ -409,16 +409,16 @@ def derivative(self, n=1): The species `E` of sets satisfies the relationship `E' = E`:: - sage: E = species.SetSpecies().cycle_index_series() # optional - sage.modules - sage: E[:8] == E.derivative()[:8] # optional - sage.modules + sage: E = species.SetSpecies().cycle_index_series() # needs sage.modules + sage: E[:8] == E.derivative()[:8] # needs sage.modules True The species `C` of cyclic orderings and the species `L` of linear orderings satisfy the relationship `C' = L`:: - sage: C = species.CycleSpecies().cycle_index_series() # optional - sage.modules - sage: L = species.LinearOrderSpecies().cycle_index_series() # optional - sage.modules - sage: L[:8] == C.derivative()[:8] # optional - sage.modules + sage: C = species.CycleSpecies().cycle_index_series() # needs sage.modules + sage: L = species.LinearOrderSpecies().cycle_index_series() # needs sage.modules + sage: L[:8] == C.derivative()[:8] # needs sage.modules True """ return self.derivative_with_respect_to_p1(n=n) @@ -439,9 +439,9 @@ def pointing(self): The species `E^{\bullet}` of "pointed sets" satisfies `E^{\bullet} = X \cdot E`:: - sage: E = species.SetSpecies().cycle_index_series() # optional - sage.modules - sage: X = species.SingletonSpecies().cycle_index_series() # optional - sage.modules - sage: E.pointing()[:8] == (X*E)[:8] # optional - sage.modules + sage: E = species.SetSpecies().cycle_index_series() # needs sage.modules + sage: X = species.SingletonSpecies().cycle_index_series() # needs sage.modules + sage: E.pointing()[:8] == (X*E)[:8] # needs sage.modules True """ X = self.parent()([1], valuation=1) @@ -463,9 +463,9 @@ def exponential(self): Let `BT` be the species of binary trees, `BF` the species of binary forests, and `E` the species of sets. Then we have `BF = E \circ BT`:: - sage: BT = species.BinaryTreeSpecies().cycle_index_series() # optional - sage.modules - sage: BF = species.BinaryForestSpecies().cycle_index_series() # optional - sage.modules - sage: BT.exponential().isotype_generating_series()[:8] == BF.isotype_generating_series()[:8] # optional - sage.modules + sage: BT = species.BinaryTreeSpecies().cycle_index_series() # needs sage.modules + sage: BF = species.BinaryForestSpecies().cycle_index_series() # needs sage.modules + sage: BT.exponential().isotype_generating_series()[:8] == BF.isotype_generating_series()[:8] # needs sage.modules True """ base_ring = self.parent().base_ring().base_ring() @@ -490,10 +490,10 @@ def logarithm(self): Let `G` be the species of nonempty graphs and `CG` be the species of nonempty connected graphs. Then `G = E^{+} \circ CG`, so `CG = \Omega \circ G`:: - sage: G = species.SimpleGraphSpecies().cycle_index_series() - 1 # optional - sage.modules + sage: G = species.SimpleGraphSpecies().cycle_index_series() - 1 # needs sage.modules sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries - sage: CG = LogarithmCycleIndexSeries()(G) # optional - sage.modules - sage: CG.isotype_generating_series()[0:8] # optional - sage.modules + sage: CG = LogarithmCycleIndexSeries()(G) # needs sage.modules + sage: CG.isotype_generating_series()[0:8] # needs sage.modules [0, 1, 1, 2, 6, 21, 112, 853] """ base_ring = self.parent().base_ring().base_ring() @@ -536,17 +536,17 @@ class CycleIndexSeriesRing(LazySymmetricFunctions): EXAMPLES:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: R = CycleIndexSeriesRing(QQ); R # optional - sage.modules + sage: R = CycleIndexSeriesRing(QQ); R # needs sage.modules Cycle Index Series Ring over Rational Field - sage: p = SymmetricFunctions(QQ).p() # optional - sage.modules - sage: R(lambda n: p[n]) # optional - sage.modules + sage: p = SymmetricFunctions(QQ).p() # needs sage.modules + sage: R(lambda n: p[n]) # needs sage.modules p[] + p[1] + p[2] + p[3] + p[4] + p[5] + p[6] + O^7 TESTS: We test to make sure that caching works:: - sage: R is CycleIndexSeriesRing(QQ) # optional - sage.modules + sage: R is CycleIndexSeriesRing(QQ) # needs sage.modules True """ Element = CycleIndexSeries @@ -559,8 +559,8 @@ def __init__(self, base_ring, sparse=True): sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: CycleIndexSeriesRing.options.halting_precision(12) - sage: R = CycleIndexSeriesRing(QQ) # optional - sage.modules - sage: TestSuite(R).run() # optional - sage.modules + sage: R = CycleIndexSeriesRing(QQ) # needs sage.modules + sage: TestSuite(R).run() # needs sage.modules sage: CycleIndexSeriesRing.options._reset() # reset options """ @@ -574,7 +574,7 @@ def _repr_(self): EXAMPLES:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: CycleIndexSeriesRing(QQ) # optional - sage.modules + sage: CycleIndexSeriesRing(QQ) # needs sage.modules Cycle Index Series Ring over Rational Field """ return "Cycle Index Series Ring over %s" % self.base_ring() @@ -589,7 +589,7 @@ def _exp_term(n, R=QQ): EXAMPLES:: sage: from sage.combinat.species.generating_series import _exp_term - sage: [_exp_term(i) for i in range(4)] # optional - sage.modules + sage: [_exp_term(i) for i in range(4)] # needs sage.modules [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] """ p = SymmetricFunctions(R).power() @@ -611,7 +611,7 @@ def ExponentialCycleIndexSeries(R=QQ): EXAMPLES:: sage: from sage.combinat.species.generating_series import ExponentialCycleIndexSeries - sage: ExponentialCycleIndexSeries()[:5] # optional - sage.modules + sage: ExponentialCycleIndexSeries()[:5] # needs sage.modules [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3], 1/24*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] + 1/8*p[2, 2] + 1/3*p[3, 1] + 1/4*p[4]] @@ -630,7 +630,7 @@ def _cl_term(n, R=QQ): EXAMPLES:: sage: from sage.combinat.species.generating_series import _cl_term - sage: [_cl_term(i) for i in range(4)] # optional - sage.modules + sage: [_cl_term(i) for i in range(4)] # needs sage.modules [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] """ n = Integer(n) # check that n is an integer @@ -662,15 +662,15 @@ def LogarithmCycleIndexSeries(R=QQ): its cycle index has negative coefficients:: sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries - sage: LogarithmCycleIndexSeries()[0:4] # optional - sage.modules + sage: LogarithmCycleIndexSeries()[0:4] # needs sage.modules [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] Its defining property is that `\Omega \circ E^{+} = E^{+} \circ \Omega = X` (that is, that composition with `E^{+}` in both directions yields the multiplicative identity `X`):: - sage: Eplus = sage.combinat.species.set_species.SetSpecies(min=1).cycle_index_series() # optional - sage.modules - sage: LogarithmCycleIndexSeries()(Eplus)[0:4] # optional - sage.modules + sage: Eplus = sage.combinat.species.set_species.SetSpecies(min=1).cycle_index_series() # needs sage.modules + sage: LogarithmCycleIndexSeries()(Eplus)[0:4] # needs sage.modules [0, p[1], 0, 0] """ CIS = CycleIndexSeriesRing(R) diff --git a/src/sage/combinat/species/library.py b/src/sage/combinat/species/library.py index 3e3025d87f6..c50a9fe75fa 100644 --- a/src/sage/combinat/species/library.py +++ b/src/sage/combinat/species/library.py @@ -43,25 +43,25 @@ def SimpleGraphSpecies(): sage: S = species.SimpleGraphSpecies() sage: S.generating_series().counts(10) [1, 1, 2, 8, 64, 1024, 32768, 2097152, 268435456, 68719476736] - sage: S.cycle_index_series()[:5] # optional - sage.modules + sage: S.cycle_index_series()[:5] # needs sage.modules [p[], p[1], p[1, 1] + p[2], 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] - sage: S.isotype_generating_series()[:6] # optional - sage.modules + sage: S.isotype_generating_series()[:6] # needs sage.modules [1, 1, 2, 4, 11, 34] TESTS:: - sage: seq = S.isotype_generating_series().counts(6)[1:] # optional - sage.modules - sage: oeis(seq)[0] # optional -- internet # optional - sage.modules + sage: seq = S.isotype_generating_series().counts(6)[1:] # needs sage.modules + sage: oeis(seq)[0] # optional - internet # needs sage.modules A000088: Number of graphs on n unlabeled nodes. :: - sage: seq = S.generating_series().counts(10)[1:] # optional - sage.modules - sage: oeis(seq)[0] # optional -- internet # optional - sage.modules + sage: seq = S.generating_series().counts(10)[1:] # needs sage.modules + sage: oeis(seq)[0] # optional - internet # needs sage.modules A006125: a(n) = 2^(n*(n-1)/2). """ E = SetSpecies() @@ -94,7 +94,7 @@ def BinaryTreeSpecies(): sage: B = species.BinaryTreeSpecies() sage: a = B.structures([1,2,3,4,5])[187]; a 2*((5*3)*(4*1)) - sage: a.automorphism_group() # optional - sage.groups + sage: a.automorphism_group() # needs sage.groups Permutation Group with generators [()] TESTS:: @@ -121,9 +121,9 @@ def BinaryForestSpecies(): sage: F = species.BinaryForestSpecies() sage: F.generating_series().counts(10) [1, 1, 3, 19, 193, 2721, 49171, 1084483, 28245729, 848456353] - sage: F.isotype_generating_series().counts(10) # optional - sage.modules + sage: F.isotype_generating_series().counts(10) # needs sage.modules [1, 1, 2, 4, 10, 26, 77, 235, 758, 2504] - sage: F.cycle_index_series()[:7] # optional - sage.modules + sage: F.cycle_index_series()[:7] # needs sage.modules [p[], p[1], 3/2*p[1, 1] + 1/2*p[2], @@ -134,8 +134,8 @@ def BinaryForestSpecies(): TESTS:: - sage: seq = F.isotype_generating_series().counts(10)[1:] # optional - sage.modules - sage: oeis(seq)[0] # optional -- internet # optional - sage.modules + sage: seq = F.isotype_generating_series().counts(10)[1:] # needs sage.modules + sage: oeis(seq)[0] # optional - internet # needs sage.modules A052854: Number of forests of ordered trees on n total nodes. """ B = BinaryTreeSpecies() diff --git a/src/sage/combinat/species/linear_order_species.py b/src/sage/combinat/species/linear_order_species.py index a889c8ab6c2..0761dea576d 100644 --- a/src/sage/combinat/species/linear_order_species.py +++ b/src/sage/combinat/species/linear_order_species.py @@ -43,8 +43,8 @@ def transport(self, perm): sage: F = species.LinearOrderSpecies() sage: a = F.structures(["a", "b", "c"])[0]; a ['a', 'b', 'c'] - sage: p = PermutationGroupElement((1,2)) # optional - sage.groups - sage: a.transport(p) # optional - sage.groups + sage: p = PermutationGroupElement((1,2)) # needs sage.groups + sage: a.transport(p) # needs sage.groups ['b', 'a', 'c'] """ return LinearOrderSpeciesStructure(self.parent(), self._labels, [perm(i) for i in self._list]) @@ -60,7 +60,7 @@ def automorphism_group(self): sage: F = species.LinearOrderSpecies() sage: a = F.structures(["a", "b", "c"])[0]; a ['a', 'b', 'c'] - sage: a.automorphism_group() # optional - sage.groups + sage: a.automorphism_group() # needs sage.groups Symmetric group of order 1! as a permutation group """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -155,8 +155,8 @@ def _cis_callable(self, base_ring, n): EXAMPLES:: sage: L = species.LinearOrderSpecies() - sage: g = L.cycle_index_series() # optional - sage.modules - sage: g[0:5] # optional - sage.modules + sage: g = L.cycle_index_series() # needs sage.modules + sage: g[0:5] # needs sage.modules [p[], p[1], p[1, 1], p[1, 1, 1], p[1, 1, 1, 1]] """ from sage.combinat.sf.sf import SymmetricFunctions diff --git a/src/sage/combinat/species/partition_species.py b/src/sage/combinat/species/partition_species.py index f3038ad6ba2..bd24f470402 100644 --- a/src/sage/combinat/species/partition_species.py +++ b/src/sage/combinat/species/partition_species.py @@ -272,7 +272,7 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: P = species.PartitionSpecies() - sage: g = P.cycle_index_series() # optional - sage.modules + sage: g = P.cycle_index_series() # needs sage.modules sage: g[0:5] [p[], p[1], diff --git a/src/sage/combinat/species/permutation_species.py b/src/sage/combinat/species/permutation_species.py index 470a766a2c4..59f41bbad0a 100644 --- a/src/sage/combinat/species/permutation_species.py +++ b/src/sage/combinat/species/permutation_species.py @@ -225,8 +225,8 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: g = P.cycle_index_series() # optional - sage.modules - sage: g[0:5] # optional - sage.modules + sage: g = P.cycle_index_series() # needs sage.modules + sage: g[0:5] # needs sage.modules [p[], p[1], p[1, 1] + p[2], @@ -244,7 +244,7 @@ def _cis_gen(self, base_ring, m, n): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: [P._cis_gen(QQ, 2, i) for i in range(10)] # optional - sage.modules + sage: [P._cis_gen(QQ, 2, i) for i in range(10)] # needs sage.modules [p[], 0, p[2], 0, p[2, 2], 0, p[2, 2, 2], 0, p[2, 2, 2, 2], 0] """ from sage.combinat.sf.sf import SymmetricFunctions diff --git a/src/sage/combinat/species/product_species.py b/src/sage/combinat/species/product_species.py index b1ce34596fd..41cd958532f 100644 --- a/src/sage/combinat/species/product_species.py +++ b/src/sage/combinat/species/product_species.py @@ -58,12 +58,12 @@ def transport(self, perm): """ EXAMPLES:: - sage: p = PermutationGroupElement((2,3)) # optional - sage.groups - sage: S = species.SetSpecies() # optional - sage.groups - sage: F = S * S # optional - sage.groups - sage: a = F.structures(['a','b','c'])[4]; a # optional - sage.groups + sage: p = PermutationGroupElement((2,3)) # needs sage.groups + sage: S = species.SetSpecies() # needs sage.groups + sage: F = S * S # needs sage.groups + sage: a = F.structures(['a','b','c'])[4]; a # needs sage.groups {'a', 'b'}*{'c'} - sage: a.transport(p) # optional - sage.groups + sage: a.transport(p) # needs sage.groups {'a', 'c'}*{'b'} """ left, right = self._list @@ -151,17 +151,17 @@ def automorphism_group(self): """ EXAMPLES:: - sage: p = PermutationGroupElement((2,3)) # optional - sage.groups - sage: S = species.SetSpecies() # optional - sage.groups - sage: F = S * S # optional - sage.groups - sage: a = F.structures([1,2,3,4])[1]; a # optional - sage.groups + sage: p = PermutationGroupElement((2,3)) # needs sage.groups + sage: S = species.SetSpecies() # needs sage.groups + sage: F = S * S # needs sage.groups + sage: a = F.structures([1,2,3,4])[1]; a # needs sage.groups {1}*{2, 3, 4} - sage: a.automorphism_group() # optional - sage.groups + sage: a.automorphism_group() # needs sage.groups Permutation Group with generators [(2,3), (2,3,4)] :: - sage: [a.transport(g) for g in a.automorphism_group()] # optional - sage.groups + sage: [a.transport(g) for g in a.automorphism_group()] # needs sage.groups [{1}*{2, 3, 4}, {1}*{2, 3, 4}, {1}*{2, 3, 4}, @@ -171,9 +171,9 @@ def automorphism_group(self): :: - sage: a = F.structures([1,2,3,4])[8]; a # optional - sage.groups + sage: a = F.structures([1,2,3,4])[8]; a # needs sage.groups {2, 3}*{1, 4} - sage: [a.transport(g) for g in a.automorphism_group()] # optional - sage.groups + sage: [a.transport(g) for g in a.automorphism_group()] # needs sage.groups [{2, 3}*{1, 4}, {2, 3}*{1, 4}, {2, 3}*{1, 4}, {2, 3}*{1, 4}] """ from sage.groups.perm_gps.constructor import PermutationGroupElement @@ -215,7 +215,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): Product of (Permutation species) and (Permutation species) sage: F == loads(dumps(F)) True - sage: F._check() # optional - sage.libs.flint + sage: F._check() # needs sage.libs.flint True TESTS:: @@ -340,7 +340,7 @@ def _itgs(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P * P - sage: F.isotype_generating_series()[0:5] # optional - sage.libs.flint + sage: F.isotype_generating_series()[0:5] # needs sage.libs.flint [1, 2, 5, 10, 20] """ res = (self.left_factor().isotype_generating_series(base_ring) * @@ -355,7 +355,7 @@ def _cis(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P * P - sage: F.cycle_index_series()[0:5] # optional - sage.modules + sage: F.cycle_index_series()[0:5] # needs sage.modules [p[], 2*p[1], 3*p[1, 1] + 2*p[2], @@ -409,7 +409,7 @@ def _equation(self, var_mapping): sage: X = species.SingletonSpecies() sage: S = X * X - sage: S.algebraic_equation_system() # optional - sage.graphs + sage: S.algebraic_equation_system() # needs sage.graphs [node0 + (-z^2)] """ from sage.misc.misc_c import prod diff --git a/src/sage/combinat/species/recursive_species.py b/src/sage/combinat/species/recursive_species.py index a87bb27866b..8eaabf0d2a8 100644 --- a/src/sage/combinat/species/recursive_species.py +++ b/src/sage/combinat/species/recursive_species.py @@ -263,7 +263,7 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: F = CombinatorialSpecies() - sage: F.cycle_index_series() # optional - sage.modules + sage: F.cycle_index_series() # needs sage.modules Uninitialized Lazy Series """ if base_ring not in self._cycle_index_series: @@ -429,17 +429,17 @@ def _add_to_digraph(self, d): EXAMPLES:: - sage: d = DiGraph(multiedges=True) # optional - sage.graphs + sage: d = DiGraph(multiedges=True) # needs sage.graphs sage: X = species.SingletonSpecies() sage: B = species.CombinatorialSpecies() sage: B.define(X+B*B) - sage: B._add_to_digraph(d); d # optional - sage.graphs + sage: B._add_to_digraph(d); d # needs sage.graphs Multi-digraph on 4 vertices TESTS:: sage: C = species.CombinatorialSpecies() - sage: C._add_to_digraph(d) # optional - sage.graphs + sage: C._add_to_digraph(d) # needs sage.graphs Traceback (most recent call last): ... NotImplementedError @@ -461,7 +461,7 @@ def _equation(self, var_mapping): EXAMPLES:: sage: C = species.CombinatorialSpecies() - sage: C.algebraic_equation_system() # optional - sage.graphs + sage: C.algebraic_equation_system() # needs sage.graphs Traceback (most recent call last): ... NotImplementedError @@ -469,7 +469,7 @@ def _equation(self, var_mapping): :: sage: B = species.BinaryTreeSpecies() - sage: B.algebraic_equation_system() # optional - sage.graphs + sage: B.algebraic_equation_system() # needs sage.graphs [-node3^2 + node1, -node1 + node3 + (-z)] """ try: diff --git a/src/sage/combinat/species/set_species.py b/src/sage/combinat/species/set_species.py index 31020f8eb5e..94aa893cf46 100644 --- a/src/sage/combinat/species/set_species.py +++ b/src/sage/combinat/species/set_species.py @@ -57,8 +57,8 @@ def transport(self, perm): sage: F = species.SetSpecies() sage: a = F.structures(["a", "b", "c"]).random_element(); a {'a', 'b', 'c'} - sage: p = PermutationGroupElement((1,2)) # optional - sage.groups - sage: a.transport(p) # optional - sage.groups + sage: p = PermutationGroupElement((1,2)) # needs sage.groups + sage: a.transport(p) # needs sage.groups {'a', 'b', 'c'} """ return self @@ -74,7 +74,7 @@ def automorphism_group(self): sage: F = species.SetSpecies() sage: a = F.structures(["a", "b", "c"]).random_element(); a {'a', 'b', 'c'} - sage: a.automorphism_group() # optional - sage.groups + sage: a.automorphism_group() # needs sage.groups Symmetric group of order 3! as a permutation group """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -170,8 +170,8 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: S = species.SetSpecies() - sage: g = S.cycle_index_series() # optional - sage.modules - sage: g[0:5] # optional - sage.modules + sage: g = S.cycle_index_series() # needs sage.modules + sage: g[0:5] # needs sage.modules [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index 0efdb963981..2b505567433 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -24,12 +24,12 @@ sage: L = species.LinearOrderSpecies(min=1) sage: T = species.CombinatorialSpecies(min=1) sage: T.define(leaf + internal_node*L(T)) - sage: T.isotype_generating_series()[0:6] # optional - sage.modules + sage: T.isotype_generating_series()[0:6] # needs sage.modules [0, 1, q, q^2 + q, q^3 + 3*q^2 + q, q^4 + 6*q^3 + 6*q^2 + q] Consider the following:: - sage: T.isotype_generating_series().coefficient(4) # optional - sage.modules + sage: T.isotype_generating_series().coefficient(4) # needs sage.modules q^3 + 3*q^2 + q This means that, among the trees on `4` nodes, one has a @@ -335,7 +335,7 @@ def functorial_composition(self, g): sage: WP = species.SubsetSpecies() sage: P2 = E2*E sage: G = WP.functorial_composition(P2) - sage: G.isotype_generating_series()[0:5] # optional - sage.modules + sage: G.isotype_generating_series()[0:5] # needs sage.modules [1, 1, 2, 4, 11] """ from .functorial_composition_species import FunctorialCompositionSpecies @@ -401,7 +401,7 @@ def _check(self, n=5): EXAMPLES:: sage: P = species.PartitionSpecies() - sage: P._check() # optional - sage.libs.flint + sage: P._check() # needs sage.libs.flint True """ st = self.structures(range(n)) @@ -448,7 +448,7 @@ def __pow__(self, n): sage: X^1 is X True sage: A = X^32 - sage: A.digraph() # optional - sage.graphs + sage: A.digraph() # needs sage.graphs Multi-digraph on 6 vertices TESTS:: @@ -622,13 +622,13 @@ def isotype_generating_series(self, base_ring=None): sage: P = species.PermutationSpecies() sage: g = P.isotype_generating_series() - sage: g[0:4] # optional - sage.libs.flint + sage: g[0:4] # needs sage.libs.flint [1, 1, 2, 3] - sage: g.counts(4) # optional - sage.libs.flint + sage: g.counts(4) # needs sage.libs.flint [1, 1, 2, 3] - sage: P.isotypes([1,2,3]).list() # optional - sage.libs.flint + sage: P.isotypes([1,2,3]).list() # needs sage.libs.flint [[2, 3, 1], [2, 1, 3], [1, 2, 3]] - sage: len(_) # optional - sage.libs.flint + sage: len(_) # needs sage.libs.flint 3 """ return self._get_series(OrdinaryGeneratingSeriesRing, "itgs", base_ring) @@ -643,8 +643,8 @@ def cycle_index_series(self, base_ring=None): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: g = P.cycle_index_series() # optional - sage.modules - sage: g[0:4] # optional - sage.modules + sage: g = P.cycle_index_series() # needs sage.modules + sage: g[0:4] # needs sage.modules [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] """ return self._get_series(CycleIndexSeriesRing, "cis", base_ring) @@ -710,19 +710,19 @@ def digraph(self): sage: X = species.SingletonSpecies() sage: B = species.CombinatorialSpecies() sage: B.define(X+B*B) - sage: g = B.digraph(); g # optional - sage.graphs + sage: g = B.digraph(); g # needs sage.graphs Multi-digraph on 4 vertices - sage: sorted(g, key=str) # optional - sage.graphs + sage: sorted(g, key=str) # needs sage.graphs [Combinatorial species, Product of (Combinatorial species) and (Combinatorial species), Singleton species, Sum of (Singleton species) and (Product of (Combinatorial species) and (Combinatorial species))] - sage: d = {sp: i for i, sp in enumerate(g)} # optional - sage.graphs - sage: g.relabel(d) # optional - sage.graphs - sage: g.canonical_label().edges(sort=True) # optional - sage.graphs + sage: d = {sp: i for i, sp in enumerate(g)} # needs sage.graphs + sage: g.relabel(d) # needs sage.graphs + sage: g.canonical_label().edges(sort=True) # needs sage.graphs [(0, 3, None), (2, 0, None), (2, 0, None), (3, 1, None), (3, 2, None)] """ from sage.graphs.digraph import DiGraph @@ -739,13 +739,13 @@ def _add_to_digraph(self, d): EXAMPLES:: - sage: d = DiGraph(multiedges=True) # optional - sage.graphs - sage: X = species.SingletonSpecies() # optional - sage.graphs - sage: X._add_to_digraph(d); d # optional - sage.graphs + sage: d = DiGraph(multiedges=True) # needs sage.graphs + sage: X = species.SingletonSpecies() # needs sage.graphs + sage: X._add_to_digraph(d); d # needs sage.graphs Multi-digraph on 1 vertex - sage: (X+X)._add_to_digraph(d); d # optional - sage.graphs + sage: (X+X)._add_to_digraph(d); d # needs sage.graphs Multi-digraph on 2 vertices - sage: d.edges(sort=True) # optional - sage.graphs + sage: d.edges(sort=True) # needs sage.graphs [(Sum of (Singleton species) and (Singleton species), Singleton species, None), (Sum of (Singleton species) and (Singleton species), Singleton species, None)] """ @@ -770,12 +770,12 @@ def algebraic_equation_system(self): EXAMPLES:: sage: B = species.BinaryTreeSpecies() - sage: B.algebraic_equation_system() # optional - sage.graphs + sage: B.algebraic_equation_system() # needs sage.graphs [-node3^2 + node1, -node1 + node3 + (-z)] :: - sage: sorted(B.digraph().vertex_iterator(), key=str) # optional - sage.graphs + sage: sorted(B.digraph().vertex_iterator(), key=str) # needs sage.graphs [Combinatorial species with min=1, Product of (Combinatorial species with min=1) and (Combinatorial species with min=1), @@ -786,7 +786,7 @@ def algebraic_equation_system(self): :: - sage: B.algebraic_equation_system()[0].parent() # optional - sage.graphs + sage: B.algebraic_equation_system()[0].parent() # needs sage.graphs Multivariate Polynomial Ring in node0, node1, node2, node3 over Fraction Field of Univariate Polynomial Ring in z over Rational Field """ diff --git a/src/sage/combinat/species/structure.py b/src/sage/combinat/species/structure.py index 6dc1fc2ea15..b3003ed0f13 100644 --- a/src/sage/combinat/species/structure.py +++ b/src/sage/combinat/species/structure.py @@ -16,8 +16,8 @@ sage: bar = species.EmptySetSpecies() sage: BB = CombinatorialSpecies() sage: BB.define(ball + ball*BB + ball*bar*BB) - sage: o = var('o') # optional - sage.symbolic - sage: BB.isotypes([o]*3).list() # optional - sage.symbolic + sage: o = var('o') # needs sage.symbolic + sage: BB.isotypes([o]*3).list() # needs sage.symbolic [o*(o*o), o*((o*{})*o), (o*{})*(o*o), (o*{})*((o*{})*o)] If we ignore the parentheses, we can read off that the integer @@ -277,9 +277,9 @@ def transport(self, perm): EXAMPLES:: sage: P = species.PartitionSpecies() - sage: s = (P+P).structures([1,2,3])[1]; s # optional - sage.libs.flint + sage: s = (P+P).structures([1,2,3])[1]; s # needs sage.libs.flint {{1, 3}, {2}} - sage: s.transport(PermutationGroupElement((2,3))) # optional - sage.groups sage.libs.flint + sage: s.transport(PermutationGroupElement((2,3))) # needs sage.groups sage.libs.flint {{1, 2}, {3}} """ return self.__class__(self._parent, self._s.transport(perm), **self._options) @@ -289,9 +289,9 @@ def canonical_label(self): EXAMPLES:: sage: P = species.PartitionSpecies() - sage: s = (P+P).structures([1,2,3])[1]; s # optional - sage.libs.flint + sage: s = (P+P).structures([1,2,3])[1]; s # needs sage.libs.flint {{1, 3}, {2}} - sage: s.canonical_label() # optional - sage.libs.flint + sage: s.canonical_label() # needs sage.libs.flint {{1, 2}, {3}} """ return self.__class__(self._parent, self._s.canonical_label(), **self._options) diff --git a/src/sage/combinat/species/subset_species.py b/src/sage/combinat/species/subset_species.py index 2d3b9f8dcb6..2e7a6697e29 100644 --- a/src/sage/combinat/species/subset_species.py +++ b/src/sage/combinat/species/subset_species.py @@ -74,11 +74,11 @@ def transport(self, perm): sage: F = species.SubsetSpecies() sage: a = F.structures(["a", "b", "c"])[5]; a {'a', 'c'} - sage: p = PermutationGroupElement((1,2)) # optional - sage.groups - sage: a.transport(p) # optional - sage.groups + sage: p = PermutationGroupElement((1,2)) # needs sage.groups + sage: a.transport(p) # needs sage.groups {'b', 'c'} - sage: p = PermutationGroupElement((1,3)) # optional - sage.groups - sage: a.transport(p) # optional - sage.groups + sage: p = PermutationGroupElement((1,3)) # needs sage.groups + sage: a.transport(p) # needs sage.groups {'a', 'c'} """ l = sorted([perm(i) for i in self._list]) @@ -94,12 +94,12 @@ def automorphism_group(self): sage: F = species.SubsetSpecies() sage: a = F.structures([1,2,3,4])[6]; a {1, 3} - sage: a.automorphism_group() # optional - sage.groups + sage: a.automorphism_group() # needs sage.groups Permutation Group with generators [(2,4), (1,3)] :: - sage: [a.transport(g) for g in a.automorphism_group()] # optional - sage.groups + sage: [a.transport(g) for g in a.automorphism_group()] # needs sage.groups [{1, 3}, {1, 3}, {1, 3}, {1, 3}] """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -224,7 +224,7 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: S = species.SubsetSpecies() - sage: S.cycle_index_series()[0:5] # optional - sage.modules + sage: S.cycle_index_series()[0:5] # needs sage.modules [p[], 2*p[1], 2*p[1, 1] + p[2], diff --git a/src/sage/combinat/species/sum_species.py b/src/sage/combinat/species/sum_species.py index ac2e05943b3..b3ff129dc55 100644 --- a/src/sage/combinat/species/sum_species.py +++ b/src/sage/combinat/species/sum_species.py @@ -38,7 +38,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: P = species.PermutationSpecies() sage: F = P + P - sage: F._check() # optional - sage.libs.flint + sage: F._check() # needs sage.libs.flint True sage: F == loads(dumps(F)) True @@ -126,7 +126,7 @@ def _isotypes(self, structure_class, labels): sage: P = species.PermutationSpecies() sage: F = P + P - sage: F.isotypes([1,2]).list() # optional - sage.libs.flint + sage: F.isotypes([1,2]).list() # needs sage.libs.flint [[2, 1], [1, 2], [2, 1], [1, 2]] """ for res in self._F.isotypes(labels): @@ -157,7 +157,7 @@ def _itgs(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P + P - sage: F.isotype_generating_series()[:5] # optional - sage.libs.flint + sage: F.isotype_generating_series()[:5] # needs sage.libs.flint [2, 2, 4, 6, 10] """ return (self.left_summand().isotype_generating_series(base_ring) + @@ -171,7 +171,7 @@ def _cis(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P + P - sage: F.cycle_index_series()[:5] # optional - sage.modules + sage: F.cycle_index_series()[:5] # needs sage.modules [2*p[], 2*p[1], 2*p[1, 1] + 2*p[2], @@ -214,7 +214,7 @@ def _equation(self, var_mapping): sage: X = species.SingletonSpecies() sage: S = X + X - sage: S.algebraic_equation_system() # optional - sage.graphs + sage: S.algebraic_equation_system() # needs sage.graphs [node1 + (-2*z)] """ return sum(var_mapping[operand] for operand in self._state_info) From bddb7fc8c5e89cbaa79a25225699436bc0820468 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 13 Jul 2023 23:26:30 -0700 Subject: [PATCH 127/463] sage.combinat.species: Update # needs --- .../combinat/species/composition_species.py | 19 ++++---- .../combinat/species/generating_series.py | 45 ++++++++++--------- .../combinat/species/partition_species.py | 2 +- src/sage/combinat/species/product_species.py | 22 ++++----- src/sage/combinat/species/species.py | 11 ++--- 5 files changed, 53 insertions(+), 46 deletions(-) diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index a60b0cbed89..b60e5348985 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -145,21 +145,22 @@ def _structures(self, structure_class, labels): TESTS:: - sage: a = _[2] # needs sage.libs.flint - sage: f, gs = a._list # needs sage.libs.flint - sage: f # needs sage.libs.flint + sage: # needs sage.libs.flint + sage: a = _[2] + sage: f, gs = a._list + sage: f {{'a', 'c'}, {'b'}} - sage: f.parent() # needs sage.libs.flint + sage: f.parent() Set species - sage: f._list # needs sage.libs.flint + sage: f._list [1, 2] - sage: f._labels # needs sage.libs.flint + sage: f._labels [{'a', 'c'}, {'b'}] - sage: [g.parent() for g in gs] # needs sage.libs.flint + sage: [g.parent() for g in gs] [Cyclic permutation species, Cyclic permutation species] - sage: [g._labels for g in gs] # needs sage.libs.flint + sage: [g._labels for g in gs] [['a', 'c'], ['b']] - sage: [g._list for g in gs] # needs sage.libs.flint + sage: [g._list for g in gs] [[1, 2], [1]] """ from itertools import product diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 9c0515bbead..c585634d314 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -15,19 +15,20 @@ TESTS:: + sage: # needs sage.modules sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() # needs sage.modules - sage: CIS = CycleIndexSeriesRing(QQ) # needs sage.modules - sage: geo1 = CIS(lambda i: p([1])^i) # needs sage.modules - sage: geo2 = CIS(lambda i: p([2])^(i // 2) if is_even(i) else 0) # needs sage.modules - sage: s = geo1 * geo2 # needs sage.modules - sage: s[0] # needs sage.modules + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + sage: geo1 = CIS(lambda i: p([1])^i) + sage: geo2 = CIS(lambda i: p([2])^(i // 2) if is_even(i) else 0) + sage: s = geo1 * geo2 + sage: s[0] p[] - sage: s[1] # needs sage.modules + sage: s[1] p[1] - sage: s[2] # needs sage.modules + sage: s[2] p[1, 1] + p[2] - sage: s[3] # needs sage.modules + sage: s[3] p[1, 1, 1] + p[2, 1] REFERENCES: @@ -292,15 +293,16 @@ def count(self, t): EXAMPLES:: + sage: # needs sage.modules sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() # needs sage.modules - sage: CIS = CycleIndexSeriesRing(QQ) # needs sage.modules - sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) # needs sage.modules - sage: f.count([1]) # needs sage.modules + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) + sage: f.count([1]) 1 - sage: f.count([1,1]) # needs sage.modules + sage: f.count([1,1]) 4 - sage: f.count([2,1]) # needs sage.modules + sage: f.count([2,1]) 6 """ t = Partition(t) @@ -312,15 +314,16 @@ def coefficient_cycle_type(self, t): EXAMPLES:: + sage: # needs sage.modules sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() # needs sage.modules - sage: CIS = CycleIndexSeriesRing(QQ) # needs sage.modules - sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) # needs sage.modules - sage: f.coefficient_cycle_type([1]) # needs sage.modules + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) + sage: f.coefficient_cycle_type([1]) 1 - sage: f.coefficient_cycle_type([1,1]) # needs sage.modules + sage: f.coefficient_cycle_type([1,1]) 2 - sage: f.coefficient_cycle_type([2,1]) # needs sage.modules + sage: f.coefficient_cycle_type([2,1]) 3 """ t = Partition(t) diff --git a/src/sage/combinat/species/partition_species.py b/src/sage/combinat/species/partition_species.py index bd24f470402..21a57197ccd 100644 --- a/src/sage/combinat/species/partition_species.py +++ b/src/sage/combinat/species/partition_species.py @@ -273,7 +273,7 @@ def _cis(self, series_ring, base_ring): sage: P = species.PartitionSpecies() sage: g = P.cycle_index_series() # needs sage.modules - sage: g[0:5] + sage: g[0:5] # needs sage.modules [p[], p[1], p[1, 1] + p[2], diff --git a/src/sage/combinat/species/product_species.py b/src/sage/combinat/species/product_species.py index 41cd958532f..90209e64776 100644 --- a/src/sage/combinat/species/product_species.py +++ b/src/sage/combinat/species/product_species.py @@ -58,12 +58,13 @@ def transport(self, perm): """ EXAMPLES:: - sage: p = PermutationGroupElement((2,3)) # needs sage.groups - sage: S = species.SetSpecies() # needs sage.groups - sage: F = S * S # needs sage.groups - sage: a = F.structures(['a','b','c'])[4]; a # needs sage.groups + sage: # needs sage.groups + sage: p = PermutationGroupElement((2,3)) + sage: S = species.SetSpecies() + sage: F = S * S + sage: a = F.structures(['a','b','c'])[4]; a {'a', 'b'}*{'c'} - sage: a.transport(p) # needs sage.groups + sage: a.transport(p) {'a', 'c'}*{'b'} """ left, right = self._list @@ -151,12 +152,13 @@ def automorphism_group(self): """ EXAMPLES:: - sage: p = PermutationGroupElement((2,3)) # needs sage.groups - sage: S = species.SetSpecies() # needs sage.groups - sage: F = S * S # needs sage.groups - sage: a = F.structures([1,2,3,4])[1]; a # needs sage.groups + sage: # needs sage.groups + sage: p = PermutationGroupElement((2,3)) + sage: S = species.SetSpecies() + sage: F = S * S + sage: a = F.structures([1,2,3,4])[1]; a {1}*{2, 3, 4} - sage: a.automorphism_group() # needs sage.groups + sage: a.automorphism_group() Permutation Group with generators [(2,3), (2,3,4)] :: diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index 2b505567433..d3f1e9d3867 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -739,13 +739,14 @@ def _add_to_digraph(self, d): EXAMPLES:: - sage: d = DiGraph(multiedges=True) # needs sage.graphs - sage: X = species.SingletonSpecies() # needs sage.graphs - sage: X._add_to_digraph(d); d # needs sage.graphs + sage: # needs sage.graphs + sage: d = DiGraph(multiedges=True) + sage: X = species.SingletonSpecies() + sage: X._add_to_digraph(d); d Multi-digraph on 1 vertex - sage: (X+X)._add_to_digraph(d); d # needs sage.graphs + sage: (X+X)._add_to_digraph(d); d Multi-digraph on 2 vertices - sage: d.edges(sort=True) # needs sage.graphs + sage: d.edges(sort=True) [(Sum of (Singleton species) and (Singleton species), Singleton species, None), (Sum of (Singleton species) and (Singleton species), Singleton species, None)] """ From 02a8c740cc0ca9d0b6b255b52f4fa7dd10ff8d09 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 25 May 2023 17:51:07 -0700 Subject: [PATCH 128/463] sage.combinat: Modularization fixes for imports --- src/sage/combinat/words/suffix_trees.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/words/suffix_trees.py b/src/sage/combinat/words/suffix_trees.py index 5e4fa13ddea..59b3acb57d3 100644 --- a/src/sage/combinat/words/suffix_trees.py +++ b/src/sage/combinat/words/suffix_trees.py @@ -13,12 +13,15 @@ from itertools import chain from sage.structure.sage_object import SageObject -from sage.graphs.digraph import DiGraph from sage.sets.set import Set from sage.combinat.words.words import Words from sage.combinat.words.word import Word +from sage.misc.lazy_import import lazy_import from sage.rings.integer import Integer +lazy_import('sage.graphs.digraph', 'DiGraph') + + ################################################################################ # Suffix Tries ################################################################################ From d281815ebf8c330cd8d7b885dc5e2d8f16b8b16e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 3 Jun 2023 16:59:56 -0700 Subject: [PATCH 129/463] sage.combinat: Modularization fixes --- src/sage/combinat/words/finite_word.py | 5 +++-- src/sage/combinat/words/morphic.py | 10 +++++----- src/sage/combinat/words/morphism.py | 8 +++++--- src/sage/combinat/words/word.py | 4 +++- src/sage/combinat/words/word_generators.py | 4 +++- src/sage/combinat/words/words.py | 4 ++-- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index bf355d9d10a..b5bb427373c 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -221,6 +221,7 @@ from sage.combinat.words.abstract_word import Word_class from sage.combinat.words.words import Words from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.combinat.words.word_options import word_options from sage.rings.infinity import Infinity from sage.rings.integer import Integer @@ -228,6 +229,8 @@ from sage.rings.rational_field import QQ from sage.sets.set import Set +lazy_import('sage.groups.perm_gps.permgroup_element', 'PermutationGroupElement') + class FiniteWord_class(Word_class): def __str__(self): @@ -6752,7 +6755,6 @@ def apply_permutation_to_positions(self, permutation): word: 3421 """ from sage.combinat.permutation import Permutation - from sage.groups.perm_gps.permgroup_element import PermutationGroupElement if not isinstance(permutation, Permutation): if isinstance(permutation, PermutationGroupElement): permutation = Permutation(permutation.domain()) @@ -6781,7 +6783,6 @@ def apply_permutation_to_letters(self, permutation): word: badc """ from sage.combinat.permutation import Permutation - from sage.groups.perm_gps.permgroup_element import PermutationGroupElement if not isinstance(permutation, Permutation): if isinstance(permutation, PermutationGroupElement): permutation = Permutation(permutation.domain()) diff --git a/src/sage/combinat/words/morphic.py b/src/sage/combinat/words/morphic.py index 389c37a9b65..d5c447403d0 100644 --- a/src/sage/combinat/words/morphic.py +++ b/src/sage/combinat/words/morphic.py @@ -14,8 +14,7 @@ Creation of the fixed point of a morphism:: sage: m = WordMorphism('a->abc,b->baba,c->ca') - sage: w = m.fixed_point('a') - sage: w + sage: w = m.fixed_point('a'); w word: abcbabacababaabcbabaabccaabcbabaabcbabaa... sage: w.length() +Infinity @@ -30,8 +29,10 @@ """ from sage.combinat.words.word_infinite_datatypes import WordDatatype_callable +from sage.misc.lazy_import import lazy_import from sage.rings.infinity import Infinity -from sage.modules.free_module_element import vector + +lazy_import('sage.modules.free_module_element', 'import vector') class WordDatatype_morphic(WordDatatype_callable): @@ -78,8 +79,7 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): When the morphic word is finite:: sage: m = WordMorphism("a->ab,b->") - sage: w = m.fixed_point("a") - sage: w + sage: w = m.fixed_point("a"); w word: ab sage: w[0] # optional - sage.modules 'a' diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index 7e04e8646d0..e618ccbdaeb 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -93,17 +93,19 @@ from sage.misc.callable_dict import CallableDict from sage.structure.sage_object import SageObject from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.misc.lazy_list import lazy_list from sage.sets.set import Set from sage.rings.rational_field import QQ from sage.rings.infinity import Infinity from sage.rings.integer_ring import IntegerRing from sage.rings.integer import Integer -from sage.modules.free_module_element import vector -from sage.matrix.constructor import Matrix from sage.combinat.words.word import FiniteWord_class from sage.combinat.words.words import FiniteWords, FiniteOrInfiniteWords +lazy_import('sage.modules.free_module_element', 'vector') +lazy_import('sage.matrix.constructor', 'Matrix') + def get_cycles(f, domain): r""" @@ -2084,7 +2086,7 @@ def language(self, n, u=None): A growing but non-primitive example. The DOL-languages generated by 0 and 2 are different:: - sage: s = WordMorphism({0: [0,1], 1:[0], 2:[2,0,2]}) + sage: s = WordMorphism({0: [0,1], 1: [0], 2: [2,0,2]}) sage: u = s.fixed_point(0) sage: A0 = u[:200].factor_set(5) diff --git a/src/sage/combinat/words/word.py b/src/sage/combinat/words/word.py index 4555c2df762..320bc3d9f0c 100644 --- a/src/sage/combinat/words/word.py +++ b/src/sage/combinat/words/word.py @@ -23,6 +23,7 @@ # (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** +from sage.misc.lazy_import import lazy_import from sage.combinat.words.word_char import WordDatatype_char from sage.combinat.words.abstract_word import Word_class from sage.combinat.words.finite_word import FiniteWord_class @@ -36,7 +37,8 @@ WordDatatype_callable_with_caching, WordDatatype_callable) from .morphic import WordDatatype_morphic -from sage.monoids.free_monoid_element import FreeMonoidElement + +lazy_import('sage.monoids.free_monoid_element', 'FreeMonoidElement') # TODO. Word needs to be replaced by Word. Consider renaming # Word_class to Word and imbedding Word as its __call__ method. diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index d7093ae997c..e21ab9a22b4 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -59,7 +59,6 @@ from random import randint from sage.misc.cachefunc import cached_method from sage.rings.integer_ring import ZZ -from sage.rings.real_mpfr import RR from sage.rings.infinity import Infinity from sage.combinat.words.abstract_word import Word_class from sage.combinat.words.word import FiniteWord_list @@ -68,6 +67,9 @@ from sage.combinat.words.morphism import WordMorphism from sage.arith.misc import gcd from sage.misc.decorators import rename_keyword +from sage.misc.lazy_import import lazy_import + +lazy_import('sage.rings.real_mpfr', 'RR') def _build_tab(sym, tab, W): diff --git a/src/sage/combinat/words/words.py b/src/sage/combinat/words/words.py index 63d6f1f0d05..8c23a452bc7 100644 --- a/src/sage/combinat/words/words.py +++ b/src/sage/combinat/words/words.py @@ -1973,7 +1973,7 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr sage: p.length() # optional - sage.modules 100 - Creation of a word path from a FiniteWord_callable:: + Creation of a word path from a :class:`FiniteWord_callable`:: sage: g = Word(lambda n: n%2, length=100) sage: P = WordPaths([0,1,2,3]) # optional - sage.modules @@ -1984,7 +1984,7 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr Creation of a word from a pickled function:: - sage: f = lambda n : n % 10 + sage: f = lambda n: n % 10 sage: from sage.misc.fpickle import pickle_function sage: s = pickle_function(f) sage: Word(s, datatype='pickled_function') From 4696b3d27464ab5dab1d0321757a605b161a6914 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 8 Jun 2023 18:33:43 -0700 Subject: [PATCH 130/463] sage.combinat: More # optional --- src/sage/combinat/words/finite_word.py | 6 +++--- src/sage/combinat/words/lyndon_word.py | 16 ++++++++-------- src/sage/combinat/words/morphic.py | 8 ++++---- src/sage/combinat/words/morphism.py | 26 +++++++++++++------------- src/sage/combinat/words/word_char.pyx | 4 ++-- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index b5bb427373c..bdb182ac6b9 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -1676,7 +1676,7 @@ def reduced_rauzy_graph(self, n): For ultimately periodic words:: sage: sigma = WordMorphism('a->abcd,b->cd,c->cd,d->cd') - sage: w = sigma.fixed_point('a')[:100]; w + sage: w = sigma.fixed_point('a')[:100]; w # optional - sage.modules word: abcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd... sage: g = w.reduced_rauzy_graph(5) # optional - sage.graphs sage: g.vertices(sort=True) # optional - sage.graphs @@ -6749,7 +6749,7 @@ def apply_permutation_to_positions(self, permutation): word: badc sage: w.apply_permutation_to_positions(Permutation([2,1,4,3])) word: badc - sage: w.apply_permutation_to_positions(PermutationGroupElement([2,1,4,3])) + sage: w.apply_permutation_to_positions(PermutationGroupElement([2,1,4,3])) # optional - sage.groups word: badc sage: Word([1,2,3,4]).apply_permutation_to_positions([3,4,2,1]) word: 3421 @@ -6779,7 +6779,7 @@ def apply_permutation_to_letters(self, permutation): word: dcba sage: w.apply_permutation_to_letters(Permutation(p)) word: badc - sage: w.apply_permutation_to_letters(PermutationGroupElement(p)) + sage: w.apply_permutation_to_letters(PermutationGroupElement(p)) # optional - sage.groups word: badc """ from sage.combinat.permutation import Permutation diff --git a/src/sage/combinat/words/lyndon_word.py b/src/sage/combinat/words/lyndon_word.py index 6adb96421e5..575d68c58bc 100644 --- a/src/sage/combinat/words/lyndon_word.py +++ b/src/sage/combinat/words/lyndon_word.py @@ -64,9 +64,9 @@ def LyndonWords(e=None, k=None): word: 1112 sage: LW.last() word: 2333 - sage: LW.random_element() # random + sage: LW.random_element() # random # optional - sage.libs.pari word: 1232 - sage: LW.cardinality() + sage: LW.cardinality() # optional - sage.libs.pari 18 If e is a (weak) composition, then it returns the class of Lyndon @@ -277,9 +277,9 @@ def cardinality(self): sage: LyndonWords([]).cardinality() 0 - sage: LyndonWords([2,2]).cardinality() + sage: LyndonWords([2,2]).cardinality() # optional - sage.libs.pari 1 - sage: LyndonWords([2,3,2]).cardinality() + sage: LyndonWords([2,3,2]).cardinality() # optional - sage.libs.pari 30 Check to make sure that the count matches up with the number of @@ -287,7 +287,7 @@ def cardinality(self): sage: comps = [[],[2,2],[3,2,7],[4,2]] + Compositions(4).list() sage: lws = [LyndonWords(comp) for comp in comps] - sage: all(lw.cardinality() == len(lw.list()) for lw in lws) + sage: all(lw.cardinality() == len(lw.list()) for lw in lws) # optional - sage.libs.pari True """ evaluation = self._e @@ -417,7 +417,7 @@ def __call__(self, *args, **kwds): Make sure that the correct length is checked (:trac:`30186`):: sage: L = LyndonWords(2, 4) - sage: _ = L(L.random_element()) + sage: _ = L(L.random_element()) # optional - sage.libs.pari """ w = self._words(*args, **kwds) if kwds.get('check', True) and not w.is_lyndon(): @@ -443,7 +443,7 @@ def cardinality(self): """ TESTS:: - sage: [ LyndonWords(3,i).cardinality() for i in range(1, 11) ] + sage: [ LyndonWords(3,i).cardinality() for i in range(1, 11) ] # optional - sage.libs.pari [3, 3, 8, 18, 48, 116, 312, 810, 2184, 5880] """ if self._k == 0: @@ -470,7 +470,7 @@ def __iter__(self): sage: sum(1 for lw in LyndonWords(1, 1000)) 0 - sage: list(LyndonWords(1, 1)) + sage: list(LyndonWords(1, 1)) # optional - sage.libs.pari [word: 1] """ W = self._words._element_classes['list'] diff --git a/src/sage/combinat/words/morphic.py b/src/sage/combinat/words/morphic.py index d5c447403d0..96390756bfb 100644 --- a/src/sage/combinat/words/morphic.py +++ b/src/sage/combinat/words/morphic.py @@ -255,11 +255,11 @@ def _func(self, key): sage: m = WordMorphism("a->ab,b->a") sage: w = m.fixed_point("a") - sage: w[0] + sage: w[0] # optional - sage.modules 'a' - sage: w[5] + sage: w[5] # optional - sage.modules 'a' - sage: w[10000] + sage: w[10000] # optional - sage.modules 'a' TESTS: @@ -271,7 +271,7 @@ def _func(self, key): sage: W = m.domain() sage: from sage.combinat.words.morphic import WordDatatype_morphic sage: w = WordDatatype_morphic(W, m, 'a') - sage: w._func(5) + sage: w._func(5) # optional - sage.modules 'a' """ diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index e618ccbdaeb..e46f7f9d075 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -1590,25 +1590,25 @@ def is_primitive(self): EXAMPLES:: sage: tm = WordMorphism('a->ab,b->ba') - sage: tm.is_primitive() + sage: tm.is_primitive() # optional - sage.modules True sage: fibo = WordMorphism('a->ab,b->a') - sage: fibo.is_primitive() + sage: fibo.is_primitive() # optional - sage.modules True sage: m = WordMorphism('a->bb,b->aa') - sage: m.is_primitive() + sage: m.is_primitive() # optional - sage.modules False sage: f = WordMorphism({0:[1],1:[0]}) - sage: f.is_primitive() + sage: f.is_primitive() # optional - sage.modules False :: sage: s = WordMorphism('a->b,b->c,c->ab') - sage: s.is_primitive() + sage: s.is_primitive() # optional - sage.modules True sage: s = WordMorphism('a->b,b->c,c->d,d->e,e->f,f->g,g->h,h->ab') - sage: s.is_primitive() + sage: s.is_primitive() # optional - sage.modules True TESTS:: @@ -1618,8 +1618,8 @@ def is_primitive(self): Traceback (most recent call last): ... TypeError: self (=a->bb, b->aac) is not an endomorphism - sage: m = WordMorphism('a->,b->',codomain=Words('ab')) - sage: m.is_primitive() + sage: m = WordMorphism('a->,b->', codomain=Words('ab')) + sage: m.is_primitive() # optional - sage.modules False sage: m = WordMorphism('a->,b->') sage: m.is_primitive() @@ -1683,9 +1683,9 @@ def is_prolongable(self, letter): :: - sage: n0, n1 = matrix(2,[1,1,1,0]), matrix(2,[2,1,1,0]) - sage: n = {'a':n0, 'b':n1} - sage: WordMorphism(n).is_prolongable(letter='a') #todo: not implemented + sage: n0, n1 = matrix(2,[1,1,1,0]), matrix(2,[2,1,1,0]) # optional - sage.modules + sage: n = {'a':n0, 'b':n1} # optional - sage.modules + sage: WordMorphism(n).is_prolongable(letter='a') # todo: not implemented # optional - sage.modules Traceback (most recent call last): ... TypeError: codomain of self must be an instance of Words @@ -2089,7 +2089,7 @@ def language(self, n, u=None): sage: s = WordMorphism({0: [0,1], 1: [0], 2: [2,0,2]}) sage: u = s.fixed_point(0) - sage: A0 = u[:200].factor_set(5) + sage: A0 = u[:200].factor_set(5) # optional - sage.modules sage: B0 = s.language(5, [0]) # optional - sage.modules sage: set(A0) == B0 # optional - sage.modules True @@ -2888,7 +2888,7 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, sage: t = WordMorphism("a->aC,b->d,C->de,d->a,e->ab") # substitution found by Julien Bernat sage: V = [vector((0,0,1,0,-1)), vector((0,0,1,-1,0))] # optional - sage.modules - sage: S = set(map(tuple, [i*V[0] + j*V[1] + sage: S = set(map(tuple, [i*V[0] + j*V[1] # optional - sage.modules ....: for i in [-1,0,1] for j in [-1,0,1]])) sage: t.rauzy_fractal_plot(n=10000, # not tested (> 1 second) ....: translate=S, exchange=true) diff --git a/src/sage/combinat/words/word_char.pyx b/src/sage/combinat/words/word_char.pyx index f2b7b47edb2..31f642ffc65 100644 --- a/src/sage/combinat/words/word_char.pyx +++ b/src/sage/combinat/words/word_char.pyx @@ -716,9 +716,9 @@ cdef class WordDatatype_char(WordDatatype): sage: W = Words([0,1]) sage: w = words.FibonacciWord() sage: w = W(list(w[:5000])) - sage: L = [[len(w[n:].longest_common_prefix(w[n+fibonacci(i):])) + sage: L = [[len(w[n:].longest_common_prefix(w[n+fibonacci(i):])) # optional - sage.libs.pari ....: for i in range(5,15)] for n in range(1,1000)] - sage: for n,l in enumerate(L): + sage: for n,l in enumerate(L): # optional - sage.libs.pari ....: if l.count(0) > 4: ....: print("{} {}".format(n+1,l)) 375 [0, 13, 0, 34, 0, 89, 0, 233, 0, 233] From 0e31af803a4f84a93703617689a348b47238c9c8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 9 Jun 2023 00:55:41 -0700 Subject: [PATCH 131/463] More # optional --- src/sage/combinat/words/morphism.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index e46f7f9d075..6e11f5db4c9 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -2095,7 +2095,7 @@ def language(self, n, u=None): True sage: v = s.fixed_point(2) - sage: A2 = v[:200].factor_set(5) + sage: A2 = v[:200].factor_set(5) # optional - sage.modules sage: B2 = s.language(5, [2]) # optional - sage.modules sage: set(A2) == B2 # optional - sage.modules True From 9aa2aa470446581cca4a1a1da25c7af6f965a858 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 17:49:30 -0700 Subject: [PATCH 132/463] More # optional --- src/sage/combinat/words/morphism.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index 6e11f5db4c9..5fc7d5e62b7 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -709,7 +709,7 @@ def __call__(self, w, order=1): sage: tm('a', 6.7) Traceback (most recent call last): ... - TypeError: order (6.70000000000000) must be a non-negative integer or plus Infinity + TypeError: order (6.7...) must be a non-negative integer or plus Infinity Only the first letter is considered for infinitely iterated image of a word under a morphism:: @@ -976,7 +976,7 @@ def __pow__(self, exp): sage: m^1.5 Traceback (most recent call last): ... - ValueError: exponent (1.50000000000000) must be an integer + ValueError: exponent (1.5...) must be an integer sage: m^-2 Traceback (most recent call last): ... @@ -2100,7 +2100,7 @@ def language(self, n, u=None): sage: set(A2) == B2 # optional - sage.modules True - sage: len(A0), len(A2) + sage: len(A0), len(A2) # optional - sage.modules (6, 20) The Chacon transformation (non-primitive):: From 91e44aa1caae5a8113f5811e5ca04a320c4d6bed Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 23:46:00 -0700 Subject: [PATCH 133/463] sage.combinat: More # optional --- src/sage/combinat/words/finite_word.py | 2 +- src/sage/combinat/words/morphic.py | 2 +- src/sage/combinat/words/paths.py | 3 ++- src/sage/combinat/words/word_generators.py | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index bdb182ac6b9..9fe6dc815c0 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -5977,7 +5977,7 @@ def is_sturmian_factor(self): sage: words.LowerMechanicalWord(random(),alphabet='01')[:100].is_sturmian_factor() True - sage: words.CharacteristicSturmianWord(random())[:100].is_sturmian_factor() + sage: words.CharacteristicSturmianWord(random())[:100].is_sturmian_factor() # optional - sage.rings.real_mpfr True :: diff --git a/src/sage/combinat/words/morphic.py b/src/sage/combinat/words/morphic.py index 96390756bfb..73d4973af85 100644 --- a/src/sage/combinat/words/morphic.py +++ b/src/sage/combinat/words/morphic.py @@ -32,7 +32,7 @@ from sage.misc.lazy_import import lazy_import from sage.rings.infinity import Infinity -lazy_import('sage.modules.free_module_element', 'import vector') +lazy_import('sage.modules.free_module_element', 'vector') class WordDatatype_morphic(WordDatatype_callable): diff --git a/src/sage/combinat/words/paths.py b/src/sage/combinat/words/paths.py index cc4aecd250b..ae78cb206b9 100644 --- a/src/sage/combinat/words/paths.py +++ b/src/sage/combinat/words/paths.py @@ -188,7 +188,6 @@ lazy_import("sage.plot.all", ["arrow", "line", "polygon", "point", "Graphics"]) from sage.modules.free_module_element import vector from sage.rings.integer_ring import ZZ -from sage.rings.number_field.number_field import QuadraticField from sage.rings.real_mpfr import RR from .word_datatypes import (WordDatatype_str, WordDatatype_list, @@ -202,6 +201,8 @@ WordDatatype_callable) from sage.matrix.constructor import vector_on_axis_rotation_matrix +lazy_import('sage.rings.number_field.number_field', 'QuadraticField') + ####################################################################### # # diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index e21ab9a22b4..54d8a96f637 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -778,9 +778,9 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): sage: words.CharacteristicSturmianWord(1/golden_ratio^2) # optional - sage.symbolic word: 0100101001001010010100100101001001010010... - sage: words.CharacteristicSturmianWord(4/5) + sage: words.CharacteristicSturmianWord(4/5) # optional - sage.rings.real_mpfr word: 11110 - sage: words.CharacteristicSturmianWord(5/14) + sage: words.CharacteristicSturmianWord(5/14) # optional - sage.rings.real_mpfr word: 01001001001001 sage: words.CharacteristicSturmianWord(pi - 3) # optional - sage.symbolic word: 0000001000000100000010000001000000100000... From 2e33391db782ec01029cbe384f5690b69443fea9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 12 Jul 2023 17:59:24 -0700 Subject: [PATCH 134/463] ./sage -fixdoctests --distribution sagemath-categories --only-tags src/sage/combinat --- src/sage/combinat/words/abstract_word.py | 10 +- src/sage/combinat/words/alphabet.py | 6 +- src/sage/combinat/words/finite_word.py | 96 ++++++++-------- src/sage/combinat/words/lyndon_word.py | 16 +-- src/sage/combinat/words/morphic.py | 36 +++--- src/sage/combinat/words/morphism.py | 126 ++++++++++----------- src/sage/combinat/words/paths.py | 84 +++++++------- src/sage/combinat/words/suffix_trees.py | 26 ++--- src/sage/combinat/words/word.py | 2 +- src/sage/combinat/words/word_char.pyx | 4 +- src/sage/combinat/words/word_generators.py | 88 +++++++------- src/sage/combinat/words/words.py | 44 +++---- 12 files changed, 269 insertions(+), 269 deletions(-) diff --git a/src/sage/combinat/words/abstract_word.py b/src/sage/combinat/words/abstract_word.py index 610dba1437a..eaf5cbd4975 100644 --- a/src/sage/combinat/words/abstract_word.py +++ b/src/sage/combinat/words/abstract_word.py @@ -1476,24 +1476,24 @@ def sum_digits(self, base=2, mod=None): Sum of digits modulo 2 of the prime numbers written in base 2:: - sage: Word(primes(1000)).sum_digits() # optional - sage.libs.pari + sage: Word(primes(1000)).sum_digits() # needs sage.libs.pari word: 1001110100111010111011001011101110011011... Sum of digits modulo 3 of the prime numbers written in base 3:: - sage: Word(primes(1000)).sum_digits(base=3) # optional - sage.libs.pari + sage: Word(primes(1000)).sum_digits(base=3) # needs sage.libs.pari word: 2100002020002221222121022221022122111022... - sage: Word(primes(1000)).sum_digits(base=3, mod=3) # optional - sage.libs.pari + sage: Word(primes(1000)).sum_digits(base=3, mod=3) # needs sage.libs.pari word: 2100002020002221222121022221022122111022... Sum of digits modulo 2 of the prime numbers written in base 3:: - sage: Word(primes(1000)).sum_digits(base=3, mod=2) # optional - sage.libs.pari + sage: Word(primes(1000)).sum_digits(base=3, mod=2) # needs sage.libs.pari word: 0111111111111111111111111111111111111111... Sum of digits modulo 7 of the prime numbers written in base 10:: - sage: Word(primes(1000)).sum_digits(base=10, mod=7) # optional - sage.libs.pari + sage: Word(primes(1000)).sum_digits(base=10, mod=7) # needs sage.libs.pari word: 2350241354435041006132432241353546006304... Negative entries:: diff --git a/src/sage/combinat/words/alphabet.py b/src/sage/combinat/words/alphabet.py index 3289ad5aa1a..1de8838df00 100644 --- a/src/sage/combinat/words/alphabet.py +++ b/src/sage/combinat/words/alphabet.py @@ -192,15 +192,15 @@ def build_alphabet(data=None, names=None, name=None): Traceback (most recent call last): ... ValueError: invalid value for names - sage: Alphabet(8, x) # optional - sage.symbolic + sage: Alphabet(8, x) # needs sage.symbolic Traceback (most recent call last): ... ValueError: invalid value for names - sage: Alphabet(name=x, names="punctuation") # optional - sage.symbolic + sage: Alphabet(name=x, names="punctuation") # needs sage.symbolic Traceback (most recent call last): ... ValueError: name cannot be specified with any other argument - sage: Alphabet(x) # optional - sage.symbolic + sage: Alphabet(x) # needs sage.symbolic Traceback (most recent call last): ... ValueError: unable to construct an alphabet from the given parameters diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 9fe6dc815c0..d43624c8ebe 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -136,7 +136,7 @@ sage: st = w.suffix_tree() sage: st Implicit Suffix Tree of the word: abaabbba - sage: st.show(word_labels=True) # optional - sage.plot + sage: st.show(word_labels=True) # needs sage.plot :: @@ -190,9 +190,9 @@ Rauzy graphs:: sage: f = words.FibonacciWord()[:30] - sage: f.rauzy_graph(4) # optional - sage.graphs + sage: f.rauzy_graph(4) # needs sage.graphs Looped digraph on 5 vertices - sage: f.reduced_rauzy_graph(4) # optional - sage.graphs + sage: f.reduced_rauzy_graph(4) # needs sage.graphs Looped multi-digraph on 2 vertices Left-special and bispecial factors:: @@ -1464,16 +1464,16 @@ def topological_entropy(self, n): sage: W = Words([0, 1]) sage: w = W([0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1]) - sage: t = w.topological_entropy(3); t # optional - sage.symbolic + sage: t = w.topological_entropy(3); t # needs sage.symbolic 1/3*log(7)/log(2) - sage: n(t) # optional - sage.symbolic + sage: n(t) # needs sage.symbolic 0.935784974019201 :: sage: w = words.ThueMorseWord()[:100] sage: topo = w.topological_entropy - sage: for i in range(0, 41, 5): # optional - sage.symbolic + sage: for i in range(0, 41, 5): # needs sage.symbolic ....: print("{} {}".format(i, n(topo(i), digits=5))) 0 1.0000 5 0.71699 @@ -1497,7 +1497,7 @@ def topological_entropy(self, n): sage: W = Words(range(20)) sage: w = W(range(20)) - sage: w.topological_entropy(3) # optional - sage.symbolic + sage: w.topological_entropy(3) # needs sage.symbolic 1/3*log(18)/log(20) """ d = self.parent().alphabet().cardinality() @@ -1525,12 +1525,12 @@ def rauzy_graph(self, n): sage: w = Word(range(10)); w word: 0123456789 - sage: g = w.rauzy_graph(3); g # optional - sage.graphs + sage: g = w.rauzy_graph(3); g # needs sage.graphs Looped digraph on 8 vertices sage: WordOptions(identifier='') - sage: g.vertices(sort=True) # optional - sage.graphs + sage: g.vertices(sort=True) # needs sage.graphs [012, 123, 234, 345, 456, 567, 678, 789] - sage: g.edges(sort=True) # optional - sage.graphs + sage: g.edges(sort=True) # needs sage.graphs [(012, 123, 3), (123, 234, 4), (234, 345, 5), @@ -1543,20 +1543,20 @@ def rauzy_graph(self, n): :: sage: f = words.FibonacciWord()[:100] - sage: f.rauzy_graph(8) # optional - sage.graphs + sage: f.rauzy_graph(8) # needs sage.graphs Looped digraph on 9 vertices :: sage: w = Word('1111111') - sage: g = w.rauzy_graph(3) # optional - sage.graphs - sage: g.edges(sort=True) # optional - sage.graphs + sage: g = w.rauzy_graph(3) # needs sage.graphs + sage: g.edges(sort=True) # needs sage.graphs [(word: 111, word: 111, word: 1)] :: sage: w = Word('111') - sage: for i in range(5): w.rauzy_graph(i) # optional - sage.graphs + sage: for i in range(5): w.rauzy_graph(i) # needs sage.graphs Looped multi-digraph on 1 vertex Looped digraph on 1 vertex Looped digraph on 1 vertex @@ -1567,9 +1567,9 @@ def rauzy_graph(self, n): sage: W = Words('abcde') sage: w = W('abc') - sage: w.rauzy_graph(0) # optional - sage.graphs + sage: w.rauzy_graph(0) # needs sage.graphs Looped multi-digraph on 1 vertex - sage: _.edges(sort=True) # optional - sage.graphs + sage: _.edges(sort=True) # needs sage.graphs [(word: , word: , word: a), (word: , word: , word: b), (word: , word: , word: c)] @@ -1636,21 +1636,21 @@ def reduced_rauzy_graph(self, n): sage: w = Word(range(10)); w word: 0123456789 - sage: g = w.reduced_rauzy_graph(3); g # optional - sage.graphs + sage: g = w.reduced_rauzy_graph(3); g # needs sage.graphs Looped multi-digraph on 2 vertices - sage: g.vertices(sort=True) # optional - sage.graphs + sage: g.vertices(sort=True) # needs sage.graphs [word: 012, word: 789] - sage: g.edges(sort=True) # optional - sage.graphs + sage: g.edges(sort=True) # needs sage.graphs [(word: 012, word: 789, word: 3456789)] For the Fibonacci word:: sage: f = words.FibonacciWord()[:100] - sage: g = f.reduced_rauzy_graph(8);g # optional - sage.graphs + sage: g = f.reduced_rauzy_graph(8);g # needs sage.graphs Looped multi-digraph on 2 vertices - sage: g.vertices(sort=True) # optional - sage.graphs + sage: g.vertices(sort=True) # needs sage.graphs [word: 01001010, word: 01010010] - sage: g.edges(sort=True) # optional - sage.graphs + sage: g.edges(sort=True) # needs sage.graphs [(word: 01001010, word: 01010010, word: 010), (word: 01010010, word: 01001010, word: 01010), (word: 01010010, word: 01001010, word: 10)] @@ -1659,14 +1659,14 @@ def reduced_rauzy_graph(self, n): sage: from itertools import cycle sage: w = Word(cycle('abcd'))[:100] - sage: g = w.reduced_rauzy_graph(3) # optional - sage.graphs - sage: g.edges(sort=True) # optional - sage.graphs + sage: g = w.reduced_rauzy_graph(3) # needs sage.graphs + sage: g.edges(sort=True) # needs sage.graphs [(word: abc, word: abc, word: dabc)] :: sage: w = Word('111') - sage: for i in range(5): w.reduced_rauzy_graph(i) # optional - sage.graphs + sage: for i in range(5): w.reduced_rauzy_graph(i) # needs sage.graphs Looped digraph on 1 vertex Looped digraph on 1 vertex Looped digraph on 1 vertex @@ -1676,12 +1676,12 @@ def reduced_rauzy_graph(self, n): For ultimately periodic words:: sage: sigma = WordMorphism('a->abcd,b->cd,c->cd,d->cd') - sage: w = sigma.fixed_point('a')[:100]; w # optional - sage.modules + sage: w = sigma.fixed_point('a')[:100]; w # needs sage.modules word: abcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd... - sage: g = w.reduced_rauzy_graph(5) # optional - sage.graphs - sage: g.vertices(sort=True) # optional - sage.graphs + sage: g = w.reduced_rauzy_graph(5) # needs sage.graphs + sage: g.vertices(sort=True) # needs sage.graphs [word: abcdc, word: cdcdc] - sage: g.edges(sort=True) # optional - sage.graphs + sage: g.edges(sort=True) # needs sage.graphs [(word: abcdc, word: cdcdc, word: dc), (word: cdcdc, word: cdcdc, word: dc)] AUTHOR: @@ -3099,9 +3099,9 @@ def defect(self, f=None): sage: sa = WordMorphism('a->ab,b->b') sage: sb = WordMorphism('a->a,b->ba') sage: w = (sa*sb*sb*sa*sa*sa*sb).fixed_point('a') - sage: w[:30].defect() # optional - sage.modules + sage: w[:30].defect() # needs sage.modules 0 - sage: w[110:140].defect() # optional - sage.modules + sage: w[110:140].defect() # needs sage.modules 0 It is even conjectured that the defect of an aperiodic word which is @@ -3109,11 +3109,11 @@ def defect(self, f=None): (see [BBGL2008]_):: sage: w = words.ThueMorseWord() - sage: w[:50].defect() # optional - sage.modules + sage: w[:50].defect() # needs sage.modules 12 - sage: w[:100].defect() # optional - sage.modules + sage: w[:100].defect() # needs sage.modules 16 - sage: w[:300].defect() # optional - sage.modules + sage: w[:300].defect() # needs sage.modules 52 For generalized defect with an involution different from the identity, @@ -5977,7 +5977,7 @@ def is_sturmian_factor(self): sage: words.LowerMechanicalWord(random(),alphabet='01')[:100].is_sturmian_factor() True - sage: words.CharacteristicSturmianWord(random())[:100].is_sturmian_factor() # optional - sage.rings.real_mpfr + sage: words.CharacteristicSturmianWord(random())[:100].is_sturmian_factor() # needs sage.rings.real_mpfr True :: @@ -6749,7 +6749,7 @@ def apply_permutation_to_positions(self, permutation): word: badc sage: w.apply_permutation_to_positions(Permutation([2,1,4,3])) word: badc - sage: w.apply_permutation_to_positions(PermutationGroupElement([2,1,4,3])) # optional - sage.groups + sage: w.apply_permutation_to_positions(PermutationGroupElement([2,1,4,3])) # needs sage.groups word: badc sage: Word([1,2,3,4]).apply_permutation_to_positions([3,4,2,1]) word: 3421 @@ -6779,7 +6779,7 @@ def apply_permutation_to_letters(self, permutation): word: dcba sage: w.apply_permutation_to_letters(Permutation(p)) word: badc - sage: w.apply_permutation_to_letters(PermutationGroupElement(p)) # optional - sage.groups + sage: w.apply_permutation_to_letters(PermutationGroupElement(p)) # needs sage.groups word: badc """ from sage.combinat.permutation import Permutation @@ -6824,18 +6824,18 @@ def colored_vector(self, x=0, y=0, width='default', height=1, cmap='hsv', thickn EXAMPLES:: - sage: Word(range(20)).colored_vector() # optional - sage.plot + sage: Word(range(20)).colored_vector() # needs sage.plot Graphics object consisting of 21 graphics primitives - sage: Word(range(100)).colored_vector(0,0,10,1) # optional - sage.plot + sage: Word(range(100)).colored_vector(0,0,10,1) # needs sage.plot Graphics object consisting of 101 graphics primitives - sage: Words(range(100))(range(10)).colored_vector() # optional - sage.plot + sage: Words(range(100))(range(10)).colored_vector() # needs sage.plot Graphics object consisting of 11 graphics primitives sage: w = Word('abbabaab') - sage: w.colored_vector() # optional - sage.plot + sage: w.colored_vector() # needs sage.plot Graphics object consisting of 9 graphics primitives - sage: w.colored_vector(cmap='autumn') # optional - sage.plot + sage: w.colored_vector(cmap='autumn') # needs sage.plot Graphics object consisting of 9 graphics primitives - sage: Word(range(20)).colored_vector(label='Rainbow') # optional - sage.plot + sage: Word(range(20)).colored_vector(label='Rainbow') # needs sage.plot Graphics object consisting of 23 graphics primitives When two words are defined under the same parent, same letters are @@ -6844,25 +6844,25 @@ def colored_vector(self, x=0, y=0, width='default', height=1, cmap='hsv', thickn sage: W = Words(range(20)) sage: w = W(range(20)) sage: y = W(range(10,20)) - sage: y.colored_vector(y=1, x=10) + w.colored_vector() # optional - sage.plot + sage: y.colored_vector(y=1, x=10) + w.colored_vector() # needs sage.plot Graphics object consisting of 32 graphics primitives TESTS: The empty word:: - sage: Word().colored_vector() # optional - sage.plot + sage: Word().colored_vector() # needs sage.plot Graphics object consisting of 1 graphics primitive - sage: Word().colored_vector(label='empty') # optional - sage.plot + sage: Word().colored_vector(label='empty') # needs sage.plot Graphics object consisting of 3 graphics primitives Unknown cmap:: - sage: Word(range(100)).colored_vector(cmap='jolies') # optional - sage.plot + sage: Word(range(100)).colored_vector(cmap='jolies') # needs sage.plot Traceback (most recent call last): ... RuntimeError: Color map jolies not known - sage: Word(range(100)).colored_vector(cmap='__doc__') # optional - sage.plot + sage: Word(range(100)).colored_vector(cmap='__doc__') # needs sage.plot Traceback (most recent call last): ... RuntimeError: Color map __doc__ not known diff --git a/src/sage/combinat/words/lyndon_word.py b/src/sage/combinat/words/lyndon_word.py index 575d68c58bc..4c978680380 100644 --- a/src/sage/combinat/words/lyndon_word.py +++ b/src/sage/combinat/words/lyndon_word.py @@ -64,9 +64,9 @@ def LyndonWords(e=None, k=None): word: 1112 sage: LW.last() word: 2333 - sage: LW.random_element() # random # optional - sage.libs.pari + sage: LW.random_element() # random # needs sage.libs.pari word: 1232 - sage: LW.cardinality() # optional - sage.libs.pari + sage: LW.cardinality() # needs sage.libs.pari 18 If e is a (weak) composition, then it returns the class of Lyndon @@ -277,9 +277,9 @@ def cardinality(self): sage: LyndonWords([]).cardinality() 0 - sage: LyndonWords([2,2]).cardinality() # optional - sage.libs.pari + sage: LyndonWords([2,2]).cardinality() # needs sage.libs.pari 1 - sage: LyndonWords([2,3,2]).cardinality() # optional - sage.libs.pari + sage: LyndonWords([2,3,2]).cardinality() # needs sage.libs.pari 30 Check to make sure that the count matches up with the number of @@ -287,7 +287,7 @@ def cardinality(self): sage: comps = [[],[2,2],[3,2,7],[4,2]] + Compositions(4).list() sage: lws = [LyndonWords(comp) for comp in comps] - sage: all(lw.cardinality() == len(lw.list()) for lw in lws) # optional - sage.libs.pari + sage: all(lw.cardinality() == len(lw.list()) for lw in lws) # needs sage.libs.pari True """ evaluation = self._e @@ -417,7 +417,7 @@ def __call__(self, *args, **kwds): Make sure that the correct length is checked (:trac:`30186`):: sage: L = LyndonWords(2, 4) - sage: _ = L(L.random_element()) # optional - sage.libs.pari + sage: _ = L(L.random_element()) # needs sage.libs.pari """ w = self._words(*args, **kwds) if kwds.get('check', True) and not w.is_lyndon(): @@ -443,7 +443,7 @@ def cardinality(self): """ TESTS:: - sage: [ LyndonWords(3,i).cardinality() for i in range(1, 11) ] # optional - sage.libs.pari + sage: [ LyndonWords(3,i).cardinality() for i in range(1, 11) ] # needs sage.libs.pari [3, 3, 8, 18, 48, 116, 312, 810, 2184, 5880] """ if self._k == 0: @@ -470,7 +470,7 @@ def __iter__(self): sage: sum(1 for lw in LyndonWords(1, 1000)) 0 - sage: list(LyndonWords(1, 1)) # optional - sage.libs.pari + sage: list(LyndonWords(1, 1)) # needs sage.libs.pari [word: 1] """ W = self._words._element_classes['list'] diff --git a/src/sage/combinat/words/morphic.py b/src/sage/combinat/words/morphic.py index 73d4973af85..0db7a8db6fe 100644 --- a/src/sage/combinat/words/morphic.py +++ b/src/sage/combinat/words/morphic.py @@ -23,7 +23,7 @@ abstract numeration system associated to the morphism and the starting letter, see chapter 3 of the book [BR2010b]_:: - sage: w[10000000] # optional - sage.modules + sage: w[10000000] # needs sage.modules 'b' """ @@ -58,7 +58,7 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): sage: w = m.fixed_point('a') sage: w word: abaababaabaababaababaabaababaabaababaaba... - sage: w[555:1000] # optional - sage.modules + sage: w[555:1000] # needs sage.modules word: abaababaabaababaababaabaababaabaababaaba... sage: w.length() +Infinity @@ -69,11 +69,11 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): sage: m.fixed_point('a') word: abcbabacababaabcbabaabccaabcbabaabcbabaa... sage: w = m.fixed_point('a') - sage: w[7] # optional - sage.modules + sage: w[7] # needs sage.modules 'c' - sage: w[2:7] # optional - sage.modules + sage: w[2:7] # needs sage.modules word: cbaba - sage: w[500:503] # optional - sage.modules + sage: w[500:503] # needs sage.modules word: caa When the morphic word is finite:: @@ -81,7 +81,7 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): sage: m = WordMorphism("a->ab,b->") sage: w = m.fixed_point("a"); w word: ab - sage: w[0] # optional - sage.modules + sage: w[0] # needs sage.modules 'a' sage: w.length() 2 @@ -93,7 +93,7 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): sage: from sage.combinat.words.morphic import WordDatatype_morphic sage: coding = {'a':'x', 'b':'y'} sage: w = WordDatatype_morphic(W, m, 'a', coding=coding) - sage: [w[i] for i in range(10)] # optional - sage.modules + sage: [w[i] for i in range(10)] # needs sage.modules ['x', 'y', 'x', 'x', 'y', 'x', 'y', 'x', 'x', 'y'] TESTS:: @@ -104,9 +104,9 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): sage: for _ in range(10000): _ = next(it) sage: L = [next(it) for _ in range(10)]; L ['d', 'd', 'd', 'c', 'd', 'd', 'd', 'c', 'b', 'a'] - sage: w[10000:10010] # optional - sage.modules + sage: w[10000:10010] # needs sage.modules word: dddcdddcba - sage: list(w[10000:10010]) == L # optional - sage.modules + sage: list(w[10000:10010]) == L # needs sage.modules True """ @@ -177,18 +177,18 @@ def representation(self, n): sage: m = WordMorphism('a->ab,b->a') sage: w = m.fixed_point('a') - sage: w.representation(5) # optional - sage.modules + sage: w.representation(5) # needs sage.modules [1, 0, 0, 0] When the morphic word is finite:: sage: m = WordMorphism("a->ab,b->,c->cdab,d->dcab") sage: w = m.fixed_point("a") - sage: w.representation(0) # optional - sage.modules + sage: w.representation(0) # needs sage.modules [] - sage: w.representation(1) # optional - sage.modules + sage: w.representation(1) # needs sage.modules [1] - sage: w.representation(2) # optional - sage.modules + sage: w.representation(2) # needs sage.modules Traceback (most recent call last): ... IndexError: index (=2) out of range, the fixed point is finite and has length 2 @@ -204,7 +204,7 @@ def representation(self, n): sage: w = WordDatatype_morphic(W, m, 'a') sage: type(w) - sage: w.representation(5) # optional - sage.modules + sage: w.representation(5) # needs sage.modules [1, 0, 0, 0] """ letters_to_int = {a:i for (i,a) in enumerate(self._alphabet)} @@ -255,11 +255,11 @@ def _func(self, key): sage: m = WordMorphism("a->ab,b->a") sage: w = m.fixed_point("a") - sage: w[0] # optional - sage.modules + sage: w[0] # needs sage.modules 'a' - sage: w[5] # optional - sage.modules + sage: w[5] # needs sage.modules 'a' - sage: w[10000] # optional - sage.modules + sage: w[10000] # needs sage.modules 'a' TESTS: @@ -271,7 +271,7 @@ def _func(self, key): sage: W = m.domain() sage: from sage.combinat.words.morphic import WordDatatype_morphic sage: w = WordDatatype_morphic(W, m, 'a') - sage: w._func(5) # optional - sage.modules + sage: w._func(5) # needs sage.modules 'a' """ diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index 5fc7d5e62b7..1576c5aca6c 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -66,7 +66,7 @@ Incidence matrix:: - sage: matrix(m) # optional - sage.modules + sage: matrix(m) # needs sage.modules [2 3 1] [1 3 0] [1 1 1] @@ -614,7 +614,7 @@ def __str__(self) -> str: :: sage: s = WordMorphism({1:[1,2],2:[1]}) - sage: s.dual_map() # optional - sage.modules + sage: s.dual_map() # needs sage.modules E_1^*(1->12, 2->1) TESTS:: @@ -1101,21 +1101,21 @@ def _matrix_(self, R=None): sage: fibo = WordMorphism('a->ab,b->a') sage: tm = WordMorphism('a->ab,b->ba') - sage: Mfibo = matrix(fibo); Mfibo # indirect doctest # optional - sage.modules + sage: Mfibo = matrix(fibo); Mfibo # indirect doctest # needs sage.modules [1 1] [1 0] - sage: Mtm = matrix(tm); Mtm # optional - sage.modules + sage: Mtm = matrix(tm); Mtm # needs sage.modules [1 1] [1 1] - sage: Mtm * Mfibo == matrix(tm*fibo) # indirect doctest # optional - sage.modules + sage: Mtm * Mfibo == matrix(tm*fibo) # indirect doctest # needs sage.modules True - sage: Mfibo * Mtm == matrix(fibo*tm) # indirect doctest # optional - sage.modules + sage: Mfibo * Mtm == matrix(fibo*tm) # indirect doctest # needs sage.modules True - sage: Mfibo.parent() # optional - sage.modules + sage: Mfibo.parent() # needs sage.modules Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: p = Mfibo.charpoly(); p # optional - sage.modules + sage: p = Mfibo.charpoly(); p # needs sage.modules x^2 - x - 1 - sage: p.roots(ring=RR, multiplicities=False) # optional - sage.modules + sage: p.roots(ring=RR, multiplicities=False) # needs sage.modules [-0.618033988749895, 1.61803398874989] """ if R is None: @@ -1136,12 +1136,12 @@ def incidence_matrix(self): EXAMPLES:: sage: m = WordMorphism('a->abc,b->a,c->c') - sage: m.incidence_matrix() # optional - sage.modules + sage: m.incidence_matrix() # needs sage.modules [1 1 0] [1 0 0] [1 0 1] sage: m = WordMorphism('a->abc,b->a,c->c,d->abbccccabca,e->abc') - sage: m.incidence_matrix() # optional - sage.modules + sage: m.incidence_matrix() # needs sage.modules [1 1 0 3 1] [1 0 0 3 1] [1 0 1 5 1] @@ -1204,10 +1204,10 @@ def is_endomorphism(self): We check that :trac:`8674` is fixed:: - sage: P = WordPaths('abcd') # optional - sage.modules - sage: m = WordMorphism('a->adab,b->ab,c->cbcd,d->cd', # optional - sage.modules + sage: P = WordPaths('abcd') # needs sage.modules + sage: m = WordMorphism('a->adab,b->ab,c->cbcd,d->cd', # needs sage.modules ....: domain=P, codomain=P) - sage: m.is_endomorphism() # optional - sage.modules + sage: m.is_endomorphism() # needs sage.modules True """ return self.codomain() == self.domain() @@ -1496,11 +1496,11 @@ def pisot_eigenvector_right(self): EXAMPLES:: sage: m = WordMorphism('a->aaaabbc,b->aaabbc,c->aabc') - sage: matrix(m) # optional - sage.modules + sage: matrix(m) # needs sage.modules [4 3 2] [2 2 1] [1 1 1] - sage: m.pisot_eigenvector_right() # optional - sage.modules sage.rings.number_field + sage: m.pisot_eigenvector_right() # needs sage.modules sage.rings.number_field (1, 0.5436890126920763?, 0.2955977425220848?) """ eig = self.incidence_matrix().eigenvectors_right() @@ -1526,11 +1526,11 @@ def pisot_eigenvector_left(self): EXAMPLES:: sage: m = WordMorphism('a->aaaabbc,b->aaabbc,c->aabc') - sage: matrix(m) # optional - sage.modules + sage: matrix(m) # needs sage.modules [4 3 2] [2 2 1] [1 1 1] - sage: m.pisot_eigenvector_left() # optional - sage.modules sage.rings.number_field + sage: m.pisot_eigenvector_left() # needs sage.modules sage.rings.number_field (1, 0.8392867552141611?, 0.5436890126920763?) """ eig = self.incidence_matrix().eigenvectors_left() @@ -1590,25 +1590,25 @@ def is_primitive(self): EXAMPLES:: sage: tm = WordMorphism('a->ab,b->ba') - sage: tm.is_primitive() # optional - sage.modules + sage: tm.is_primitive() # needs sage.modules True sage: fibo = WordMorphism('a->ab,b->a') - sage: fibo.is_primitive() # optional - sage.modules + sage: fibo.is_primitive() # needs sage.modules True sage: m = WordMorphism('a->bb,b->aa') - sage: m.is_primitive() # optional - sage.modules + sage: m.is_primitive() # needs sage.modules False sage: f = WordMorphism({0:[1],1:[0]}) - sage: f.is_primitive() # optional - sage.modules + sage: f.is_primitive() # needs sage.modules False :: sage: s = WordMorphism('a->b,b->c,c->ab') - sage: s.is_primitive() # optional - sage.modules + sage: s.is_primitive() # needs sage.modules True sage: s = WordMorphism('a->b,b->c,c->d,d->e,e->f,f->g,g->h,h->ab') - sage: s.is_primitive() # optional - sage.modules + sage: s.is_primitive() # needs sage.modules True TESTS:: @@ -1619,7 +1619,7 @@ def is_primitive(self): ... TypeError: self (=a->bb, b->aac) is not an endomorphism sage: m = WordMorphism('a->,b->', codomain=Words('ab')) - sage: m.is_primitive() # optional - sage.modules + sage: m.is_primitive() # needs sage.modules False sage: m = WordMorphism('a->,b->') sage: m.is_primitive() @@ -1683,9 +1683,9 @@ def is_prolongable(self, letter): :: - sage: n0, n1 = matrix(2,[1,1,1,0]), matrix(2,[2,1,1,0]) # optional - sage.modules - sage: n = {'a':n0, 'b':n1} # optional - sage.modules - sage: WordMorphism(n).is_prolongable(letter='a') # todo: not implemented # optional - sage.modules + sage: n0, n1 = matrix(2,[1,1,1,0]), matrix(2,[2,1,1,0]) # needs sage.modules + sage: n = {'a':n0, 'b':n1} # needs sage.modules + sage: WordMorphism(n).is_prolongable(letter='a') # not implemented, needs sage.modules Traceback (most recent call last): ... TypeError: codomain of self must be an instance of Words @@ -2076,11 +2076,11 @@ def language(self, n, u=None): The fibonacci morphism:: sage: s = WordMorphism({0: [0,1], 1: [0]}) - sage: sorted(s.language(3)) # optional - sage.modules + sage: sorted(s.language(3)) # needs sage.modules [word: 001, word: 010, word: 100, word: 101] - sage: len(s.language(1000)) # optional - sage.modules + sage: len(s.language(1000)) # needs sage.modules 1001 - sage: all(len(s.language(n)) == n+1 for n in range(100)) # optional - sage.modules + sage: all(len(s.language(n)) == n+1 for n in range(100)) # needs sage.modules True A growing but non-primitive example. The DOL-languages generated @@ -2089,24 +2089,24 @@ def language(self, n, u=None): sage: s = WordMorphism({0: [0,1], 1: [0], 2: [2,0,2]}) sage: u = s.fixed_point(0) - sage: A0 = u[:200].factor_set(5) # optional - sage.modules - sage: B0 = s.language(5, [0]) # optional - sage.modules - sage: set(A0) == B0 # optional - sage.modules + sage: A0 = u[:200].factor_set(5) # needs sage.modules + sage: B0 = s.language(5, [0]) # needs sage.modules + sage: set(A0) == B0 # needs sage.modules True sage: v = s.fixed_point(2) - sage: A2 = v[:200].factor_set(5) # optional - sage.modules - sage: B2 = s.language(5, [2]) # optional - sage.modules - sage: set(A2) == B2 # optional - sage.modules + sage: A2 = v[:200].factor_set(5) # needs sage.modules + sage: B2 = s.language(5, [2]) # needs sage.modules + sage: set(A2) == B2 # needs sage.modules True - sage: len(A0), len(A2) # optional - sage.modules + sage: len(A0), len(A2) # needs sage.modules (6, 20) The Chacon transformation (non-primitive):: sage: s = WordMorphism({0: [0,0,1,0], 1:[1]}) - sage: sorted(s.language(10)) # optional - sage.modules + sage: sorted(s.language(10)) # needs sage.modules [word: 0001000101, word: 0001010010, ... @@ -2461,7 +2461,7 @@ def dual_map(self, k=1): EXAMPLES:: sage: sigma = WordMorphism({1: [2], 2: [3], 3: [1,2]}) - sage: sigma.dual_map() # optional - sage.modules + sage: sigma.dual_map() # needs sage.modules E_1^*(1->2, 2->3, 3->12) :: @@ -2515,7 +2515,7 @@ def rauzy_fractal_projection(self, eig=None, prec=53): is:: sage: s = WordMorphism('1->12,2->13,3->1') - sage: s.rauzy_fractal_projection() # optional - sage.modules + sage: s.rauzy_fractal_projection() # needs sage.modules {'1': (1.00000000000000, 0.000000000000000), '2': (-1.41964337760708, -0.606290729207199), '3': (-0.771844506346038, 1.11514250803994)} @@ -2523,9 +2523,9 @@ def rauzy_fractal_projection(self, eig=None, prec=53): TESTS:: sage: t = WordMorphism('1->12,2->3,3->45,4->5,5->6,6->7,7->8,8->1') - sage: E = t.incidence_matrix().eigenvalues() # optional - sage.modules - sage: x = [x for x in E if -0.8 < x < -0.7][0] # optional - sage.modules - sage: t.rauzy_fractal_projection(prec=10) # optional - sage.modules + sage: E = t.incidence_matrix().eigenvalues() # needs sage.modules + sage: x = [x for x in E if -0.8 < x < -0.7][0] # needs sage.modules + sage: t.rauzy_fractal_projection(prec=10) # needs sage.modules {'1': (1.0, 0.00), '2': (-1.7, -0.56), '3': (0.79, 1.3), @@ -2534,7 +2534,7 @@ def rauzy_fractal_projection(self, eig=None, prec=53): '6': (0.79, 1.3), '7': (0.21, -1.3), '8': (-0.88, 0.74)} - sage: t.rauzy_fractal_projection(eig=x, prec=10) # optional - sage.modules + sage: t.rauzy_fractal_projection(eig=x, prec=10) # needs sage.modules {'1': (1.0, 0.00), '2': (-0.12, -0.74), '3': (-0.66, -0.56), @@ -2619,20 +2619,20 @@ def rauzy_fractal_points(self, n=None, exchange=False, eig=None, translate=None, and ``'3'`` are respectively:: sage: s = WordMorphism('1->12,2->13,3->1') - sage: D = s.rauzy_fractal_points(n=100) # optional - sage.modules - sage: len(D['1']) # optional - sage.modules + sage: D = s.rauzy_fractal_points(n=100) # needs sage.modules + sage: len(D['1']) # needs sage.modules 54 - sage: len(D['2']) # optional - sage.modules + sage: len(D['2']) # needs sage.modules 30 - sage: len(D['3']) # optional - sage.modules + sage: len(D['3']) # needs sage.modules 16 TESTS:: sage: s = WordMorphism('1->12,2->13,3->1') - sage: D = s.rauzy_fractal_points(n=100, exchange=True, # optional - sage.modules + sage: D = s.rauzy_fractal_points(n=100, exchange=True, # needs sage.modules ....: translate=[(3,1,-2), (5,-33,8)], prec=40) - sage: len(D['1']) # optional - sage.modules + sage: len(D['1']) # needs sage.modules 108 AUTHOR: @@ -2794,7 +2794,7 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, #. The Rauzy fractal of the Tribonacci substitution:: sage: s = WordMorphism('1->12,2->13,3->1') - sage: s.rauzy_fractal_plot() # long time # optional - sage.plot + sage: s.rauzy_fractal_plot() # long time # needs sage.plot Graphics object consisting of 3 graphics primitives #. The "Hokkaido" fractal. We tweak the plot using the plotting options @@ -2843,8 +2843,8 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, #. Different fractals can be obtained by choosing another (non-Pisot) eigenvalue:: sage: s = WordMorphism('1->12,2->3,3->45,4->5,5->6,6->7,7->8,8->1') - sage: E = s.incidence_matrix().eigenvalues() # optional - sage.modules - sage: x = [x for x in E if -0.8 < x < -0.7][0] # optional - sage.modules + sage: E = s.incidence_matrix().eigenvalues() # needs sage.modules + sage: x = [x for x in E if -0.8 < x < -0.7][0] # needs sage.modules sage: s.rauzy_fractal_plot() # not tested (> 1 second) sage: s.rauzy_fractal_plot(eig=x) # not tested (> 1 second) @@ -2887,8 +2887,8 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, :: sage: t = WordMorphism("a->aC,b->d,C->de,d->a,e->ab") # substitution found by Julien Bernat - sage: V = [vector((0,0,1,0,-1)), vector((0,0,1,-1,0))] # optional - sage.modules - sage: S = set(map(tuple, [i*V[0] + j*V[1] # optional - sage.modules + sage: V = [vector((0,0,1,0,-1)), vector((0,0,1,-1,0))] # needs sage.modules + sage: S = set(map(tuple, [i*V[0] + j*V[1] # needs sage.modules ....: for i in [-1,0,1] for j in [-1,0,1]])) sage: t.rauzy_fractal_plot(n=10000, # not tested (> 1 second) ....: translate=S, exchange=true) @@ -2911,7 +2911,7 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, TESTS:: sage: s = WordMorphism('a->ab,b->c,c->d,d->e,e->a') - sage: s.rauzy_fractal_plot(n=1000, colormap='Set1', # optional - sage.modules sage.plot + sage: s.rauzy_fractal_plot(n=1000, colormap='Set1', # needs sage.modules sage.plot ....: opacity={'a':0.5,'b':1,'c':0.7,'d':0,'e':0.2}, ....: plot_origin=(100,"black"), plot_basis=True, ....: point_size=2.5) @@ -3331,24 +3331,24 @@ def abelian_rotation_subspace(self): EXAMPLES:: - sage: WordMorphism('0->1,1->0').abelian_rotation_subspace() # optional - sage.modules + sage: WordMorphism('0->1,1->0').abelian_rotation_subspace() # needs sage.modules Vector space of degree 2 and dimension 2 over Rational Field Basis matrix: [1 0] [0 1] - sage: WordMorphism('0->01,1->10').abelian_rotation_subspace() # optional - sage.modules + sage: WordMorphism('0->01,1->10').abelian_rotation_subspace() # needs sage.modules Vector space of degree 2 and dimension 0 over Rational Field Basis matrix: [] - sage: WordMorphism('0->01,1->1').abelian_rotation_subspace() # optional - sage.modules + sage: WordMorphism('0->01,1->1').abelian_rotation_subspace() # needs sage.modules Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: [0 1] - sage: WordMorphism('1->122,2->211').abelian_rotation_subspace() # optional - sage.modules + sage: WordMorphism('1->122,2->211').abelian_rotation_subspace() # needs sage.modules Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: [ 1 -1] - sage: WordMorphism('0->1,1->102,2->3,3->4,4->2').abelian_rotation_subspace() # optional - sage.modules + sage: WordMorphism('0->1,1->102,2->3,3->4,4->2').abelian_rotation_subspace() # needs sage.modules Vector space of degree 5 and dimension 3 over Rational Field Basis matrix: [0 0 1 0 0] @@ -3357,7 +3357,7 @@ def abelian_rotation_subspace(self): The domain needs to be equal to the codomain:: - sage: WordMorphism('0->1,1->',codomain=Words('01')).abelian_rotation_subspace() # optional - sage.modules + sage: WordMorphism('0->1,1->',codomain=Words('01')).abelian_rotation_subspace() # needs sage.modules Vector space of degree 2 and dimension 0 over Rational Field Basis matrix: [] diff --git a/src/sage/combinat/words/paths.py b/src/sage/combinat/words/paths.py index ae78cb206b9..dcf37d8f456 100644 --- a/src/sage/combinat/words/paths.py +++ b/src/sage/combinat/words/paths.py @@ -45,7 +45,7 @@ [(0, 0), (1, 2), (-2, 6), (-1, 8), (-1, 5), (-1, 2), (-4, 6), (-3, 8)] sage: p.is_closed() False - sage: p.plot() # optional - sage.plot + sage: p.plot() # needs sage.plot Graphics object consisting of 3 graphics primitives To obtain a list of all the available word path specific functions, @@ -104,14 +104,14 @@ Finite Dyck paths sage: d = D('()()()(())'); d Path: ()()()(()) - sage: d.plot() # optional - sage.plot + sage: d.plot() # needs sage.plot Graphics object consisting of 3 graphics primitives :: sage: P = WordPaths('abcdef', steps='triangle_grid') sage: p = P('babaddefadabcadefaadfafabacdefa') - sage: p.plot() # optional - sage.plot + sage: p.plot() # needs sage.plot Graphics object consisting of 3 graphics primitives Vector steps may be in more than 2 dimensions:: @@ -120,7 +120,7 @@ sage: P = WordPaths(alphabet='abc', steps=d); P Word Paths over 3 steps sage: p = P('abcabcabcabcaabacabcababcacbabacacabcaccbcac') - sage: p.plot() # optional - sage.plot + sage: p.plot() # needs sage.plot Graphics3d Object :: @@ -137,7 +137,7 @@ sage: CubePaths = WordPaths('abcABC', steps='cube_grid'); CubePaths Word Paths on the cube grid - sage: CubePaths('abcabaabcabAAAAA').plot() # optional - sage.plot + sage: CubePaths('abcabaabcabAAAAA').plot() # needs sage.plot Graphics3d Object The input data may be a str, a list, a tuple, @@ -1366,15 +1366,15 @@ def plot_projection(self, v=None, letters=None, color=None, ring=None, To remove the axis, do like this:: - sage: r = w.plot_projection(v) # optional - sage.plot - sage: r.axes(False) # optional - sage.plot - sage: r # long time (2s) # optional - sage.plot + sage: r = w.plot_projection(v) # needs sage.plot + sage: r.axes(False) # needs sage.plot + sage: r # long time (2s) # needs sage.plot Graphics object consisting of 200 graphics primitives You can assign different colors to each letter:: sage: color = {'1': 'purple', '2': (.2,.3,.4), '3': 'magenta'} - sage: w.plot_projection(v, color=color) # long time (2s) # optional - sage.plot + sage: w.plot_projection(v, color=color) # long time (2s) # needs sage.plot Graphics object consisting of 200 graphics primitives The 3d-Rauzy fractal:: @@ -1384,14 +1384,14 @@ def plot_projection(self, v=None, letters=None, color=None, ring=None, sage: v = s.pisot_eigenvector_right() sage: P = WordPaths('1234',[(1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1)]) sage: w = P(D[:200]) - sage: w.plot_projection(v) # optional - sage.plot + sage: w.plot_projection(v) # needs sage.plot Graphics3d Object The dimension of vector space of the parent must be 3 or 4:: sage: P = WordPaths('ab', [(1, 0), (0, 1)]) sage: p = P('aabbabbab') - sage: p.plot_projection() # optional - sage.plot + sage: p.plot_projection() # needs sage.plot Traceback (most recent call last): ... TypeError: The dimension of the vector space (=2) must be 3 or 4 @@ -1445,7 +1445,7 @@ def projected_path(self, v=None, ring=None): sage: p = w.projected_path(v) sage: p Path: 1213121121312121312112131213121121312121... - sage: p[:20].plot() # optional - sage.plot + sage: p[:20].plot() # needs sage.plot Graphics object consisting of 3 graphics primitives The ``ring`` argument allows to change the precision of the @@ -1531,42 +1531,42 @@ def plot(self, pathoptions=dict(rgbcolor='red',thickness=3), A non closed path on the square grid:: sage: P = WordPaths('abAB') - sage: P('abababAABAB').plot() # optional - sage.plot + sage: P('abababAABAB').plot() # needs sage.plot Graphics object consisting of 3 graphics primitives A closed path on the square grid:: - sage: P('abababAABABB').plot() # optional - sage.plot + sage: P('abababAABABB').plot() # needs sage.plot Graphics object consisting of 4 graphics primitives A Dyck path:: sage: P = WordPaths('()', steps='dyck') - sage: P('()()()((()))').plot() # optional - sage.plot + sage: P('()()()((()))').plot() # needs sage.plot Graphics object consisting of 3 graphics primitives A path in the triangle grid:: sage: P = WordPaths('abcdef', steps='triangle_grid') - sage: P('abcdedededefab').plot() # optional - sage.plot + sage: P('abcdedededefab').plot() # needs sage.plot Graphics object consisting of 3 graphics primitives A polygon of length 220 that tiles the plane in two ways:: sage: P = WordPaths('abAB') - sage: P('aBababAbabaBaBABaBabaBaBABAbABABaBabaBaBABaBababAbabaBaBABaBabaBaBABAbABABaBABAbAbabAbABABaBABAbABABaBabaBaBABAbABABaBABAbAbabAbABAbAbabaBababAbABAbAbabAbABABaBABAbAbabAbABAbAbabaBababAbabaBaBABaBababAbabaBababAbABAbAbab').plot() # optional - sage.plot + sage: P('aBababAbabaBaBABaBabaBaBABAbABABaBabaBaBABaBababAbabaBaBABaBabaBaBABAbABABaBABAbAbabAbABABaBABAbABABaBabaBaBABAbABABaBABAbAbabAbABAbAbabaBababAbABAbAbabAbABABaBABAbAbabAbABAbAbabaBababAbabaBaBABaBababAbabaBababAbABAbAbab').plot() # needs sage.plot Graphics object consisting of 4 graphics primitives With gridlines:: - sage: P('ababababab').plot(gridlines=True) # optional - sage.plot + sage: P('ababababab').plot(gridlines=True) # needs sage.plot TESTS:: sage: P = WordPaths('abAB') - sage: P().plot() # optional - sage.plot + sage: P().plot() # needs sage.plot Graphics object consisting of 3 graphics primitives - sage: sum(map(plot,map(P,['a','A','b','B']))) # optional - sage.plot + sage: sum(map(plot,map(P,['a','A','b','B']))) # needs sage.plot Graphics object consisting of 12 graphics primitives """ G = Graphics() @@ -1615,44 +1615,44 @@ def animate(self): sage: P = WordPaths('abAB') sage: p = P('aaababbb') - sage: a = p.animate(); print(a) # optional - sage.plot + sage: a = p.animate(); print(a) # needs sage.plot Animation with 9 frames - sage: show(a) # long time # optional -- ImageMagick sage.plot - sage: show(a, delay=35, iterations=3) # long time # optional -- ImageMagick sage.plot + sage: show(a) # long time, optional - imagemagick, needs sage.plot + sage: show(a, delay=35, iterations=3) # long time, optional - imagemagick, needs sage.plot :: sage: P = WordPaths('abcdef',steps='triangle') sage: p = P('abcdef') - sage: a = p.animate(); print(a) # optional - sage.plot + sage: a = p.animate(); print(a) # needs sage.plot Animation with 8 frames - sage: show(a) # long time # optional -- ImageMagick sage.plot + sage: show(a) # long time, optional - imagemagick, needs sage.plot If the path is closed, the plain polygon is added at the end of the animation:: sage: P = WordPaths('abAB') sage: p = P('ababAbABABaB') - sage: a = p.animate(); print(a) # optional - sage.plot + sage: a = p.animate(); print(a) # needs sage.plot Animation with 14 frames - sage: show(a) # long time # optional -- ImageMagick sage.plot + sage: show(a) # long time, optional - imagemagick, needs sage.plot Another example illustrating a Fibonacci tile:: sage: w = words.fibonacci_tile(2) - sage: a = w.animate(); print(a) # optional - sage.plot + sage: a = w.animate(); print(a) # needs sage.plot Animation with 54 frames - sage: show(a) # long time # optional -- ImageMagick sage.plot + sage: show(a) # long time, optional - imagemagick, needs sage.plot The first 4 Fibonacci tiles in an animation:: - sage: a = words.fibonacci_tile(0).animate() # optional - sage.plot - sage: b = words.fibonacci_tile(1).animate() # optional - sage.plot - sage: c = words.fibonacci_tile(2).animate() # optional - sage.plot - sage: d = words.fibonacci_tile(3).animate() # optional - sage.plot - sage: print(a*b*c*d) # optional - sage.plot + sage: a = words.fibonacci_tile(0).animate() # needs sage.plot + sage: b = words.fibonacci_tile(1).animate() # needs sage.plot + sage: c = words.fibonacci_tile(2).animate() # needs sage.plot + sage: d = words.fibonacci_tile(3).animate() # needs sage.plot + sage: print(a*b*c*d) # needs sage.plot Animation with 296 frames - sage: show(a*b*c*d) # long time # optional -- ImageMagick sage.plot + sage: show(a*b*c*d) # long time, optional - imagemagick, needs sage.plot .. note:: @@ -1714,17 +1714,17 @@ def plot_directive_vector(self, options=dict(rgbcolor='blue')): Word Paths on the square grid sage: p = P('aaaccaccacacacaccccccbbdd'); p Path: aaaccaccacacacaccccccbbdd - sage: R = p.plot() + p.plot_directive_vector() # optional - sage.plot - sage: R.axes(False) # optional - sage.plot - sage: R.set_aspect_ratio(1) # optional - sage.plot - sage: R.plot() # optional - sage.plot + sage: R = p.plot() + p.plot_directive_vector() # needs sage.plot + sage: R.axes(False) # needs sage.plot + sage: R.set_aspect_ratio(1) # needs sage.plot + sage: R.plot() # needs sage.plot Graphics object consisting of 4 graphics primitives TESTS: A closed path:: - sage: P('acbd').plot_directive_vector() # optional - sage.plot + sage: P('acbd').plot_directive_vector() # needs sage.plot Graphics object consisting of 1 graphics primitive """ start = self.start_point() @@ -2021,12 +2021,12 @@ def plot(self, pathoptions=dict(rgbcolor='red',arrow_head=True,thickness=3), Word Paths over 2 steps sage: p = P('ababab'); p Path: ababab - sage: p.plot() # optional - sage.plot + sage: p.plot() # needs sage.plot Graphics3d Object sage: P = WordPaths('abcABC', steps='cube_grid') sage: p = P('abcabcAABBC') - sage: p.plot() # optional - sage.plot + sage: p.plot() # needs sage.plot Graphics3d Object """ diff --git a/src/sage/combinat/words/suffix_trees.py b/src/sage/combinat/words/suffix_trees.py index 59b3acb57d3..8375bde1a8a 100644 --- a/src/sage/combinat/words/suffix_trees.py +++ b/src/sage/combinat/words/suffix_trees.py @@ -440,9 +440,9 @@ def to_digraph(self): sage: from sage.combinat.words.suffix_trees import SuffixTrie sage: w = Words("cao")("cac") sage: t = SuffixTrie(w) - sage: d = t.to_digraph(); d # optional - sage.graphs + sage: d = t.to_digraph(); d # needs sage.graphs Digraph on 6 vertices - sage: d.adjacency_matrix() # optional - sage.graphs sage.modules + sage: d.adjacency_matrix() # needs sage.graphs sage.modules [0 1 0 1 0 0] [0 0 1 0 0 0] [0 0 0 0 1 0] @@ -464,13 +464,13 @@ def plot(self, layout='tree', tree_root=0, tree_orientation='up', EXAMPLES:: sage: from sage.combinat.words.suffix_trees import SuffixTrie - sage: SuffixTrie(Word("cacao")).plot() # optional - sage.plot + sage: SuffixTrie(Word("cacao")).plot() # needs sage.plot Graphics object consisting of 38 graphics primitives TESTS:: sage: from sage.combinat.words.suffix_trees import SuffixTrie - sage: type(SuffixTrie(Word("cacao")).plot()) # optional - sage.plot + sage: type(SuffixTrie(Word("cacao")).plot()) # needs sage.plot """ tree = self.to_digraph() @@ -494,7 +494,7 @@ def show(self, *args, **kwds): sage: from sage.combinat.words.suffix_trees import SuffixTrie sage: w = Words("cao")("cac") sage: t = SuffixTrie(w) - sage: t.show() # optional - sage.plot + sage: t.show() # needs sage.plot """ self.plot(*args, **kwds).show() return @@ -832,7 +832,7 @@ def to_digraph(self, word_labels=False): sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree sage: W = Words([0,1,2]) sage: t = ImplicitSuffixTree(W([0,1,0,1,2])) - sage: t.to_digraph() # optional - sage.graphs + sage: t.to_digraph() # needs sage.graphs Digraph on 8 vertices """ if not self._letters: @@ -868,17 +868,17 @@ def plot(self, word_labels=False, layout='tree', tree_root=0, EXAMPLES:: sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree - sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=True) # optional - sage.graphs sage.plot + sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=True) # needs sage.graphs sage.plot Graphics object consisting of 23 graphics primitives - sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=False) # optional - sage.graphs sage.plot + sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=False) # needs sage.graphs sage.plot Graphics object consisting of 23 graphics primitives TESTS:: sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree - sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=True)) # optional - sage.graphs sage.plot + sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=True)) # needs sage.graphs sage.plot - sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=False)) # optional - sage.graphs sage.plot + sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=False)) # needs sage.graphs sage.plot """ tree = self.to_digraph(word_labels=word_labels) @@ -907,8 +907,8 @@ def show(self, word_labels=None, *args, **kwds): sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree sage: w = Words("cao")("cacao") sage: t = ImplicitSuffixTree(w) - sage: t.show(word_labels=True) # optional - sage.plot - sage: t.show(word_labels=False) # optional - sage.plot + sage: t.show(word_labels=True) # needs sage.plot + sage: t.show(word_labels=False) # needs sage.plot """ self.plot(word_labels=word_labels, *args, **kwds).show() return @@ -1509,7 +1509,7 @@ def uncompactify(self): sage: abbab = Words("ab")("abbab") sage: s = SuffixTrie(abbab) sage: t = ImplicitSuffixTree(abbab) - sage: t.uncompactify().is_isomorphic(s.to_digraph()) # optional - sage.graphs + sage: t.uncompactify().is_isomorphic(s.to_digraph()) # needs sage.graphs True """ tree = self.to_digraph(word_labels=True) diff --git a/src/sage/combinat/words/word.py b/src/sage/combinat/words/word.py index 320bc3d9f0c..132195589e9 100644 --- a/src/sage/combinat/words/word.py +++ b/src/sage/combinat/words/word.py @@ -265,7 +265,7 @@ class FiniteWord_char(WordDatatype_char, FiniteWord_class): sage: len(w.factor_set()) 127 - sage: w.rauzy_graph(5) # optional - sage.graphs + sage: w.rauzy_graph(5) # needs sage.graphs Looped digraph on 9 vertices sage: u = W([1,2,3]) diff --git a/src/sage/combinat/words/word_char.pyx b/src/sage/combinat/words/word_char.pyx index 31f642ffc65..1b68cd293ce 100644 --- a/src/sage/combinat/words/word_char.pyx +++ b/src/sage/combinat/words/word_char.pyx @@ -716,9 +716,9 @@ cdef class WordDatatype_char(WordDatatype): sage: W = Words([0,1]) sage: w = words.FibonacciWord() sage: w = W(list(w[:5000])) - sage: L = [[len(w[n:].longest_common_prefix(w[n+fibonacci(i):])) # optional - sage.libs.pari + sage: L = [[len(w[n:].longest_common_prefix(w[n+fibonacci(i):])) # needs sage.libs.pari ....: for i in range(5,15)] for n in range(1,1000)] - sage: for n,l in enumerate(L): # optional - sage.libs.pari + sage: for n,l in enumerate(L): # needs sage.libs.pari ....: if l.count(0) > 4: ....: print("{} {}".format(n+1,l)) 375 [0, 13, 0, 34, 0, 89, 0, 233, 0, 233] diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 54d8a96f637..681ce39e26e 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -243,10 +243,10 @@ def markoff_number(self): sage: w0 = words.LowerChristoffelWord(4,7) sage: w1, w2 = w0.standard_factorization() - sage: (m0,m1,m2) = (w.markoff_number() for w in (w0,w1,w2)) # optional - sage.modules - sage: (m0,m1,m2) # optional - sage.modules + sage: (m0,m1,m2) = (w.markoff_number() for w in (w0,w1,w2)) # needs sage.modules + sage: (m0,m1,m2) # needs sage.modules (294685, 13, 7561) - sage: m0**2 + m1**2 + m2**2 == 3*m0*m1*m2 # optional - sage.modules + sage: m0**2 + m1**2 + m2**2 == 3*m0*m1*m2 # needs sage.modules True """ from sage.matrix.constructor import matrix @@ -542,9 +542,9 @@ def FibonacciWord(self, alphabet=(0, 1), construction_method="recursive"): :: - sage: words.FibonacciWord([0,1], 'function') # optional - sage.symbolic + sage: words.FibonacciWord([0,1], 'function') # needs sage.symbolic word: 0100101001001010010100100101001001010010... - sage: words.FibonacciWord('ab', 'function') # optional - sage.symbolic + sage: words.FibonacciWord('ab', 'function') # needs sage.symbolic word: abaababaabaababaababaabaababaabaababaaba... TESTS:: @@ -642,7 +642,7 @@ def FixedPointOfMorphism(self, morphism, first_letter): sage: tm = words.FixedPointOfMorphism(mu,0); tm word: 0110100110010110100101100110100110010110... sage: TM = words.ThueMorseWord() - sage: tm[:1000] == TM[:1000] # optional - sage.modules + sage: tm[:1000] == TM[:1000] # needs sage.modules True :: @@ -652,7 +652,7 @@ def FixedPointOfMorphism(self, morphism, first_letter): word: 0100101001001010010100100101001001010010... sage: F = words.FibonacciWord(); F word: 0100101001001010010100100101001001010010... - sage: f[:1000] == F[:1000] # optional - sage.modules + sage: f[:1000] == F[:1000] # needs sage.modules True :: @@ -776,13 +776,13 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): From real slope:: - sage: words.CharacteristicSturmianWord(1/golden_ratio^2) # optional - sage.symbolic + sage: words.CharacteristicSturmianWord(1/golden_ratio^2) # needs sage.symbolic word: 0100101001001010010100100101001001010010... - sage: words.CharacteristicSturmianWord(4/5) # optional - sage.rings.real_mpfr + sage: words.CharacteristicSturmianWord(4/5) # needs sage.rings.real_mpfr word: 11110 - sage: words.CharacteristicSturmianWord(5/14) # optional - sage.rings.real_mpfr + sage: words.CharacteristicSturmianWord(5/14) # needs sage.rings.real_mpfr word: 01001001001001 - sage: words.CharacteristicSturmianWord(pi - 3) # optional - sage.symbolic + sage: words.CharacteristicSturmianWord(pi - 3) # needs sage.symbolic word: 0000001000000100000010000001000000100000... From an iterator of the continued fraction expansion of a real:: @@ -791,21 +791,21 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): ....: yield 0 ....: yield 2 ....: while True: yield 1 - sage: F = words.CharacteristicSturmianWord(cf()); F + sage: F = words.CharacteristicSturmianWord(cf()); F # needs sage.rings.real_mpfr word: 0100101001001010010100100101001001010010... sage: Fib = words.FibonacciWord(); Fib word: 0100101001001010010100100101001001010010... - sage: F[:10000] == Fib[:10000] + sage: F[:10000] == Fib[:10000] # needs sage.rings.real_mpfr True The alphabet may be specified:: - sage: words.CharacteristicSturmianWord(cf(), 'rs') + sage: words.CharacteristicSturmianWord(cf(), 'rs') # needs sage.rings.real_mpfr word: rsrrsrsrrsrrsrsrrsrsrrsrrsrsrrsrrsrsrrsr... The characteristic sturmian word of slope `(\sqrt{3}-1)/2`:: - sage: words.CharacteristicSturmianWord((sqrt(3)-1)/2) # optional - sage.symbolic + sage: words.CharacteristicSturmianWord((sqrt(3)-1)/2) # needs sage.symbolic word: 0100100101001001001010010010010100100101... The same word defined from the continued fraction expansion of @@ -848,17 +848,17 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): :: - sage: words.CharacteristicSturmianWord(1/golden_ratio^2) # optional - sage.symbolic + sage: words.CharacteristicSturmianWord(1/golden_ratio^2) # needs sage.symbolic word: 0100101001001010010100100101001001010010... - sage: _.length() # optional - sage.symbolic + sage: _.length() # needs sage.symbolic +Infinity :: - sage: a = words.LowerMechanicalWord(1/pi)[1:] # optional - sage.symbolic - sage: b = words.UpperMechanicalWord(1/pi)[1:] # optional - sage.symbolic - sage: c = words.CharacteristicSturmianWord(1/pi) # optional - sage.symbolic - sage: n = 500; a[:n] == b[:n] == c[:n] # optional - sage.symbolic + sage: a = words.LowerMechanicalWord(1/pi)[1:] # needs sage.symbolic + sage: b = words.UpperMechanicalWord(1/pi)[1:] # needs sage.symbolic + sage: c = words.CharacteristicSturmianWord(1/pi) # needs sage.symbolic + sage: n = 500; a[:n] == b[:n] == c[:n] # needs sage.symbolic True :: @@ -929,19 +929,19 @@ def _CharacteristicSturmianWord_LetterIterator(self, cf, alphabet=(0,1)): EXAMPLES:: - sage: continued_fraction(1/golden_ratio^2)[:8] # optional - sage.symbolic + sage: continued_fraction(1/golden_ratio^2)[:8] # needs sage.symbolic [0; 2, 1, 1, 1, 1, 2] - sage: cf = iter(_) # optional - sage.symbolic - sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) # optional - sage.symbolic + sage: cf = iter(_) # needs sage.symbolic + sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) # needs sage.symbolic word: 0100101001001010010100100101001010 :: - sage: alpha = (sqrt(3)-1)/2 # optional - sage.symbolic - sage: continued_fraction(alpha)[:10] # optional - sage.symbolic + sage: alpha = (sqrt(3)-1)/2 # needs sage.symbolic + sage: continued_fraction(alpha)[:10] # needs sage.symbolic [0; 2, 1, 2, 1, 2, 1, 2, 1, 2] - sage: cf = iter(_) # optional - sage.symbolic - sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) # optional - sage.symbolic + sage: cf = iter(_) # needs sage.symbolic + sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) # needs sage.symbolic word: 0100100101001001001010010010010100100101... """ try: @@ -1135,23 +1135,23 @@ def LowerMechanicalWord(self, alpha, rho=0, alphabet=None): EXAMPLES:: - sage: words.LowerMechanicalWord(1/golden_ratio^2) # optional - sage.symbolic + sage: words.LowerMechanicalWord(1/golden_ratio^2) # needs sage.symbolic word: 0010010100100101001010010010100100101001... - sage: words.LowerMechanicalWord(1/5) # optional - sage.symbolic + sage: words.LowerMechanicalWord(1/5) # needs sage.symbolic word: 0000100001000010000100001000010000100001... - sage: words.LowerMechanicalWord(1/pi) # optional - sage.symbolic + sage: words.LowerMechanicalWord(1/pi) # needs sage.symbolic word: 0001001001001001001001000100100100100100... TESTS:: - sage: m = words.LowerMechanicalWord(1/golden_ratio^2)[1:] # optional - sage.symbolic - sage: s = words.CharacteristicSturmianWord(1/golden_ratio^2) # optional - sage.symbolic - sage: m[:500] == s[:500] # optional - sage.symbolic + sage: m = words.LowerMechanicalWord(1/golden_ratio^2)[1:] # needs sage.symbolic + sage: s = words.CharacteristicSturmianWord(1/golden_ratio^2) # needs sage.symbolic + sage: m[:500] == s[:500] # needs sage.symbolic True Check that this returns a word in an alphabet (:trac:`10054`):: - sage: words.UpperMechanicalWord(1/golden_ratio^2).parent() # optional - sage.symbolic + sage: words.UpperMechanicalWord(1/golden_ratio^2).parent() # needs sage.symbolic Infinite words over {0, 1} """ if not 0 <= alpha <= 1: @@ -1195,23 +1195,23 @@ def UpperMechanicalWord(self, alpha, rho=0, alphabet=None): EXAMPLES:: - sage: words.UpperMechanicalWord(1/golden_ratio^2) # optional - sage.symbolic + sage: words.UpperMechanicalWord(1/golden_ratio^2) # needs sage.symbolic word: 1010010100100101001010010010100100101001... - sage: words.UpperMechanicalWord(1/5) # optional - sage.symbolic + sage: words.UpperMechanicalWord(1/5) # needs sage.symbolic word: 1000010000100001000010000100001000010000... - sage: words.UpperMechanicalWord(1/pi) # optional - sage.symbolic + sage: words.UpperMechanicalWord(1/pi) # needs sage.symbolic word: 1001001001001001001001000100100100100100... TESTS:: - sage: m = words.UpperMechanicalWord(1/golden_ratio^2)[1:] # optional - sage.symbolic - sage: s = words.CharacteristicSturmianWord(1/golden_ratio^2) # optional - sage.symbolic - sage: m[:500] == s[:500] # optional - sage.symbolic + sage: m = words.UpperMechanicalWord(1/golden_ratio^2)[1:] # needs sage.symbolic + sage: s = words.CharacteristicSturmianWord(1/golden_ratio^2) # needs sage.symbolic + sage: m[:500] == s[:500] # needs sage.symbolic True Check that this returns a word in an alphabet (:trac:`10054`):: - sage: words.UpperMechanicalWord(1/golden_ratio^2).parent() # optional - sage.symbolic + sage: words.UpperMechanicalWord(1/golden_ratio^2).parent() # needs sage.symbolic Infinite words over {0, 1} """ if not 0 <= alpha <= 1: @@ -1522,7 +1522,7 @@ def fibonacci_tile(self, n): EXAMPLES:: - sage: for i in range(3): words.fibonacci_tile(i) # optional - sage.modules + sage: for i in range(3): words.fibonacci_tile(i) # needs sage.modules Path: 3210 Path: 323030101212 Path: 3230301030323212323032321210121232121010... @@ -1540,7 +1540,7 @@ def dual_fibonacci_tile(self, n): EXAMPLES:: - sage: for i in range(4): words.dual_fibonacci_tile(i) # optional - sage.modules + sage: for i in range(4): words.dual_fibonacci_tile(i) # needs sage.modules Path: 3210 Path: 32123032301030121012 Path: 3212303230103230321232101232123032123210... diff --git a/src/sage/combinat/words/words.py b/src/sage/combinat/words/words.py index 8c23a452bc7..0149df17598 100644 --- a/src/sage/combinat/words/words.py +++ b/src/sage/combinat/words/words.py @@ -705,9 +705,9 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr Construction of a word path from a finite word:: sage: W = FiniteWords('abcd') - sage: P = WordPaths('abcd') # optional - sage.modules + sage: P = WordPaths('abcd') # needs sage.modules sage: w = W('aaab') - sage: P(w) # optional - sage.modules + sage: P(w) # needs sage.modules Path: aaab Construction of a word path from a Christoffel word:: @@ -715,8 +715,8 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr sage: w = words.ChristoffelWord(5,8) sage: w word: 0010010100101 - sage: P = WordPaths([0,1,2,3]) # optional - sage.modules - sage: P(w) # optional - sage.modules + sage: P = WordPaths([0,1,2,3]) # needs sage.modules + sage: P(w) # needs sage.modules Path: 0010010100101 Construction of a word represented by a list from a word @@ -744,19 +744,19 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr sage: w = words.FibonacciWord() sage: f = w[:100] - sage: P = WordPaths([0,1,2,3]) # optional - sage.modules - sage: p = P(f); p # optional - sage.modules + sage: P = WordPaths([0,1,2,3]) # needs sage.modules + sage: p = P(f); p # needs sage.modules Path: 0100101001001010010100100101001001010010... - sage: p.length() # optional - sage.modules + sage: p.length() # needs sage.modules 100 Creation of a word path from a FiniteWord_callable:: sage: g = W(lambda n:n%2, length = 100) - sage: P = WordPaths([0,1,2,3]) # optional - sage.modules - sage: p = P(g); p # optional - sage.modules + sage: P = WordPaths([0,1,2,3]) # needs sage.modules + sage: p = P(g); p # needs sage.modules Path: 0101010101010101010101010101010101010101... - sage: p.length() # optional - sage.modules + sage: p.length() # needs sage.modules 100 Creation of a word from a pickled function:: @@ -1017,7 +1017,7 @@ def random_element(self, length=None, *args, **kwds): TESTS:: - sage: _ = FiniteWords(GF(5)).random_element() # optional - sage.rings.finite_rings + sage: _ = FiniteWords(GF(5)).random_element() # needs sage.rings.finite_rings """ if length is None: length = ZZ.random_element(0, 10) @@ -1928,9 +1928,9 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr Construction of a word path from a finite word:: sage: W = Words('abcd') - sage: P = WordPaths('abcd') # optional - sage.modules + sage: P = WordPaths('abcd') # needs sage.modules sage: w = W('aaab') - sage: P(w) # optional - sage.modules + sage: P(w) # needs sage.modules Path: aaab Construction of a word path from a Christoffel word:: @@ -1938,8 +1938,8 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr sage: w = words.ChristoffelWord(5,8) sage: w word: 0010010100101 - sage: P = WordPaths([0,1,2,3]) # optional - sage.modules - sage: P(w) # optional - sage.modules + sage: P = WordPaths([0,1,2,3]) # needs sage.modules + sage: P(w) # needs sage.modules Path: 0010010100101 Construction of a word represented by a list from a word @@ -1967,19 +1967,19 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr sage: w = words.FibonacciWord() sage: f = w[:100] - sage: P = WordPaths([0,1,2,3]) # optional - sage.modules - sage: p = P(f); p # optional - sage.modules + sage: P = WordPaths([0,1,2,3]) # needs sage.modules + sage: p = P(f); p # needs sage.modules Path: 0100101001001010010100100101001001010010... - sage: p.length() # optional - sage.modules + sage: p.length() # needs sage.modules 100 Creation of a word path from a :class:`FiniteWord_callable`:: sage: g = Word(lambda n: n%2, length=100) - sage: P = WordPaths([0,1,2,3]) # optional - sage.modules - sage: p = P(g); p # optional - sage.modules + sage: P = WordPaths([0,1,2,3]) # needs sage.modules + sage: p = P(g); p # needs sage.modules Path: 0101010101010101010101010101010101010101... - sage: p.length() # optional - sage.modules + sage: p.length() # needs sage.modules 100 Creation of a word from a pickled function:: @@ -2216,7 +2216,7 @@ def random_element(self, *args, **kwds): TESTS:: - sage: _ = Words(GF(5),4).random_element() # optional - sage.rings.finite_rings + sage: _ = Words(GF(5),4).random_element() # needs sage.rings.finite_rings Check that :trac:`18283` is fixed:: From 6613b17ad045b129a515a0fbd92cdf082698d3db Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 13 Jul 2023 23:26:21 -0700 Subject: [PATCH 135/463] sage.combinat.words: Update # needs --- src/sage/combinat/words/morphism.py | 11 ++++++----- src/sage/combinat/words/paths.py | 13 +++++++------ src/sage/combinat/words/word_generators.py | 18 ++++++++++-------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index 1576c5aca6c..de7f00902ef 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -3331,24 +3331,25 @@ def abelian_rotation_subspace(self): EXAMPLES:: - sage: WordMorphism('0->1,1->0').abelian_rotation_subspace() # needs sage.modules + sage: # needs sage.modules + sage: WordMorphism('0->1,1->0').abelian_rotation_subspace() Vector space of degree 2 and dimension 2 over Rational Field Basis matrix: [1 0] [0 1] - sage: WordMorphism('0->01,1->10').abelian_rotation_subspace() # needs sage.modules + sage: WordMorphism('0->01,1->10').abelian_rotation_subspace() Vector space of degree 2 and dimension 0 over Rational Field Basis matrix: [] - sage: WordMorphism('0->01,1->1').abelian_rotation_subspace() # needs sage.modules + sage: WordMorphism('0->01,1->1').abelian_rotation_subspace() Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: [0 1] - sage: WordMorphism('1->122,2->211').abelian_rotation_subspace() # needs sage.modules + sage: WordMorphism('1->122,2->211').abelian_rotation_subspace() Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: [ 1 -1] - sage: WordMorphism('0->1,1->102,2->3,3->4,4->2').abelian_rotation_subspace() # needs sage.modules + sage: WordMorphism('0->1,1->102,2->3,3->4,4->2').abelian_rotation_subspace() Vector space of degree 5 and dimension 3 over Rational Field Basis matrix: [0 0 1 0 0] diff --git a/src/sage/combinat/words/paths.py b/src/sage/combinat/words/paths.py index dcf37d8f456..5c84a784533 100644 --- a/src/sage/combinat/words/paths.py +++ b/src/sage/combinat/words/paths.py @@ -1646,13 +1646,14 @@ def animate(self): The first 4 Fibonacci tiles in an animation:: - sage: a = words.fibonacci_tile(0).animate() # needs sage.plot - sage: b = words.fibonacci_tile(1).animate() # needs sage.plot - sage: c = words.fibonacci_tile(2).animate() # needs sage.plot - sage: d = words.fibonacci_tile(3).animate() # needs sage.plot - sage: print(a*b*c*d) # needs sage.plot + sage: # needs sage.plot + sage: a = words.fibonacci_tile(0).animate() + sage: b = words.fibonacci_tile(1).animate() + sage: c = words.fibonacci_tile(2).animate() + sage: d = words.fibonacci_tile(3).animate() + sage: print(a*b*c*d) Animation with 296 frames - sage: show(a*b*c*d) # long time, optional - imagemagick, needs sage.plot + sage: show(a*b*c*d) # long time, optional - imagemagick .. note:: diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 681ce39e26e..58886bd9108 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -855,10 +855,11 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): :: - sage: a = words.LowerMechanicalWord(1/pi)[1:] # needs sage.symbolic - sage: b = words.UpperMechanicalWord(1/pi)[1:] # needs sage.symbolic - sage: c = words.CharacteristicSturmianWord(1/pi) # needs sage.symbolic - sage: n = 500; a[:n] == b[:n] == c[:n] # needs sage.symbolic + sage: # needs sage.symbolic + sage: a = words.LowerMechanicalWord(1/pi)[1:] + sage: b = words.UpperMechanicalWord(1/pi)[1:] + sage: c = words.CharacteristicSturmianWord(1/pi) + sage: n = 500; a[:n] == b[:n] == c[:n] True :: @@ -937,11 +938,12 @@ def _CharacteristicSturmianWord_LetterIterator(self, cf, alphabet=(0,1)): :: - sage: alpha = (sqrt(3)-1)/2 # needs sage.symbolic - sage: continued_fraction(alpha)[:10] # needs sage.symbolic + sage: # needs sage.symbolic + sage: alpha = (sqrt(3)-1)/2 + sage: continued_fraction(alpha)[:10] [0; 2, 1, 2, 1, 2, 1, 2, 1, 2] - sage: cf = iter(_) # needs sage.symbolic - sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) # needs sage.symbolic + sage: cf = iter(_) + sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) word: 0100100101001001001010010010010100100101... """ try: From 8153dbd027a4a21bcc0de7a60793b1252fff60d1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 4 Nov 2023 10:24:42 -0700 Subject: [PATCH 136/463] sage.combinat.words: More block tags --- src/sage/combinat/words/finite_word.py | 13 +++++++------ src/sage/combinat/words/morphism.py | 27 +++++++++++++------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index d43624c8ebe..35fd6e69c55 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -6824,18 +6824,19 @@ def colored_vector(self, x=0, y=0, width='default', height=1, cmap='hsv', thickn EXAMPLES:: - sage: Word(range(20)).colored_vector() # needs sage.plot + sage: # needs sage.plot + sage: Word(range(20)).colored_vector() Graphics object consisting of 21 graphics primitives - sage: Word(range(100)).colored_vector(0,0,10,1) # needs sage.plot + sage: Word(range(100)).colored_vector(0,0,10,1) Graphics object consisting of 101 graphics primitives - sage: Words(range(100))(range(10)).colored_vector() # needs sage.plot + sage: Words(range(100))(range(10)).colored_vector() Graphics object consisting of 11 graphics primitives sage: w = Word('abbabaab') - sage: w.colored_vector() # needs sage.plot + sage: w.colored_vector() Graphics object consisting of 9 graphics primitives - sage: w.colored_vector(cmap='autumn') # needs sage.plot + sage: w.colored_vector(cmap='autumn') Graphics object consisting of 9 graphics primitives - sage: Word(range(20)).colored_vector(label='Rainbow') # needs sage.plot + sage: Word(range(20)).colored_vector(label='Rainbow') Graphics object consisting of 23 graphics primitives When two words are defined under the same parent, same letters are diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index de7f00902ef..279c238718e 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -346,7 +346,7 @@ def __init__(self, data, domain=None, codomain=None): The image of a letter can be a set, but the order is not preserved:: - sage: WordMorphism({2:[4,5,6],3:set([4,1,8])}) #random results + sage: WordMorphism({2:[4,5,6],3:set([4,1,8])}) # random results WordMorphism: 2->456, 3->814 If the image of a letter is not iterable, it is considered as a @@ -1099,23 +1099,24 @@ def _matrix_(self, R=None): EXAMPLES:: + sage: # needs sage.modules sage: fibo = WordMorphism('a->ab,b->a') sage: tm = WordMorphism('a->ab,b->ba') - sage: Mfibo = matrix(fibo); Mfibo # indirect doctest # needs sage.modules + sage: Mfibo = matrix(fibo); Mfibo # indirect doctest [1 1] [1 0] - sage: Mtm = matrix(tm); Mtm # needs sage.modules + sage: Mtm = matrix(tm); Mtm [1 1] [1 1] - sage: Mtm * Mfibo == matrix(tm*fibo) # indirect doctest # needs sage.modules + sage: Mtm * Mfibo == matrix(tm*fibo) # indirect doctest True - sage: Mfibo * Mtm == matrix(fibo*tm) # indirect doctest # needs sage.modules + sage: Mfibo * Mtm == matrix(fibo*tm) # indirect doctest True - sage: Mfibo.parent() # needs sage.modules + sage: Mfibo.parent() Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: p = Mfibo.charpoly(); p # needs sage.modules + sage: p = Mfibo.charpoly(); p x^2 - x - 1 - sage: p.roots(ring=RR, multiplicities=False) # needs sage.modules + sage: p.roots(ring=RR, multiplicities=False) [-0.618033988749895, 1.61803398874989] """ if R is None: @@ -1406,19 +1407,19 @@ def partition_of_domain_alphabet(self): EXAMPLES:: sage: m = WordMorphism('a->b,b->a') - sage: m.partition_of_domain_alphabet() #random ordering + sage: m.partition_of_domain_alphabet() # random ordering ({'a'}, {'b'}, {}) sage: m = WordMorphism('a->b,b->a,c->c') - sage: m.partition_of_domain_alphabet() #random ordering + sage: m.partition_of_domain_alphabet() # random ordering ({'a'}, {'b'}, {'c'}) sage: m = WordMorphism('a->a,b->b,c->c') - sage: m.partition_of_domain_alphabet() #random ordering + sage: m.partition_of_domain_alphabet() # random ordering ({}, {}, {'a', 'c', 'b'}) sage: m = WordMorphism('A->T,T->A,C->G,G->C') - sage: m.partition_of_domain_alphabet() #random ordering + sage: m.partition_of_domain_alphabet() # random ordering ({'A', 'C'}, {'T', 'G'}, {}) sage: I = WordMorphism({0:oo,oo:0,1:-1,-1:1,2:-2,-2:2,3:-3,-3:3}) - sage: I.partition_of_domain_alphabet() #random ordering + sage: I.partition_of_domain_alphabet() # random ordering ({0, -1, -3, -2}, {1, 2, 3, +Infinity}, {}) TESTS:: From 81dfb7bce2a04bac66050dc69c361fa7939088ba Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 4 Nov 2023 10:29:24 -0700 Subject: [PATCH 137/463] src/sage/combinat/species/partition_species.py: Fix indentation --- src/sage/combinat/species/partition_species.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/species/partition_species.py b/src/sage/combinat/species/partition_species.py index 21a57197ccd..dea38378a7a 100644 --- a/src/sage/combinat/species/partition_species.py +++ b/src/sage/combinat/species/partition_species.py @@ -141,7 +141,7 @@ def __classcall__(cls, *args, **kwds): sage: P = species.PartitionSpecies(); P Partition species - """ + """ return super().__classcall__(cls, *args, **kwds) def __init__(self, min=None, max=None, weight=None): From d2e559e95fc6eefb3f05b8cb8d84a38d56726cef Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 4 Nov 2023 11:42:18 -0700 Subject: [PATCH 138/463] src/sage/algebras/cluster_algebra.py: Restore lost # random --- src/sage/algebras/cluster_algebra.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/algebras/cluster_algebra.py b/src/sage/algebras/cluster_algebra.py index fa29367d014..4550e57e6ab 100644 --- a/src/sage/algebras/cluster_algebra.py +++ b/src/sage/algebras/cluster_algebra.py @@ -301,7 +301,7 @@ sage: # long time sage: A.reset_exploring_iterator(mutating_F=False) sage: v = (-1, 1, -2, 2, -1, 1, -1, 1, 1) - sage: seq = A.find_g_vector(v); seq + sage: seq = A.find_g_vector(v); seq # random [1, 0, 2, 6, 5, 4, 3, 8, 1] sage: S = A.initial_seed().mutate(seq, inplace=False) sage: v in S.g_vectors() From df17d12eb2fe08f69c175e670d786115b20b4440 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 4 Nov 2023 11:42:30 -0700 Subject: [PATCH 139/463] src/sage/algebras/orlik_solomon.py: Fix doctest fix --- src/sage/algebras/orlik_solomon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 7cb469f09cc..76ed00aa855 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -368,7 +368,7 @@ def subset_image(self, S): sage: # needs sage.graphs sage: G = Graph([[1,2],[1,2],[2,3],[2,3],[1,3],[1,3]], multiedges=True) sage: MG = Matroid(G) - sage: sorted([sorted(c) for c in M.circuits()]) + sage: sorted([sorted(c) for c in MG.circuits()]) [[0, 1], [0, 2, 4], [0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [2, 3], [4, 5]] From a739e04ea2516ccd6c6e7336baa1daf5ccb3e2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 5 Nov 2023 18:33:10 +0100 Subject: [PATCH 140/463] clean E702 etc in integer.pyx --- src/sage/rings/integer.pyx | 308 ++++++++++++++++++++----------------- 1 file changed, 167 insertions(+), 141 deletions(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 3ecd0bd986d..744e8d37cf8 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -207,7 +207,8 @@ new_gen_from_integer = None cdef extern from *: int unlikely(int) nogil # Defined by Cython -cdef object numpy_long_interface = {'typestr': '=i4' if sizeof(long) == 4 else '=i8' } +cdef object numpy_long_interface = {'typestr': '=i4' if sizeof(long) == 4 + else '=i8'} cdef object numpy_int64_interface = {'typestr': '=i8'} cdef object numpy_object_interface = {'typestr': '|O'} @@ -288,7 +289,6 @@ cdef _digits_internal(mpz_t v,l,int offset,int power_index,power_list,digits) no cdef mpz_t mpz_res cdef mpz_t mpz_quot cdef Integer temp - cdef int v_int if power_index < 5: # It turns out that simple repeated division is very fast for # relatively few digits. I don't think this is a real algorithmic @@ -318,6 +318,7 @@ cdef mpz_t PARI_PSEUDOPRIME_LIMIT mpz_init(PARI_PSEUDOPRIME_LIMIT) mpz_ui_pow_ui(PARI_PSEUDOPRIME_LIMIT, 2, 64) + def is_Integer(x): """ Return ``True`` if ``x`` is of the Sage :class:`Integer` type. @@ -336,12 +337,14 @@ def is_Integer(x): """ return isinstance(x, Integer) + cdef inline Integer as_Integer(x) noexcept: if isinstance(x, Integer): return x else: return Integer(x) + cdef class IntegerWrapper(Integer): r""" Rationale for the :class:`IntegerWrapper` class: @@ -612,8 +615,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): # mpz_init_set_sage(self.value, x) cdef Integer tmp - cdef char* xs - cdef int paritype cdef Py_ssize_t j cdef object otmp @@ -675,8 +676,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): elif (isinstance(x, list) or isinstance(x, tuple)) and base > 1: b = the_integer_ring(base) - if b == 2: # we use a faster method - for j from 0 <= j < len(x): + if b == 2: # we use a faster method + for j in range(len(x)): otmp = x[j] if isinstance(otmp, int): if ( otmp) == 1: @@ -968,7 +969,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: m.list() [5] """ - return [ self ] + return [self] def __dealloc__(self): mpz_clear(self.value) @@ -1037,7 +1038,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: (-45)._mathml_() '-45' """ - return '%s'%self + return '%s' % self def __mpz__(self): """ @@ -1098,7 +1099,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): '1000000000' """ if base < 2 or base > 36: - raise ValueError("base (=%s) must be between 2 and 36" % base) + raise ValueError(f"base (={base}) must be between 2 and 36") cdef size_t n cdef char *s n = mpz_sizeinbase(self.value, base) + 2 @@ -1157,16 +1158,15 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): '112th' sage: ZZ(111).ordinal_str() '111th' - """ - if self<0: + if self < 0: raise ValueError("Negative integers are not ordinals.") n = self.abs() - if ((n%100)!=11 and n%10==1): + if (n % 100) != 11 and n % 10 == 1: th = 'st' - elif ((n%100)!=12 and n%10==2): + elif (n % 100) != 12 and n % 10 == 2: th = 'nd' - elif ((n%100)!=13 and n%10==3): + elif (n % 100) != 13 and n % 10 == 3: th = 'rd' else: th = 'th' @@ -1513,7 +1513,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): o = -one z = zero l = [z]*(s if s >= padto else padto) - for i from 0<= i < s: + for i in range(s): # mpz_tstbit seems to return 0 for the high-order bit of # negative numbers?! if mpz_tstbit(self_abs.value,i): @@ -1521,7 +1521,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): else: s = mpz_sizeinbase(self.value, 2) do_sig_on = (s > 256) - if do_sig_on: sig_on() + if do_sig_on: + sig_on() # We use a divide and conquer approach (suggested by the prior # author, malb?, of the digits method) here: for base b, compute @@ -1577,7 +1578,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): # assigning zero. _digits_internal(self.value,l,0,i-1,power_list,digits) - if do_sig_on: sig_off() + if do_sig_on: + sig_off() # padding should be taken care of with-in the function # all we need to do is return @@ -1908,7 +1910,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): if mpz_fits_slong_p(self.value): return s * mpz_get_si(self.value) else: - return s * int(self) # will raise the appropriate exception + return s * int(self) # will raise the appropriate exception cdef _mul_long(self, long n) noexcept: """ @@ -2024,9 +2026,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): # left * den(right) / num(right) y = Rational.__new__(Rational) mpq_div_zz(y.value, (left).value, - mpq_numref((right).value)) + mpq_numref((right).value)) mpz_mul(mpq_numref(y.value), mpq_numref(y.value), - mpq_denref((right).value)) + mpq_denref((right).value)) return y return coercion_model.bin_op(left, right, operator.truediv) @@ -2460,7 +2462,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef size_t l_min cdef size_t l_max cdef size_t l - cdef Integer result cdef mpz_t accum cdef mpz_t temp_exp @@ -2578,7 +2579,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): if (1 << (pow_2-1)) == upper-lower: pow_2 -= 1 pow_2_things = [rif_m]*pow_2 - for i from 1<=ii>=0: middle = lower + int(2)**i @@ -2683,13 +2684,12 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef Integer result cdef size_t n_log2 cdef size_t m_log2 - cdef size_t guess # this will contain the final answer + cdef size_t guess # this will contain the final answer cdef bint guess_filled = 0 # this variable is only used in one branch below - cdef mpz_t z if isinstance(m, Integer): - _m=m + _m = m else: - _m=Integer(m) + _m = Integer(m) self_sgn = mpz_sgn(self.value) if self_sgn == 0: @@ -2717,7 +2717,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): # we've already excluded the case when m is an exact power of 2 - if n_log2/m_log2 > 8000: + if n_log2 / m_log2 > 8000: # If we have a very large number of digits, it can be a nice # shortcut to test the guess using interval arithmetic. # (suggested by David Harvey and Carl Witty) @@ -2729,7 +2729,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): guess_filled = 1 elif self < approx_compare: guess_filled = 1 - guess = guess - 1 + guess = guess - 1 if not guess_filled: # At this point, either # 1) self is close enough to a perfect power of m that we @@ -2864,15 +2864,14 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): if elog == -sage.rings.infinity.infinity or m**elog == self: return elog - if (isinstance(m, Rational) - and m.numer() == 1): + if isinstance(m, Rational) and m.numer() == 1: elog = -self.exact_log(m.denom()) if m**elog == self: return elog from sage.functions.log import function_log return function_log(self,dont_call_method_on_arg=True)/\ - function_log(m,dont_call_method_on_arg=True) + function_log(m,dont_call_method_on_arg=True) def exp(self, prec=None): r""" @@ -3113,7 +3112,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef list all, prev, sorted cdef Py_ssize_t tip, top - cdef Py_ssize_t i, j, e, ee + cdef Py_ssize_t i, e, ee cdef Integer apn, p, pn, z, all_tip f = self.factor() @@ -3124,7 +3123,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef unsigned long p_c, pn_c, apn_c cdef Py_ssize_t all_len, sorted_len, prev_len cdef unsigned long* ptr - cdef unsigned long* empty_c cdef unsigned long* swap_tmp cdef unsigned long* all_c cdef unsigned long* sorted_c @@ -3222,7 +3220,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sorted = [] tip = 0 top = len(all) - mpz_mul(pn.value, pn.value, p.value) # pn *= p + mpz_mul(pn.value, pn.value, p.value) # pn *= p for a in prev: # apn = a*pn apn = PY_NEW(Integer) @@ -3510,7 +3508,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ZeroDivisionError: cannot raise to a power modulo 0 """ cdef Integer x, _exp, _mod - _exp = Integer(exp); _mod = Integer(mod) + _exp = Integer(exp) + _mod = Integer(mod) if mpz_cmp_si(_mod.value,0) == 0: raise ZeroDivisionError("cannot raise to a power modulo 0") @@ -3763,51 +3762,75 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): # We need to find i. m = start % 30 if 0 <= m <= 1: - i = 0; m = start + (1-m) + i = 0 + m = start + (1-m) elif 1 < m <= 7: - i = 1; m = start + (7-m) + i = 1 + m = start + (7-m) elif 7 < m <= 11: - i = 2; m = start + (11-m) + i = 2 + m = start + (11-m) elif 11 < m <= 13: - i = 3; m = start + (13-m) + i = 3 + m = start + (13-m) elif 13 < m <= 17: - i = 4; m = start + (17-m) + i = 4 + m = start + (17-m) elif 17 < m <= 19: - i = 5; m = start + (19-m) + i = 5 + m = start + (19-m) elif 19 < m <= 23: - i = 6; m = start + (23-m) + i = 6 + m = start + (23-m) elif 23 < m <= 29: - i = 7; m = start + (29-m) - dif[0]=6;dif[1]=4;dif[2]=2;dif[3]=4;dif[4]=2;dif[5]=4;dif[6]=6;dif[7]=2 + i = 7 + m = start + (29-m) + dif[0] = 6 + dif[1] = 4 + dif[2] = 2 + dif[3] = 4 + dif[4] = 2 + dif[5] = 4 + dif[6] = 6 + dif[7] = 2 cdef Integer x = PY_NEW(Integer) if mpz_fits_ulong_p(self.value): n = mpz_get_ui(self.value) # ignores the sign automatically - if n == 1: return one - if start <= 2 and n%2==0: - mpz_set_ui(x.value,2); return x - if start <= 3 and n%3==0: - mpz_set_ui(x.value,3); return x - if start <= 5 and n%5==0: - mpz_set_ui(x.value,5); return x + if n == 1: + return one + if start <= 2 and n % 2 == 0: + mpz_set_ui(x.value,2) + return x + if start <= 3 and n % 3 == 0: + mpz_set_ui(x.value,3) + return x + if start <= 5 and n % 5 == 0: + mpz_set_ui(x.value,5) + return x limit = sqrt_double( n) - if bound < limit: limit = bound + if bound < limit: + limit = bound # Algorithm: only trial divide by numbers that # are congruent to 1,7,11,13,17,19,23,29 mod 30=2*3*5. while m <= limit: - if n%m == 0: - mpz_set_ui(x.value, m); return x - m += dif[i%8] + if n % m == 0: + mpz_set_ui(x.value, m) + return x + m += dif[i % 8] i += 1 mpz_abs(x.value, self.value) return x else: # self is big -- it doesn't fit in unsigned long. if start <= 2 and mpz_even_p(self.value): - mpz_set_ui(x.value,2); return x + mpz_set_ui(x.value,2) + return x if start <= 3 and mpz_divisible_ui_p(self.value,3): - mpz_set_ui(x.value,3); return x + mpz_set_ui(x.value,3) + return x if start <= 5 and mpz_divisible_ui_p(self.value,5): - mpz_set_ui(x.value,5); return x + mpz_set_ui(x.value,5) + return x # x.value = floor(sqrt(self.value)) sig_on() @@ -3829,7 +3852,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return x def factor(self, algorithm='pari', proof=None, limit=None, int_=False, - verbose=0): + verbose=0): """ Return the prime factorization of this integer as a formal Factorization object. @@ -3949,23 +3972,22 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): raise ValueError("Algorithm is not known") cdef Integer n, p, unit - cdef int i if mpz_sgn(self.value) == 0: raise ArithmeticError("factorization of 0 is not defined") if mpz_sgn(self.value) > 0: - n = self + n = self unit = one else: - n = PY_NEW(Integer) + n = PY_NEW(Integer) unit = PY_NEW(Integer) mpz_neg(n.value, self.value) mpz_set_si(unit.value, -1) if mpz_cmpabs_ui(n.value, 1) == 0: return IntegerFactorization([], unit=unit, unsafe=True, - sort=False, simplify=False) + sort=False, simplify=False) if limit is not None: from sage.rings.factorint import factor_trial_division @@ -3986,7 +4008,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): F = [(smallInteger(a), smallInteger(b)) for a, b in F] F.sort() return IntegerFactorization(F, unit=unit, unsafe=True, - sort=False, simplify=False) + sort=False, simplify=False) if mpz_sizeinbase(n.value, 2) < 40: from sage.rings.factorint import factor_trial_division @@ -3997,20 +4019,20 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): F = factor_using_pari(n, int_=int_, debug_level=verbose, proof=proof) F.sort() return IntegerFactorization(F, unit=unit, unsafe=True, - sort=False, simplify=False) + sort=False, simplify=False) elif algorithm == 'flint': from sage.rings.factorint_flint import factor_using_flint F = factor_using_flint(n) F.sort() return IntegerFactorization(F, unit=unit, unsafe=True, - sort=False, simplify=False) + sort=False, simplify=False) elif algorithm in ['kash', 'magma']: if algorithm == 'kash': from sage.interfaces.kash import kash as I else: from sage.interfaces.magma import magma as I - str_res = I.eval('Factorization(%s)'%n) + str_res = I.eval('Factorization(%s)' % n) # The result looks like "[ , , ... ] str_res = str_res.replace(']', '').replace('[', '').replace('>', '').replace('<', '').split(',') res = [int(s.strip()) for s in str_res] @@ -4025,7 +4047,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): F = qsieve(n) F.sort() return IntegerFactorization(F, unit=unit, unsafe=True, - sort=False, simplify=False) + sort=False, simplify=False) else: from sage.interfaces.ecm import ecm res = [(p, 1) for p in ecm.factor(n, proof=proof)] @@ -4051,10 +4073,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: 0.support() Traceback (most recent call last): ... - ArithmeticError: Support of 0 not defined. + ArithmeticError: Support of 0 not defined """ if self.is_zero(): - raise ArithmeticError("Support of 0 not defined.") + raise ArithmeticError("Support of 0 not defined") return sage.arith.all.prime_factors(self) def coprime_integers(self, m): @@ -4345,7 +4367,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): if mpz_cmpabs_ui(self.value, 1) <= 0: return self - odd = PY_NEW(Integer) + odd = PY_NEW(Integer) bits = mpz_scan1(self.value, 0) mpz_tdiv_q_2exp(odd.value, self.value, bits) return odd @@ -4918,100 +4940,100 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef unsigned long b, c cdef mpz_t u, sabs, nabs a = mpz_cmp_ui(n.value, 2) - if a <= 0: # n <= 2 - if a == 0: # n == 2 - if mpz_popcount(self.value) == 1: #number of bits set in self == 1 + if a <= 0: # n <= 2 + if a == 0: # n == 2 + if mpz_popcount(self.value) == 1: # number of bits set in self == 1 return 1 else: return 0 a = mpz_cmp_si(n.value, -2) - if a >= 0: # -2 <= n < 2: + if a >= 0: # -2 <= n < 2: a = mpz_get_si(n.value) - if a == 1: # n == 1 - if mpz_cmp_ui(self.value, 1) == 0: # Only 1 is a power of 1 + if a == 1: # n == 1 + if mpz_cmp_ui(self.value, 1) == 0: # Only 1 is a power of 1 return 1 else: return 0 - elif a == 0: # n == 0 - if mpz_cmp_ui(self.value, 0) == 0 or mpz_cmp_ui(self.value, 1) == 0: # 0^0 = 1, 0^x = 0 + elif a == 0: # n == 0 + if mpz_cmp_ui(self.value, 0) == 0 or mpz_cmp_ui(self.value, 1) == 0: # 0^0 = 1, 0^x = 0 return 1 else: return 0 - elif a == -1: # n == -1 - if mpz_cmp_ui(self.value, 1) == 0 or mpz_cmp_si(self.value, -1) == 0: # 1 and -1 are powers of -1 + elif a == -1: # n == -1 + if mpz_cmp_ui(self.value, 1) == 0 or mpz_cmp_si(self.value, -1) == 0: # 1 and -1 are powers of -1 return 1 else: return 0 - elif a == -2: # n == -2 + elif a == -2: # n == -2 mpz_init(sabs) mpz_abs(sabs, self.value) - if mpz_popcount(sabs) == 1: # number of bits set in |self| == 1 - b = mpz_scan1(sabs, 0) % 2 # b == 1 if |self| is an odd power of 2, 0 if |self| is an even power + if mpz_popcount(sabs) == 1: # number of bits set in |self| == 1 + b = mpz_scan1(sabs, 0) % 2 # b == 1 if |self| is an odd power of 2, 0 if |self| is an even power mpz_clear(sabs) if (b == 1 and mpz_cmp_ui(self.value, 0) < 0) or (b == 0 and mpz_cmp_ui(self.value, 0) > 0): # An odd power of -2 is negative, an even power must be positive. return 1 - else: # number of bits set in |self| is not 1, so self cannot be a power of -2 + else: # number of bits set in |self| is not 1, so self cannot be a power of -2 return 0 - else: # |self| is not a power of 2, so self cannot be a power of -2 + else: # |self| is not a power of 2, so self cannot be a power of -2 return 0 - else: # n < -2 + else: # n < -2 mpz_init(nabs) mpz_neg(nabs, n.value) - if mpz_popcount(nabs) == 1: # |n| = 2^k for k >= 2. We special case this for speed + if mpz_popcount(nabs) == 1: # |n| = 2^k for k >= 2. We special case this for speed mpz_init(sabs) mpz_abs(sabs, self.value) - if mpz_popcount(sabs) == 1: # |self| = 2^L for some L >= 0. - b = mpz_scan1(sabs, 0) # the bit that self is set at - c = mpz_scan1(nabs, 0) # the bit that n is set at + if mpz_popcount(sabs) == 1: # |self| = 2^L for some L >= 0. + b = mpz_scan1(sabs, 0) # the bit that self is set at + c = mpz_scan1(nabs, 0) # the bit that n is set at # Having obtained b and c, we're done with nabs and sabs (on this branch anyway) mpz_clear(nabs) mpz_clear(sabs) - if b % c == 0: # Now we know that |self| is a power of |n| - b = (b // c) % 2 # Whether b // c is even or odd determines whether (-2^c)^(b // c) is positive or negative + if b % c == 0: # Now we know that |self| is a power of |n| + b = (b // c) % 2 # Whether b // c is even or odd determines whether (-2^c)^(b // c) is positive or negative a = mpz_cmp_ui(self.value, 0) if b == 0 and a > 0 or b == 1 and a < 0: # These two cases are that b // c is even and self positive, or b // c is odd and self negative return 1 - else: # The sign of self is wrong + else: # The sign of self is wrong return 0 - else: # Since |self| is not a power of |n|, self cannot be a power of n + else: # Since |self| is not a power of |n|, self cannot be a power of n return 0 - else: # self is not a power of 2, and thus cannot be a power of n, which is a power of 2. + else: # self is not a power of 2, and thus cannot be a power of n, which is a power of 2. mpz_clear(nabs) mpz_clear(sabs) return 0 - else: # |n| is not a power of 2, so we use mpz_remove + else: # |n| is not a power of 2, so we use mpz_remove mpz_init(u) sig_on() b = mpz_remove(u, self.value, nabs) sig_off() # Having obtained b and u, we're done with nabs mpz_clear(nabs) - if mpz_cmp_ui(u, 1) == 0: # self is a power of |n| + if mpz_cmp_ui(u, 1) == 0: # self is a power of |n| mpz_clear(u) - if b % 2 == 0: # an even power of |n|, and since self > 0, this means that self is a power of n + if b % 2 == 0: # an even power of |n|, and since self > 0, this means that self is a power of n return 1 else: return 0 - elif mpz_cmp_si(u, -1) == 0: # -self is a power of |n| + elif mpz_cmp_si(u, -1) == 0: # -self is a power of |n| mpz_clear(u) - if b % 2 == 1: # an odd power of |n|, and thus self is a power of n + if b % 2 == 1: # an odd power of |n|, and thus self is a power of n return 1 else: return 0 - else: # |self| is not a power of |n|, so self cannot be a power of n + else: # |self| is not a power of |n|, so self cannot be a power of n mpz_clear(u) return 0 - elif mpz_popcount(n.value) == 1: # n > 2 and in fact n = 2^k for k >= 2 - if mpz_popcount(self.value) == 1: # since n is a power of 2, so must self be. - if mpz_scan1(self.value, 0) % mpz_scan1(n.value, 0) == 0: # log_2(self) is divisible by log_2(n) + elif mpz_popcount(n.value) == 1: # n > 2 and in fact n = 2^k for k >= 2 + if mpz_popcount(self.value) == 1: # since n is a power of 2, so must self be. + if mpz_scan1(self.value, 0) % mpz_scan1(n.value, 0) == 0: # log_2(self) is divisible by log_2(n) return 1 else: return 0 - else: # self is not a power of 2, and thus not a power of n + else: # self is not a power of 2, and thus not a power of n return 0 - else: # n > 2, but not a power of 2, so we use mpz_remove + else: # n > 2, but not a power of 2, so we use mpz_remove mpz_init(u) sig_on() mpz_remove(u, self.value, n.value) @@ -5252,8 +5274,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return (self, zero) if get_data else False _small_primes_table[:] = [ - 0,1,1,1,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0, # 1, 3,..., 49 - 0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0, # 51, 53,..., 99 + 0,1,1,1,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0, # 001, 03,..., 49 + 0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0, # 051, 53,..., 99 1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,0,1, # 101,103,...,149 1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,1,0,1,1, # 151,153,...,199 0,0,0,0,0,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,0,0, # 201,203,...,249 @@ -5725,7 +5747,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): global objtogen if objtogen is None: from cypari2.gen import objtogen - flag = self < 0 and proof + flag = self < 0 and proof return objtogen(self).qfbclassno(flag).sage() def squarefree_part(self, long bound=-1): @@ -5829,7 +5851,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: 144168.next_probable_prime() 144169 """ - return Integer( self.__pari__().nextprime(True) ) + return Integer(self.__pari__().nextprime(True)) def next_prime(self, proof=None): r""" @@ -6138,7 +6160,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: len([D for D in srange(-100,100) if D.is_discriminant()]) 100 """ - return self%4 in [0,1] + return self % 4 in [0, 1] def is_fundamental_discriminant(self): """ @@ -6166,17 +6188,16 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: len([D for D in srange(-100,100) # needs sage.libs.pari ....: if D.is_fundamental_discriminant()]) 61 - """ - if self in [0,1]: + if self in [0, 1]: return False - Dmod4 = self%4 - if Dmod4 in [2,3]: + Dmod4 = self % 4 + if Dmod4 in [2, 3]: return False if Dmod4 == 1: return self.is_squarefree() - d = self//4 - return d%4 in [2,3] and d.is_squarefree() + d = self // 4 + return d % 4 in [2, 3] and d.is_squarefree() cpdef __pari__(self) noexcept: """ @@ -6274,9 +6295,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): True """ if self.ndigits(2) > 10000: - return 'StringToInteger("%s",16)'%self.str(16) - else: - return str(self) + return 'StringToInteger("%s",16)' % self.str(16) + return str(self) def _sage_input_(self, sib, coerced): r""" @@ -6339,13 +6359,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: Integer(-102).sqrtrem() Traceback (most recent call last): ... - ValueError: square root of negative integer not defined. + ValueError: square root of negative integer not defined """ if mpz_sgn(self.value) < 0: - raise ValueError("square root of negative integer not defined.") + raise ValueError("square root of negative integer not defined") cdef Integer s = PY_NEW(Integer) - cdef Integer r = PY_NEW(Integer) + cdef Integer r = PY_NEW(Integer) mpz_sqrtrem(s.value, r.value, self.value) return s, r @@ -6365,10 +6385,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: Integer(-102).isqrt() Traceback (most recent call last): ... - ValueError: square root of negative integer not defined. + ValueError: square root of negative integer not defined """ if mpz_sgn(self.value) < 0: - raise ValueError("square root of negative integer not defined.") + raise ValueError("square root of negative integer not defined") cdef Integer x = PY_NEW(Integer) @@ -6696,7 +6716,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): try: y = Integer(y) except TypeError: - raise TypeError("unsupported operands for %s: %s, %s"%(("<<" if sign == 1 else ">>"), self, y)) + raise TypeError("unsupported operands for %s: %s, %s" % (("<<" if sign == 1 else ">>"), self, y)) except ValueError: return coercion_model.bin_op(self, y, operator.lshift if sign == 1 else operator.rshift) @@ -6945,8 +6965,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def crt(self, y, m, n): """ Return the unique integer between `0` and `mn` that is congruent to - the integer modulo `m` and to `y` modulo `n`. We assume that `m` and - `n` are coprime. + the integer modulo `m` and to `y` modulo `n`. + + We assume that `m` and `n` are coprime. EXAMPLES:: @@ -6958,10 +6979,12 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: m%11 5 """ - cdef object g, s, t + cdef object g, s cdef Integer _y, _m, _n - _y = Integer(y); _m = Integer(m); _n = Integer(n) - g, s, t = _m.xgcd(_n) + _y = Integer(y) + _m = Integer(m) + _n = Integer(n) + g, s, _ = _m.xgcd(_n) if not g.is_one(): raise ArithmeticError("CRT requires that gcd of moduli is 1.") # Now s*m + t*n = 1, so the answer is x + (y-x)*s*m, where x=self. @@ -7023,7 +7046,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return sage.rings.infinity.Infinity return smallInteger(mpz_popcount(self.value)) - def conjugate(self): """ Return the complex conjugate of this integer, which is the @@ -7323,7 +7345,7 @@ def GCD_list(v): cdef int i, n = len(v) cdef Integer z = PY_NEW(Integer) - for i from 0 <= i < n: + for i in range(n): if not isinstance(v[i], Integer): if not isinstance(v, list): v = list(v) @@ -7336,7 +7358,7 @@ def GCD_list(v): sig_on() mpz_gcd(z.value, (v[0]).value, (v[1]).value) - for i from 2 <= i < n: + for i in range(2, n): if mpz_cmp_ui(z.value, 1) == 0: break mpz_gcd(z.value, z.value, (v[i]).value) @@ -7480,7 +7502,7 @@ cdef class long_to_Z(Morphism): def _repr_type(self): return "Native" -############### INTEGER CREATION CODE ##################### +# ############## INTEGER CREATION CODE ##################### # This variable holds the size of any Integer object in bytes. cdef int sizeof_Integer @@ -7492,6 +7514,7 @@ global_dummy_Integer = Integer() # Reallocate to one limb to fix :trac:`31340` and :trac:`33081` _mpz_realloc(global_dummy_Integer.value, 1) + def _check_global_dummy_Integer(): """ Return ``True`` if the global dummy :class:`Integer` is ok. @@ -7560,13 +7583,13 @@ cdef PyObject* fast_tp_new(type t, args, kwds) except NULL: # they do not possess references to other Python # objects (as indicated by the Py_TPFLAGS_HAVE_GC flag). # See below for a more detailed description. - new = PyObject_Malloc( sizeof_Integer ) + new = PyObject_Malloc(sizeof_Integer) if unlikely(new == NULL): raise MemoryError # Now set every member as set in z, the global dummy Integer # created before this tp_new started to operate. - memcpy(new, (global_dummy_Integer), sizeof_Integer ) + memcpy(new, (global_dummy_Integer), sizeof_Integer) # We allocate memory for the _mp_d element of the value of this # new Integer. We allocate one limb. Normally, one would use @@ -7670,15 +7693,16 @@ cdef integer(x) noexcept: return x return Integer(x) + def free_integer_pool(): cdef int i cdef PyObject *o global integer_pool_count, integer_pool_size - for i from 0 <= i < integer_pool_count: + for i in range(integer_pool_count): o = integer_pool[i] - mpz_clear( (o).value ) + mpz_clear((o).value) # Free the object. This assumes that Py_TPFLAGS_HAVE_GC is not # set. If it was set another free function would need to be # called. @@ -7688,6 +7712,7 @@ def free_integer_pool(): integer_pool_count = 0 sig_free(integer_pool) + # Replace default allocation and deletion with faster custom ones hook_fast_tp_functions() @@ -7695,7 +7720,8 @@ hook_fast_tp_functions() initialized = False cdef set_zero_one_elements() noexcept: global the_integer_ring, initialized - if initialized: return + if initialized: + return the_integer_ring._zero_element = Integer(0) the_integer_ring._one_element = Integer(1) initialized = True From f7269e42d7ecac7afef5390a196ba29273b20b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 5 Nov 2023 18:54:38 +0100 Subject: [PATCH 141/463] some fixes for E221 --- src/sage/misc/superseded.py | 6 +-- src/sage/modules/free_module.py | 14 +++--- src/sage/modules/with_basis/morphism.py | 4 +- src/sage/plot/plot3d/platonic.py | 29 ++++++++----- src/sage/plot/plot3d/tri_plot.py | 58 ++++++++++++------------- 5 files changed, 58 insertions(+), 53 deletions(-) diff --git a/src/sage/misc/superseded.py b/src/sage/misc/superseded.py index 6e93d8e5a51..87352e4f361 100644 --- a/src/sage/misc/superseded.py +++ b/src/sage/misc/superseded.py @@ -363,10 +363,10 @@ def __init__(self, issue_number, func, module, instance=None, unbound=None): try: self.__dict__.update(func.__dict__) except AttributeError: - pass # Cython classes don't have __dict__ + pass # Cython classes don't have __dict__ self.func = func - self.issue_number = issue_number - self.instance = instance # for use with methods + self.issue_number = issue_number + self.instance = instance # for use with methods self.unbound = unbound self.__module__ = module if isinstance(func, type(deprecation)): diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 5a65b4260f0..99538112cbc 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -2443,7 +2443,7 @@ def aux(length, norm, max_): iters = [iter(R) for _ in range(len(G))] for x in iters: next(x) # put at 0 - zero = R(0) + zero = R.zero() v = [zero for _ in range(len(G))] n = 0 z = self(0) @@ -3873,11 +3873,11 @@ def intersection(self, other): V2 = self A1 = V1.basis_matrix() A2 = V2.basis_matrix() - S = A1.stack(A2) - K = S.integer_kernel(self.base_ring()).basis_matrix() - n = int(V1.dimension()) + S = A1.stack(A2) + K = S.integer_kernel(self.base_ring()).basis_matrix() + n = int(V1.dimension()) K = K.matrix_from_columns(range(n)) - B = K*A1 + B = K * A1 return self.span(B) def __and__(self, other): @@ -5201,10 +5201,10 @@ def __quotient_matrices(self, sub): # Our algorithm is to note that D is determined if we just # replace both A and S by the submatrix got from their pivot # columns. - P = A.pivots() + P = A.pivots() AA = A.matrix_from_columns(P) SS = S.matrix_from_columns(P) - D = SS * AA**(-1) + D = SS * AA**(-1) # Compute the image of each basis vector for ``self`` under the # map "write an element of ``self`` in terms of the basis A" then diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index b94629a8dfe..30b4041f0cb 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -1055,7 +1055,7 @@ def coreduced(self, y): on_basis = self.on_basis() assert y in G - result = G.zero() + result = G.zero() remainder = y while not remainder.is_zero(): @@ -1447,7 +1447,7 @@ def __init__(self, domain, diagonal, codomain=None, category=None): if codomain is None: raise ValueError("The codomain should be specified") if not (domain.basis().keys() == codomain.basis().keys() and - domain.base_ring() == codomain.base_ring()): + domain.base_ring() == codomain.base_ring()): raise ValueError("The domain and codomain should have the same base ring " "and the same basis indexing") from collections.abc import Callable diff --git a/src/sage/plot/plot3d/platonic.py b/src/sage/plot/plot3d/platonic.py index be590739c3e..94d15ab16ad 100644 --- a/src/sage/plot/plot3d/platonic.py +++ b/src/sage/plot/plot3d/platonic.py @@ -152,6 +152,7 @@ def prep(G, center, size, kwds): G = G.translate(center) return G + @rename_keyword(alpha='opacity') def tetrahedron(center=(0, 0, 0), size=1, **kwds): """ @@ -255,15 +256,16 @@ def tetrahedron(center=(0, 0, 0), size=1, **kwds): one = RR.one() sqrt2 = RR(2).sqrt() sqrt6 = RR(6).sqrt() - point_list = [(0,0,1), - (2*sqrt2/3, 0, -one/3), - ( -sqrt2/3, sqrt6/3, -one/3), - ( -sqrt2/3, -sqrt6/3, -one/3)] + point_list = [(0, 0, 1), + (2*sqrt2/3, 0, -one/3), + (-sqrt2/3, sqrt6/3, -one/3), + (-sqrt2/3, -sqrt6/3, -one/3)] face_list = [[0,1,2],[1,3,2],[0,2,3],[0,3,1]] if 'aspect_ratio' not in kwds: kwds['aspect_ratio'] = [1, 1, 1] return index_face_set(face_list, point_list, enclosed=True, center=center, size=size, **kwds) + @rename_keyword(alpha='opacity') def cube(center=(0, 0, 0), size=1, color=None, frame_thickness=0, frame_color=None, **kwds): @@ -405,6 +407,7 @@ def cube(center=(0, 0, 0), size=1, color=None, frame_thickness=0, B += frame3d((-0.5,-0.5,-0.5),(0.5,0.5,0.5), thickness=frame_thickness, color=frame_color) return prep(B, center, size, kwds) + @rename_keyword(alpha='opacity') def octahedron(center=(0, 0, 0), size=1, **kwds): r""" @@ -440,7 +443,8 @@ def octahedron(center=(0, 0, 0), size=1, **kwds): kwds['enclosed'] = True if 'aspect_ratio' not in kwds: kwds['aspect_ratio'] = [1, 1, 1] - return prep(Box(1,1,1).dual(**kwds), center, size, kwds) + return prep(Box(1, 1, 1).dual(**kwds), center, size, kwds) + @rename_keyword(alpha='opacity') def dodecahedron(center=(0, 0, 0), size=1, **kwds): @@ -514,21 +518,21 @@ def dodecahedron(center=(0, 0, 0), size=1, **kwds): - Robert Bradshaw, William Stein """ RR = RDF - one = RR(1) + one = RR.one() sqrt3 = RR(3).sqrt() sqrt5 = RR(5).sqrt() R3 = RR**3 - rot = matrix(RR, [[ -one/2,-sqrt3/2, 0], - [ sqrt3/2, -one/2, 0], - [ 0, 0, 1]]) - rot2 = rot*rot + rot = matrix(RR, [[-one / 2, -sqrt3 / 2, 0], + [sqrt3 / 2, -one / 2, 0], + [0, 0, 1]]) + rot2 = rot * rot # The top - Q = R3([0,0,1]) + Q = R3([0, 0, 1]) # The first ring P1 = R3([2*one/3, 0, sqrt5/3]) # The second ring - R1 = R3([sqrt5/3, 1/sqrt3, one/3]) + R1 = R3([sqrt5/3, 1/sqrt3, one/3]) R2 = R3([sqrt5/3, -1/sqrt3, one/3]) top = [Q, P1, rot*P1, rot2*P1, R1, rot*R2, rot*R1, rot2*R2, rot2*R1, R2] @@ -555,6 +559,7 @@ def dodecahedron(center=(0, 0, 0), size=1, **kwds): # vertex_spheres += [faces.stickers(['red','yellow','blue','purple','black','orange'], .1, .1)] # [faces] # return Graphics3dGroup(vertex_spheres) + @rename_keyword(alpha='opacity') def icosahedron(center=(0, 0, 0), size=1, **kwds): r""" diff --git a/src/sage/plot/plot3d/tri_plot.py b/src/sage/plot/plot3d/tri_plot.py index da719020117..256b0d348c3 100644 --- a/src/sage/plot/plot3d/tri_plot.py +++ b/src/sage/plot/plot3d/tri_plot.py @@ -412,38 +412,38 @@ def plot_block(self, min_x, mid_x, max_x, min_y, mid_y, max_y, sw_z, nw_z, se_z, self.interface(0, sw.top, sw.top_c, nw.bottom, nw.bottom_c) self.interface(0, se.top, se.top_c, ne.bottom, ne.bottom_c) - #get the boundary information about the subsquares - left = sw.left + nw.left[1:] - left_c = sw.left_c + nw.left_c - right = se.right + ne.right[1:] - right_c = se.right_c + ne.right_c - top = nw.top + ne.top[1:] - top_c = nw.top_c + ne.top_c - bottom = sw.bottom + se.bottom[1:] + # get the boundary information about the subsquares + left = sw.left + nw.left[1:] + left_c = sw.left_c + nw.left_c + right = se.right + ne.right[1:] + right_c = se.right_c + ne.right_c + top = nw.top + ne.top[1:] + top_c = nw.top_c + ne.top_c + bottom = sw.bottom + se.bottom[1:] bottom_c = sw.bottom_c + se.bottom_c else: # just build the square we're in if self._g is None: - sw = [(min_x,min_y,sw_z[0])] - nw = [(min_x,max_y,nw_z[0])] - se = [(max_x,min_y,se_z[0])] - ne = [(max_x,max_y,ne_z[0])] - c = [[(mid_x,mid_y,mid_z[0])]] + sw = [(min_x, min_y, sw_z[0])] + nw = [(min_x, max_y, nw_z[0])] + se = [(max_x, min_y, se_z[0])] + ne = [(max_x, max_y, ne_z[0])] + c = [[(mid_x, mid_y, mid_z[0])]] else: - sw = [(min_x,min_y,sw_z[0]),sw_z[1]] - nw = [(min_x,max_y,nw_z[0]),nw_z[1]] - se = [(max_x,min_y,se_z[0]),se_z[1]] - ne = [(max_x,max_y,ne_z[0]),ne_z[1]] - c = [[(mid_x,mid_y,mid_z[0]),mid_z[1]]] - - left = [sw,nw] - left_c = c - top = [nw,ne] - top_c = c - right = [se,ne] - right_c = c - bottom = [sw,se] + sw = [(min_x, min_y, sw_z[0]), sw_z[1]] + nw = [(min_x, max_y, nw_z[0]), nw_z[1]] + se = [(max_x, min_y, se_z[0]), se_z[1]] + ne = [(max_x, max_y, ne_z[0]), ne_z[1]] + c = [[(mid_x, mid_y, mid_z[0]), mid_z[1]]] + + left = [sw, nw] + left_c = c + top = [nw, ne] + top_c = c + right = [se, ne] + right_c = c + bottom = [sw, se] bottom_c = c return PlotBlock(left, left_c, top, top_c, right, right_c, bottom, bottom_c) @@ -465,9 +465,9 @@ def interface(self, n, p, p_c, q, q_c): sage: t._objects[-1].get_vertices() ((-1/4, 0, 1/16), (-1/4, 1/4, 1/8), (-3/8, 1/8, 3/16)) """ - m = [p[0]] # a sorted union of p and q - mpc = [p_c[0]] # centers from p_c corresponding to m - mqc = [q_c[0]] # centers from q_c corresponding to m + m = [p[0]] # a sorted union of p and q + mpc = [p_c[0]] # centers from p_c corresponding to m + mqc = [q_c[0]] # centers from q_c corresponding to m i = 1 j = 1 From a945f880985732b9c34030b47f451df761700904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 5 Nov 2023 18:55:44 +0100 Subject: [PATCH 142/463] E221 in cubic_braid --- src/sage/groups/cubic_braid.py | 66 +++++++++++++++++----------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/sage/groups/cubic_braid.py b/src/sage/groups/cubic_braid.py index e8cb4a4e19f..debecbc0ba1 100644 --- a/src/sage/groups/cubic_braid.py +++ b/src/sage/groups/cubic_braid.py @@ -141,7 +141,7 @@ def eliminate_item(tietze_list): if second is None: return None middle = tietze_list[1:i] - end = tietze_list[i+1:l] + end = tietze_list[i+1:l] if first == second: return [-first] + middle + end else: @@ -490,7 +490,7 @@ def find_root(domain): if root[0] == 0: continue root_bur = root[0] - if root[1] == 1: + if root[1] == 1: break return root_bur @@ -747,7 +747,7 @@ def __init__(self, names, cbg_type=None): sage: U5 = AssionGroupU(5) # indirect doctest sage: TestSuite(U5).run() # long time """ - n = Integer(len(names)) + n = Integer(len(names)) if n < 1: raise ValueError("the number of strands must be an integer larger than one") @@ -759,12 +759,12 @@ def __init__(self, names, cbg_type=None): free_group = FreeGroup(names) self._cbg_type = cbg_type self._nstrands = n + 1 - self._ident = self._cbg_type.value + self._nstrands.str() + self._ident = self._cbg_type.value + self._nstrands.str() self._braid_group = BraidGroup(names) # internal naming of elements for convenience - b = [free_group([i]) for i in range(1, n+1)] - t = [free_group([i, i+1]) ** 3 for i in range(1, n)] + b = [free_group([i]) for i in range(1, n+1)] + t = [free_group([i, i+1]) ** 3 for i in range(1, n)] ti = [free_group([-i, -i-1]) ** 3 for i in range(1, n)] # first the braid relation @@ -796,12 +796,12 @@ def __init__(self, names, cbg_type=None): # the following global pointers to classical group realizations will be set in the private method # _create_classical_realization # ------------------------------------------------------------------------------------------------ - self._classical_group = None # This is the classical Group returned by as_classical_group - self._classical_base_group = None # this only differs for special cases for Assion groups from the former - self._classical_invariant_form = None # invariant form of the classical base group - self._classical_embedding = None # if self._classical_group different from self._classical_base_group - self._centralizing_matrix = None # for Assion groups: element in classical base group commuting with self - self._centralizing_element = None # image under nat. map of the former one in the proj. classical group + self._classical_group = None # This is the classical Group returned by as_classical_group + self._classical_base_group = None # this only differs for special cases for Assion groups from the former + self._classical_invariant_form = None # invariant form of the classical base group + self._classical_embedding = None # if self._classical_group different from self._classical_base_group + self._centralizing_matrix = None # for Assion groups: element in classical base group commuting with self + self._centralizing_element = None # image under nat. map of the former one in the proj. classical group return def _repr_(self): @@ -1095,7 +1095,7 @@ def set_classical_realization(self, base_group, proj_group, centralizing_matrix, # ------------------------------------------------------------------------------ # Setting the List of Braid Images # ------------------------------------------------------------------------------ - im_gens = [base_group(m) for m in transvec_matrices] + im_gens = [base_group(m) for m in transvec_matrices] # ------------------------------------------------------------------------------ # By the work of Assion no check on the group homomorphism is needed, at all. @@ -1109,7 +1109,7 @@ def set_classical_realization(self, base_group, proj_group, centralizing_matrix, # ------------------------------------------------------------------------------ # Do the projective group realization if needed # ------------------------------------------------------------------------------ - embedding = self._classical_embedding + embedding = self._classical_embedding classical_group = None if proj_group is None: classical_group = base_group @@ -1128,19 +1128,19 @@ def set_classical_realization(self, base_group, proj_group, centralizing_matrix, nat_hom = base_group.hom(proj_group.gens(), check=check) centralizing_element = nat_hom(centralizing_matrix) classical_group_gens = [nat_hom(m) for m in transvec_matrices] - classical_group = proj_group.subgroup(classical_group_gens, canonicalize=False) + classical_group = proj_group.subgroup(classical_group_gens, canonicalize=False) hom_to_classic = self.hom(classical_group.gens(), check=check) classical_group.register_conversion(hom_to_classic) # ------------------------------------------------------------------------------ # register constructed items # ------------------------------------------------------------------------------ - self._classical_group = classical_group - self._classical_base_group = base_group - self._classical_invariant_form = base_group.invariant_form() - self._centralizing_matrix = centralizing_matrix - self._centralizing_element = centralizing_element - self._classical_embedding = embedding + self._classical_group = classical_group + self._classical_base_group = base_group + self._classical_invariant_form = base_group.invariant_form() + self._centralizing_matrix = centralizing_matrix + self._centralizing_element = centralizing_element + self._classical_embedding = embedding return # ------------------------------------------------------------------------------- @@ -1211,7 +1211,7 @@ def transvec2mat(v, bas=bas, bform=bform, fact=1): # ------------------------------------------------------------------------------ centralizing_vector = xbas[mhalf-1] centralizing_matrix = base_group(transvec2mat(centralizing_vector, fact=1)) - transvec_matrices = [transvec2mat(v) for v in transvections] + transvec_matrices = [transvec2mat(v) for v in transvections] set_classical_realization(self, base_group, proj_group, centralizing_matrix, transvec_matrices) return @@ -1273,9 +1273,9 @@ def create_unitary_realization(self, m): for j in range(mthird): pos = 3*(j+1)-1 transvections.append(xbas[pos-1]) # t_{3i} = x_{3i-1} - if pos + 1 < m: + if pos + 1 < m: transvections.append(xbas[pos-1]+xbas[pos]+xbas[pos+1]) # t_{3i+1} = x_{3i-1} + x_{3i} + x_{3i+1} - if pos + 3 < m: + if pos + 3 < m: transvections.append(xbas[pos+1]+xbas[pos+2]+xbas[pos+3]) # t_{3i+2} = x_{3i+1} + x_{3i+2} + x_{3i+3} # ----------------------------------------------------------- @@ -1294,7 +1294,7 @@ def transvec2mat(v, bas=bas, bform=bform, fact=a): # ------------------------------------------------------------------------------ centralizing_vector = xbas[m-2]+xbas[m-1] centralizing_matrix = base_group(transvec2mat(centralizing_vector, fact=1)) - transvec_matrices = [transvec2mat(v) for v in transvections] + transvec_matrices = [transvec2mat(v) for v in transvections] set_classical_realization(self, base_group, proj_group, centralizing_matrix, transvec_matrices) return @@ -1314,13 +1314,13 @@ def transvec2mat(v, bas=bas, bform=bform, fact=a): # Setting the Classical group # ------------------------------------------------------------------------------- if self._cbg_type == CubicBraidGroup.type.AssionS: - dim_sympl_group = n-1 # S(n-1) = Sp(n-1, 3) - if n % 2 == 0: - dim_sympl_group = n # S(n-1) = subgroup of PSp(n, 3) + dim_sympl_group = n-1 # S(n-1) = Sp(n-1, 3) + if n % 2 == 0: + dim_sympl_group = n # S(n-1) = subgroup of PSp(n, 3) create_sympl_realization(self, dim_sympl_group) elif self._cbg_type == CubicBraidGroup.type.AssionU: dim_unitary_group = n-1 # U(n-1) = GU(n-1, 2) - if n % 3 == 0: + if n % 3 == 0: dim_unitary_group = n # U(n-1) = subgroup PGU(n, 3) create_unitary_realization(self, dim_unitary_group) else: @@ -1344,11 +1344,11 @@ def transvec2mat(v, bas=bas, bform=bform, fact=a): UCF = UniversalCyclotomicField() z12 = UCF.gen(12) classical_group = self.as_matrix_group(root_bur=~z12, domain=UCF, reduced='unitary') - self._classical_group = classical_group - self._classical_base_group = classical_group - self._classical_embedding = classical_group + self._classical_group = classical_group + self._classical_base_group = classical_group + self._classical_embedding = classical_group if self._classical_invariant_form is None: - self._classical_invariant_form = classical_group.ambient().invariant_form() + self._classical_invariant_form = classical_group.ambient().invariant_form() return def _element_constructor_(self, x, **kwds): From a4e65b6eac2219a575416b498be4810e2506dcc7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 23:47:37 -0700 Subject: [PATCH 143/463] More # optional --- src/sage/misc/explain_pickle.py | 214 +++++++++++++++++--------------- 1 file changed, 112 insertions(+), 102 deletions(-) diff --git a/src/sage/misc/explain_pickle.py b/src/sage/misc/explain_pickle.py index 30c3988850b..2fb34a2234e 100644 --- a/src/sage/misc/explain_pickle.py +++ b/src/sage/misc/explain_pickle.py @@ -5,9 +5,9 @@ - Carl Witty (2009-03) -The explain_pickle function takes a pickle and produces Sage code that +The :func:`explain_pickle` function takes a pickle and produces Sage code that will evaluate to the contents of the pickle. Ideally, the combination -of explain_pickle to produce Sage code and sage_eval to evaluate the code +of :func:`explain_pickle` to produce Sage code and :func:`sage_eval` to evaluate the code would be a 100% compatible implementation of cPickle's unpickler; this is almost the case now. @@ -27,9 +27,9 @@ True By default (as above) the code produced contains calls to several -utility functions (unpickle_global, etc.); this is done so that the +utility functions (:func:`unpickle_global`, etc.); this is done so that the code is truly equivalent to the pickle. If the pickle can be loaded -into a future version of Sage, then the code that explain_pickle +into a future version of Sage, then the code that :func:`explain_pickle` produces today should work in that future Sage as well. It is also possible to produce simpler code, that is tied to the current @@ -44,11 +44,11 @@ from sage.rings.rational import make_rational Polynomial_rational_flint(unpickle_PolynomialRing(RationalField(), ('x',), None, False), [make_rational('0'), make_rational('1')], False, True) -The explain_pickle function has several use cases. +The :func:`explain_pickle` function has several use cases. - Write pickling support for your classes - You can use explain_pickle to see what will happen when a pickle + You can use :func:`explain_pickle` to see what will happen when a pickle is unpickled. Consider: is this sequence of commands something that can be easily supported in all future Sage versions, or does it expose internal design decisions that are subject to change? @@ -56,55 +56,55 @@ - Debug old pickles If you have a pickle from an old version of Sage that no longer - unpickles, you can use explain_pickle to see what it is trying to + unpickles, you can use :func:`explain_pickle` to see what it is trying to do, to figure out how to fix it. - - Use explain_pickle in doctests to help maintenance + - Use :func:`explain_pickle` in doctests to help maintenance If you have a ``loads(dumps(S))`` doctest, you could also add an ``explain_pickle(dumps(S))`` doctest. Then if something changes in a way that would invalidate old pickles, the output of - ``explain_pickle`` will also change. At that point, you can add + :func:`explain_pickle` will also change. At that point, you can add the previous output of :obj:`explain_pickle` as a new set of doctests (and then update the :obj:`explain_pickle` doctest to use the new output), to ensure that old pickles will continue to work. -As mentioned above, there are several output modes for :obj:`explain_pickle`, +As mentioned above, there are several output modes for :func:`explain_pickle`, that control fidelity versus simplicity of the output. For example, the GLOBAL instruction takes a module name and a class name and produces the corresponding class. So GLOBAL of ``sage.rings.integer``, ``Integer`` is approximately equivalent to ``sage.rings.integer.Integer``. However, this class lookup process can be customized (using -sage.misc.persist.register_unpickle_override). For instance, +:func:`sage.misc.persist.register_unpickle_override`). For instance, if some future version of Sage renamed ``sage/rings/integer.pyx`` to ``sage/rings/knuth_was_here.pyx``, old pickles would no longer work unless register_unpickle_override was used; in that case, GLOBAL of -'sage.rings.integer', 'integer' would mean +``sage.rings.integer``, ``integer`` would mean ``sage.rings.knuth_was_here.integer``. -By default, ``explain_pickle`` will map this GLOBAL instruction to +By default, :func:`explain_pickle` will map this GLOBAL instruction to ``unpickle_global('sage.rings.integer', 'integer')``. Then when this code -is evaluated, unpickle_global will look up the current mapping in the -register_unpickle_override table, so the generated code will continue -to work even in hypothetical future versions of Sage where integer.pyx +is evaluated, :func:`unpickle_global` will look up the current mapping in the +:func:`register_unpickle_override` table, so the generated code will continue +to work even in hypothetical future versions of Sage where ``integer.pyx`` has been renamed. If you pass the flag ``in_current_sage=True``, then -:obj:`explain_pickle` will generate code that may only work in the +:func:`explain_pickle` will generate code that may only work in the current version of Sage, not in future versions. In this case, it would generate:: from sage.rings.integer import integer -and if you ran explain_pickle in hypothetical future sage, it would generate: +and if you ran :func:`explain_pickle` in hypothetical future sage, it would generate: from sage.rings.knuth_was_here import integer but the current code wouldn't work in the future sage. If you pass the flag ``default_assumptions=True``, then -:obj:`explain_pickle` will generate code that would work in the +:func:`explain_pickle` will generate code that would work in the absence of any special unpickling information. That is, in either current Sage or hypothetical future Sage, it would generate:: @@ -114,32 +114,32 @@ human-readable), but may not actually work; so it is only intended for human reading. -There are several functions used in the output of :obj:`explain_pickle`. +There are several functions used in the output of :func:`explain_pickle`. Here I give a brief description of what they usually do, as well as how to modify their operation (for instance, if you're trying to get old pickles to work). - ``unpickle_global(module, classname)``: - unpickle_global('sage.foo.bar', 'baz') is usually equivalent to - sage.foo.bar.baz, but this can be customized with - register_unpickle_override. + ``unpickle_global('sage.foo.bar', 'baz')`` is usually equivalent to + ``sage.foo.bar.baz``, but this can be customized with + :func:`register_unpickle_override`. - ``unpickle_newobj(klass, args)``: Usually equivalent to ``klass.__new__(klass, *args)``. If ``klass`` is a Python class, then you can define :meth:`__new__` to control the result (this result actually need not be an - instance of klass). (This doesn't work for Cython classes.) + instance of ``klass``). (This doesn't work for Cython classes.) - ``unpickle_build(obj, state)``: If ``obj`` has a :meth:`__setstate__` method, then this is equivalent to - ``obj.__setstate__(state)``. Otherwise uses state to set the attributes + ``obj.__setstate__(state)``. Otherwise uses ``state`` to set the attributes of ``obj``. Customize by defining :meth:`__setstate__`. - ``unpickle_instantiate(klass, args)``: Usually equivalent to ``klass(*args)``. Cannot be customized. - - unpickle_appends(lst, vals): - Appends the values in vals to lst. If not ``isinstance(lst, list)``, + - ``unpickle_appends(lst, vals)``: + Appends the values in ``vals`` to ``lst``. If not ``isinstance(lst, list)``, can be customized by defining a :meth:`append` method. """ @@ -165,7 +165,6 @@ from pickletools import genops -import sage.all from sage.misc.sage_input import SageInputBuilder, SageInputExpression from sage.misc.sage_eval import sage_eval from sage.misc.persist import (unpickle_override, unpickle_global, dumps, @@ -181,30 +180,30 @@ def explain_pickle(pickle=None, file=None, compress=True, **kwargs): r""" Explain a pickle. That is, produce source code such that evaluating the code is equivalent to loading the pickle. Feeding the result - of ``explain_pickle`` to ``sage_eval`` should be totally equivalent to loading + of :func:`explain_pickle` to :func:`sage_eval` should be totally equivalent to loading the ``pickle`` with ``cPickle``. INPUT: - - ``pickle`` -- the pickle to explain, as a string (default: None) - - ``file`` -- a filename of a pickle (default: None) - - ``compress`` -- if False, don't attempt to decompress the pickle - (default: True) - - ``in_current_sage`` -- if True, produce potentially simpler code that is - tied to the current version of Sage. (default: False) - - ``default_assumptions`` -- if True, produce potentially simpler code that - assumes that generic unpickling code will be - used. This code may not actually work. - (default: False) - - ``eval`` -- if True, then evaluate the resulting code and return the - evaluated result. (default: False) - - ``preparse`` -- if True, then produce code to be evaluated with - Sage's preparser; if False, then produce standard - Python code; if None, then produce code that will work - either with or without the preparser. (default: True) - - ``pedantic`` -- if True, then carefully ensures that the result has - at least as much sharing as the result of cPickle - (it may have more, for immutable objects). (default: False) + - ``pickle`` -- the pickle to explain, as a string (default: ``None``) + - ``file`` -- a filename of a pickle (default: ``None``) + - ``compress`` -- if ``False``, don't attempt to decompress the pickle + (default: ``True``) + - ``in_current_sage`` -- if ``True``, produce potentially simpler code that is + tied to the current version of Sage. (default: ``False``) + - ``default_assumptions`` -- if ``True``, produce potentially simpler code that + assumes that generic unpickling code will be + used. This code may not actually work. + (default: ``False``) + - ``eval`` -- if ``True``, then evaluate the resulting code and return the + evaluated result. (default: ``False``) + - ``preparse`` -- if ``True``, then produce code to be evaluated with + Sage's preparser; if ``False``, then produce standard + Python code; if ``None``, then produce code that will work + either with or without the preparser. (default: ``True``) + - ``pedantic`` -- if ``True``, then carefully ensures that the result has + at least as much sharing as the result of cPickle + (it may have more, for immutable objects). (default: ``False``) Exactly one of ``pickle`` (a string containing a pickle) or ``file`` (the filename of a pickle) must be provided. @@ -263,16 +262,16 @@ def explain_pickle_string(pickle, in_current_sage=False, default_assumptions=False, eval=False, preparse=True, pedantic=False): r""" - This is a helper function for explain_pickle. It takes a decompressed + This is a helper function for :func:`explain_pickle`. It takes a decompressed pickle string as input; other than that, its options are all the same - as explain_pickle. + as :func:`explain_pickle`. EXAMPLES:: sage: sage.misc.explain_pickle.explain_pickle_string(dumps("Hello, world", compress=False)) 'Hello, world' - (See the documentation for ``explain_pickle`` for many more examples.) + (See the documentation for :func:`explain_pickle` for many more examples.) """ sib = SageInputBuilder(preparse=preparse) @@ -321,17 +320,19 @@ def name_is_valid(name): class PickleObject(): r""" - Pickles have a stack-based virtual machine. The explain_pickle - pickle interpreter mostly uses SageInputExpressions, from sage_input, + Pickles have a stack-based virtual machine. The :func:`explain_pickle` + pickle interpreter mostly uses :class:`sage.misc.sage_input.SageInputExpression` objects as the stack values. However, sometimes we want some more information about the value on the stack, so that we can generate better (prettier, less confusing) code. In such cases, we push - a PickleObject instead of a SageInputExpression. A PickleObject + a :class:`PickleObject` instead of a :class:`~sage.misc.sage_input.SageInputExpression`. + A :class:`PickleObject` contains a value (which may be a standard Python value, or a - PickleDict or PickleInstance), an expression (a SageInputExpression), + :class:`PickleDict` or :class:`PickleInstance`), an expression + (a :class:`~sage.misc.sage_input.SageInputExpression`), and an "immutable" flag (which checks whether this object - has been converted to a SageInputExpression; if it has, then we - must not mutate the object, since the SageInputExpression would not + has been converted to a :class:`SageInputExpression`; if it has, then we + must not mutate the object, since the :class:`SageInputExpression` would not reflect the changes). """ @@ -375,9 +376,9 @@ def _sage_input_(self, sib, coerced): class PickleDict(): r""" - An object which can be used as the value of a PickleObject. The items + An object which can be used as the value of a :class:`PickleObject`. The items is a list of key-value pairs, where the keys and values are - SageInputExpressions. We use this to help construct dictionary literals, + :class:`SageInputExpression` objects. We use this to help construct dictionary literals, instead of always starting with an empty dictionary and assigning to it. """ @@ -395,8 +396,8 @@ def __init__(self, items): class PickleInstance(): r""" - An object which can be used as the value of a PickleObject. Unlike - other possible values of a PickleObject, a PickleInstance doesn't represent + An object which can be used as the value of a :class:`PickleObject`. Unlike + other possible values of a :class:`PickleObject`, a :class:`PickleInstance` doesn't represent an exact value; instead, it gives the class (type) of the object. """ def __init__(self, klass): @@ -414,7 +415,7 @@ def __init__(self, klass): class PickleExplainer(): r""" An interpreter for the pickle virtual machine, that executes - symbolically and constructs SageInputExpressions instead of + symbolically and constructs :class:`SageInputExpression` objects instead of directly constructing values. """ def __init__(self, sib, in_current_sage=False, default_assumptions=False, @@ -448,7 +449,7 @@ def run_pickle(self, p): r""" Given an (uncompressed) pickle as a string, run the pickle in this virtual machine. Once a STOP has been executed, return - the result (a SageInputExpression representing code which, when + the result (a :class:`SageInputExpression` representing code which, when evaluated, will give the value of the pickle). EXAMPLES:: @@ -477,8 +478,8 @@ def run_pickle(self, p): def check_value(self, v): r""" - Check that the given value is either a SageInputExpression or a - PickleObject. Used for internal sanity checking. + Check that the given value is either a :class:`SageInputExpression` or a + :class:`PickleObject`. Used for internal sanity checking. EXAMPLES:: @@ -514,7 +515,7 @@ def push(self, v): def push_and_share(self, v): r""" Push a value onto the virtual machine's stack; also mark it as shared - for sage_input if we are in pedantic mode. + for :func:`sage_input` if we are in pedantic mode. EXAMPLES:: @@ -595,14 +596,15 @@ def pop_to_mark(self): def share(self, v): r""" - Mark a sage_input value as shared, if we are in pedantic mode. + Mark a :func:`sage_input` value as shared, if we are in pedantic mode. EXAMPLES:: sage: from sage.misc.explain_pickle import * sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() - sage: pe = PickleExplainer(sib, in_current_sage=True, default_assumptions=False, pedantic=True) + sage: pe = PickleExplainer(sib, in_current_sage=True, + ....: default_assumptions=False, pedantic=True) sage: v = sib(7) sage: v._sie_share False @@ -617,15 +619,16 @@ def share(self, v): def is_mutable_pickle_object(self, v): r""" - Test whether a PickleObject is mutable (has never been converted - to a SageInputExpression). + Test whether a :class:`PickleObject` is mutable (has never been converted + to a :class:`SageInputExpression`). EXAMPLES:: sage: from sage.misc.explain_pickle import * sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() - sage: pe = PickleExplainer(sib, in_current_sage=True, default_assumptions=False, pedantic=True) + sage: pe = PickleExplainer(sib, in_current_sage=True, + ....: default_assumptions=False, pedantic=True) sage: v = PickleObject(1, sib(1)) sage: pe.is_mutable_pickle_object(v) True @@ -1394,7 +1397,12 @@ def GLOBAL(self, name): # OK, we know what module and function name will actually # be used, as well as the actual function. # Is this already available at the command line? - cmdline_f = getattr(sage.all, func, None) + try: + import sage.all + except ImportError: + cmdline_f = None + else: + cmdline_f = getattr(sage.all, func, None) if cmdline_f is f: self.push(PickleObject(f, self.sib.name(func))) return @@ -2368,7 +2376,7 @@ def UNICODE(self, s): def unpickle_newobj(klass, args): r""" Create a new object; this corresponds to the C code - klass->tp_new(klass, args, NULL). Used by ``explain_pickle``. + ``klass->tp_new(klass, args, NULL)``. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2413,7 +2421,7 @@ def pers_load(id): def unpickle_build(obj, state): r""" - Set the state of an object. Used by ``explain_pickle``. + Set the state of an object. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2447,8 +2455,8 @@ def unpickle_build(obj, state): def unpickle_instantiate(fn, args): r""" - Instantiate a new object of class fn with arguments args. Almost always - equivalent to ``fn(*args)``. Used by ``explain_pickle``. + Instantiate a new object of class ``fn`` with arguments ``args``. Almost always + equivalent to ``fn(*args)``. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2469,7 +2477,7 @@ def unpickle_persistent(s): r""" Takes an integer index and returns the persistent object with that index; works by calling whatever callable is stored in - unpickle_persistent_loader. Used by ``explain_pickle``. + ``unpickle_persistent_loader``. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2484,7 +2492,7 @@ def unpickle_persistent(s): def unpickle_extension(code): r""" Takes an integer index and returns the extension object with that - index. Used by ``explain_pickle``. + index. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2512,7 +2520,7 @@ def unpickle_appends(lst, vals): r""" Given a list (or list-like object) and a sequence of values, appends the values to the end of the list. This is careful to do so using the - exact same technique that cPickle would use. Used by ``explain_pickle``. + exact same technique that cPickle would use. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2532,7 +2540,9 @@ def unpickle_appends(lst, vals): def test_pickle(p, verbose_eval=False, pedantic=False, args=()): r""" - Tests explain_pickle on a given pickle p. p can be: + Test :func:`explain_pickle` on a given pickle ``p``. + + ``p`` can be: - a string containing an uncompressed pickle (which will always end with a '.') @@ -2542,14 +2552,14 @@ def test_pickle(p, verbose_eval=False, pedantic=False, args=()): the stack (using persistent IDs), run the pickle fragment, and then STOP (if the string 'mark' occurs in args, then a mark will be pushed) - - an arbitrary object; test_pickle will pickle the object + - an arbitrary object; :func:`test_pickle` will pickle the object - Once it has a pickle, test_pickle will print the pickle's - disassembly, run explain_pickle with in_current_sage=True and - False, print the results, evaluate the results, unpickle the + Once it has a pickle, :func:`test_pickle` will print the pickle's + disassembly, run :func:`explain_pickle` with ``in_current_sage=True`` and + ``False``, print the results, evaluate the results, unpickle the object with cPickle, and compare all three results. - If verbose_eval is True, then test_pickle will print messages + If ``verbose_eval`` is ``True``, then :func:`test_pickle` will print messages before evaluating the pickles; this is to allow for tests where the unpickling prints messages (to verify that the same operations occur in all cases). @@ -2636,7 +2646,7 @@ def pers_load(s): class EmptyOldstyleClass: r""" A featureless old-style class (does not inherit from object); used for - testing explain_pickle. + testing :func:`explain_pickle`. """ def __repr__(self): r""" @@ -2674,7 +2684,7 @@ def __hash__(self): class EmptyNewstyleClass(): r""" A featureless new-style class (inherits from object); used for - testing explain_pickle. + testing :func:`explain_pickle`. """ def __repr__(self): r""" @@ -2696,8 +2706,8 @@ def __repr__(self): class TestReduceGetinitargs: r""" - An old-style class with a __getinitargs__ method. Used for testing - explain_pickle. + An old-style class with a :func:`__getinitargs__` method. Used for testing + :func:`explain_pickle`. """ def __init__(self): r""" @@ -2748,8 +2758,8 @@ def __repr__(self): class TestReduceNoGetinitargs: r""" - An old-style class with no __getinitargs__ method. Used for testing - explain_pickle. + An old-style class with no :meth:`__getinitargs__` method. Used for testing + :func:`explain_pickle`. """ def __init__(self): r""" @@ -2786,8 +2796,8 @@ def __repr__(self): class TestAppendList(list): r""" - A subclass of list, with deliberately-broken append and extend methods. - Used for testing explain_pickle. + A subclass of :class:`list`, with deliberately-broken append and extend methods. + Used for testing :func:`explain_pickle`. """ def append(self): r""" @@ -2835,7 +2845,7 @@ def extend(self): class TestAppendNonlist(): r""" A list-like class, carefully designed to test exact unpickling - behavior. Used for testing explain_pickle. + behavior. Used for testing :func:`explain_pickle`. """ def __init__(self): r""" @@ -2918,8 +2928,8 @@ def __repr__(self): class TestBuild(): r""" - A simple class with a __getstate__ but no __setstate__. Used for testing - explain_pickle. + A simple class with a :meth:`__getstate__` but no :meth:`__setstate__`. Used for testing + :func:`explain_pickle`. """ def __getstate__(self): r""" @@ -2955,8 +2965,8 @@ def __repr__(self): class TestBuildSetstate(TestBuild): r""" - A simple class with a __getstate__ and a __setstate__. Used for testing - explain_pickle. + A simple class with a :meth:`__getstate__` and a :meth:`__setstate__`. Used for testing + :func:`explain_pickle`. """ def __setstate__(self, state): r""" @@ -2978,8 +2988,8 @@ def __setstate__(self, state): class TestGlobalOldName(): r""" A featureless new-style class. When you try to unpickle an instance - of this class, it is redirected to create a TestGlobalNewName instead. - Used for testing explain_pickle. + of this class, it is redirected to create a :class:`TestGlobalNewName` instead. + Used for testing :func:`explain_pickle`. EXAMPLES:: @@ -2993,8 +3003,8 @@ class TestGlobalOldName(): class TestGlobalNewName(): r""" A featureless new-style class. When you try to unpickle an instance - of TestGlobalOldName, it is redirected to create an instance of this - class instead. Used for testing explain_pickle. + of :class:`TestGlobalOldName`, it is redirected to create an instance of this + class instead. Used for testing :func:`explain_pickle`. EXAMPLES:: From ed209d1512e17332480d5e2108049d95a9057882 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 17 May 2023 13:20:30 -0700 Subject: [PATCH 144/463] Massive modularization fixes --- ...ticle_heuberger_krenn_kropf_fsm-in-sage.py | 46 +++++++++---------- src/sage/tests/benchmark.py | 1 + src/sage/tests/book_stein_ent.py | 16 +++---- src/sage/tests/gosper-sum.py | 1 + src/sage/tests/symbolic-series.py | 1 + src/sage/tests/sympy.py | 1 + 6 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py b/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py index 6125930bd45..2df7199c47b 100644 --- a/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py +++ b/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py @@ -505,21 +505,21 @@ Sage example in fsm-in-sage.tex, line 1091:: - sage: var('y') + sage: var('y') # optional - sage.symbolic y - sage: def am_entry(trans): + sage: def am_entry(trans): # optional - sage.symbolic ....: return y^add(trans.word_out) / 2 - sage: A = W.adjacency_matrix(entry=am_entry) + sage: A = W.adjacency_matrix(entry=am_entry) # optional - sage.symbolic Sage example in fsm-in-sage.tex, line 1097:: - sage: latex.matrix_column_alignment('c') + sage: latex.matrix_column_alignment('c') # optional - sage.symbolic Sage example in fsm-in-sage.tex, line 1099:: - sage: latex(A) + sage: latex(A) # optional - sage.symbolic \left(\begin{array}{ccccccccc} \frac{1}{2} & \frac{1}{2} \, y^{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & \frac{1}{2} & \frac{1}{2} & 0 & 0 & 0 & 0 & 0 \\ @@ -535,95 +535,95 @@ Sage example in fsm-in-sage.tex, line 1109:: - sage: (pi_not_normalized,) = (A.subs(y=1) - A.parent().identity_matrix())\ + sage: (pi_not_normalized,) = (A.subs(y=1) - A.parent().identity_matrix())\ # optional - sage.symbolic ....: .left_kernel().basis() - sage: pi = pi_not_normalized / pi_not_normalized.norm(p=1) + sage: pi = pi_not_normalized / pi_not_normalized.norm(p=1) # optional - sage.symbolic Sage example in fsm-in-sage.tex, line 1110:: - sage: str(pi) + sage: str(pi) # optional - sage.symbolic '(1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9)' Sage example in fsm-in-sage.tex, line 1117:: - sage: expected_output = derivative(A, y).subs(y=1) * vector(len(W.states())*[1]) + sage: expected_output = derivative(A, y).subs(y=1) * vector(len(W.states())*[1]) # optional - sage.symbolic Sage example in fsm-in-sage.tex, line 1118:: - sage: latex(expected_output) + sage: latex(expected_output) # optional - sage.symbolic \left(1,\,0,\,0,\,0,\,\frac{1}{2},\,1,\,1,\,\frac{1}{2},\,1\right) Sage example in fsm-in-sage.tex, line 1126:: - sage: pi * expected_output + sage: pi * expected_output # optional - sage.symbolic 5/9 Sage example in fsm-in-sage.tex, line 1127:: - sage: latex(pi * expected_output) + sage: latex(pi * expected_output) # optional - sage.symbolic \frac{5}{9} Sage example in fsm-in-sage.tex, line 1129:: - sage: latex(pi * expected_output) + sage: latex(pi * expected_output) # optional - sage.symbolic \frac{5}{9} Sage example in fsm-in-sage.tex, line 1145:: - sage: var('k') + sage: var('k') # optional - sage.symbolic k - sage: moments = W.asymptotic_moments(k) + sage: moments = W.asymptotic_moments(k) # optional - sage.symbolic Sage example in fsm-in-sage.tex, line 1155:: - sage: latex(moments['expectation']) + sage: latex(moments['expectation']) # optional - sage.symbolic \frac{5}{9} \, k + \mathcal{O}\left(1\right) Sage example in fsm-in-sage.tex, line 1162:: - sage: latex(moments['variance']) + sage: latex(moments['variance']) # optional - sage.symbolic \frac{44}{243} \, k + \mathcal{O}\left(1\right) Sage example in fsm-in-sage.tex, line 1192:: - sage: expectation_binary = Id.asymptotic_moments(k)['expectation'] + sage: expectation_binary = Id.asymptotic_moments(k)['expectation'] # optional - sage.symbolic Sage example in fsm-in-sage.tex, line 1195:: - sage: latex(expectation_binary) + sage: latex(expectation_binary) # optional - sage.symbolic \frac{1}{2} \, k + \mathcal{O}\left(1\right) Sage example in fsm-in-sage.tex, line 1202:: - sage: expectation_NAF = Weight(NAF).asymptotic_moments(k)['expectation'] + sage: expectation_NAF = Weight(NAF).asymptotic_moments(k)['expectation'] # optional - sage.symbolic Sage example in fsm-in-sage.tex, line 1205:: - sage: latex(expectation_NAF) + sage: latex(expectation_NAF) # optional - sage.symbolic \frac{1}{3} \, k + \mathcal{O}\left(1\right) Sage example in fsm-in-sage.tex, line 1211:: - sage: Abs = transducers.abs([-1, 0, 1]) + sage: Abs = transducers.abs([-1, 0, 1]) # optional - sage.symbolic Sage example in fsm-in-sage.tex, line 1216:: - sage: latex(moments['expectation']) + sage: latex(moments['expectation']) # optional - sage.symbolic \frac{5}{9} \, k + \mathcal{O}\left(1\right) """ diff --git a/src/sage/tests/benchmark.py b/src/sage/tests/benchmark.py index 626388bd3ab..9f8d665e646 100644 --- a/src/sage/tests/benchmark.py +++ b/src/sage/tests/benchmark.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.symbolic """ Benchmarks diff --git a/src/sage/tests/book_stein_ent.py b/src/sage/tests/book_stein_ent.py index af4f77eb566..b03b5ad3a02 100644 --- a/src/sage/tests/book_stein_ent.py +++ b/src/sage/tests/book_stein_ent.py @@ -41,18 +41,18 @@ '12457502601536945540' sage: s[-20:] # the last 20 digits (long time) '11752880154053967871' -sage: prime_pi(6) +sage: prime_pi(6) # optional - sage.symbolic 3 -sage: prime_pi(100) +sage: prime_pi(100) # optional - sage.symbolic 25 -sage: prime_pi(3000000) +sage: prime_pi(3000000) # optional - sage.symbolic 216816 -sage: plot(prime_pi, 1,1000, rgbcolor=(0,0,1)) +sage: plot(prime_pi, 1,1000, rgbcolor=(0,0,1)) # optional - sage.plot sage.symbolic Graphics object consisting of 1 graphics primitive -sage: P = plot(Li, 2,10000, rgbcolor='purple') -sage: Q = plot(prime_pi, 2,10000, rgbcolor='black') -sage: R = plot(sqrt(x)*log(x),2,10000,rgbcolor='red') -sage: show(P+Q+R,xmin=0, figsize=[8,3]) +sage: P = plot(Li, 2,10000, rgbcolor='purple') # optional - sage.plot sage.symbolic +sage: Q = plot(prime_pi, 2,10000, rgbcolor='black') # optional - sage.plot sage.symbolic +sage: R = plot(sqrt(x)*log(x),2,10000,rgbcolor='red') # optional - sage.plot sage.symbolic +sage: show(P+Q+R,xmin=0, figsize=[8,3]) # optional - sage.plot sage.symbolic sage: R = Integers(3) sage: list(R) [0, 1, 2] diff --git a/src/sage/tests/gosper-sum.py b/src/sage/tests/gosper-sum.py index 76c2438d1c9..16d195dc71b 100644 --- a/src/sage/tests/gosper-sum.py +++ b/src/sage/tests/gosper-sum.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.symbolic """ Some tests about Gosper sums. diff --git a/src/sage/tests/symbolic-series.py b/src/sage/tests/symbolic-series.py index fb42289074d..4aff094d364 100644 --- a/src/sage/tests/symbolic-series.py +++ b/src/sage/tests/symbolic-series.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.symbolic """ Tests for the fast univariate series expansion in Pynac ------------------------------------------------------- diff --git a/src/sage/tests/sympy.py b/src/sage/tests/sympy.py index a42dcab7b2a..2f98f95e00c 100644 --- a/src/sage/tests/sympy.py +++ b/src/sage/tests/sympy.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sympy r""" TESTS: From ec4ac24baeededd93b395bc5420760adb967abca Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 20 May 2023 15:38:10 -0700 Subject: [PATCH 145/463] More # optional --- .../book_schilling_zabrocki_kschur_primer.py | 4 ++-- src/sage/tests/book_stein_ent.py | 24 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py index b0d56792851..55e6781d0f1 100644 --- a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py +++ b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py @@ -576,8 +576,8 @@ Sage example in ./kschurnotes/notes-mike-anne.tex, line 4055:: - sage: t = var('t') - sage: for mu in Partitions(5): + sage: t = var('t') # optional - sage.symbolic + sage: for mu in Partitions(5): # optional - sage.symbolic ....: print("{} {}".format(mu, sum(t^T.spin() for T in StrongTableaux(3,[4,1,1],mu)))) [5] 0 [4, 1] t diff --git a/src/sage/tests/book_stein_ent.py b/src/sage/tests/book_stein_ent.py index b03b5ad3a02..ed6b046de93 100644 --- a/src/sage/tests/book_stein_ent.py +++ b/src/sage/tests/book_stein_ent.py @@ -157,15 +157,15 @@ 1.09861228866811 sage: log(19683.0) / log(3.0) 9.00000000000000 -sage: plot(log, 0.1,10, rgbcolor=(0,0,1)) +sage: plot(log, 0.1, 10, rgbcolor=(0,0,1)) # optional - sage.plot Graphics object consisting of 1 graphics primitive sage: p = 53 sage: R = Integers(p) sage: a = R.multiplicative_generator() sage: v = sorted([(a^n, n) for n in range(p-1)]) -sage: G = plot(point(v,pointsize=50,rgbcolor=(0,0,1))) -sage: H = plot(line(v,rgbcolor=(0.5,0.5,0.5))) -sage: G + H +sage: G = plot(point(v,pointsize=50,rgbcolor=(0,0,1))) # optional - sage.plot +sage: H = plot(line(v,rgbcolor=(0.5,0.5,0.5))) # optional - sage.plot +sage: G + H # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: q = 93450983094850938450983409623 sage: q.is_prime() @@ -421,11 +421,11 @@ [1, 2, 7, 30, 157] sage: c = continued_fraction([1,1,1,1,1,1,1,1]) sage: v = [(i, c.p(i)/c.q(i)) for i in range(len(c))] -sage: P = point(v, rgbcolor=(0,0,1), pointsize=40) -sage: L = line(v, rgbcolor=(0.5,0.5,0.5)) -sage: L2 = line([(0,c.value()),(len(c)-1,c.value())], \ -....: thickness=0.5, rgbcolor=(0.7,0,0)) -sage: (L+L2+P).show(xmin=0,ymin=1) +sage: P = point(v, rgbcolor=(0,0,1), pointsize=40) # optional - sage.plot +sage: L = line(v, rgbcolor=(0.5,0.5,0.5)) # optional - sage.plot +sage: L2 = line([(0,c.value()), (len(c)-1,c.value())], # optional - sage.plot +....: thickness=0.5, rgbcolor=(0.7,0,0)) +sage: (L + L2 + P).show(xmin=0, ymin=1) # optional - sage.plot sage: def cf(bits): ....: x = (1 + sqrt(RealField(bits)(5))) / 2 ....: return continued_fraction(x) @@ -497,13 +497,13 @@ sage: E Elliptic Curve defined by y^2 = x^3 - 5*x + 4 over Rational Field -sage: P = E.plot(thickness=4,rgbcolor=(0.1,0.7,0.1)) -sage: P.show(figsize=[4,6]) +sage: P = E.plot(thickness=4,rgbcolor=(0.1,0.7,0.1)) # optional - sage.plot +sage: P.show(figsize=[4,6]) # optional - sage.plot sage: E = EllipticCurve(GF(37), [1,0]) sage: E Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 37 -sage: E.plot(pointsize=45) +sage: E.plot(pointsize=45) # optional - sage.plot Graphics object consisting of 1 graphics primitive sage: E = EllipticCurve([-5,4]) sage: P = E([1,0]); Q = E([0,2]) From e808a2c152e5b6b4ae5ba8b01cf6c5ed7d159537 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 20 May 2023 22:49:07 -0700 Subject: [PATCH 146/463] Fixups --- src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py b/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py index 2df7199c47b..1731530b9fc 100644 --- a/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py +++ b/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py @@ -535,8 +535,8 @@ Sage example in fsm-in-sage.tex, line 1109:: - sage: (pi_not_normalized,) = (A.subs(y=1) - A.parent().identity_matrix())\ # optional - sage.symbolic - ....: .left_kernel().basis() + sage: A1mI = (A.subs(y=1) - A.parent().identity_matrix()) # optional - sage.symbolic + sage: (pi_not_normalized,) = A1mI.left_kernel().basis() # optional - sage.symbolic sage: pi = pi_not_normalized / pi_not_normalized.norm(p=1) # optional - sage.symbolic From 446a1c971dd1b2f691c248714fc8dcd421b11539 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 13 Jul 2023 22:17:52 -0700 Subject: [PATCH 147/463] sage.tests: Add # needs --- ...ticle_heuberger_krenn_kropf_fsm-in-sage.py | 1 + src/sage/tests/arxiv_0812_2725.py | 1 + .../book_schilling_zabrocki_kschur_primer.py | 1 + src/sage/tests/book_stein_ent.py | 45 +++--- src/sage/tests/book_stein_modform.py | 1 + src/sage/tests/cmdline.py | 143 ++++++++++-------- src/sage/tests/combinatorial_hopf_algebras.py | 1 + src/sage/tests/finite_poset.py | 1 + src/sage/tests/gap_packages.py | 1 + src/sage/tests/lazy_imports.py | 1 + src/sage/tests/modular_group_cohomology.py | 35 ++--- src/sage/tests/numpy.py | 1 + src/sage/tests/parigp.py | 1 + 13 files changed, 133 insertions(+), 100 deletions(-) diff --git a/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py b/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py index 1731530b9fc..3828fa50d1c 100644 --- a/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py +++ b/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.graphs r""" This file contains doctests of the article :: diff --git a/src/sage/tests/arxiv_0812_2725.py b/src/sage/tests/arxiv_0812_2725.py index 3f304803c31..62217b3e8d8 100644 --- a/src/sage/tests/arxiv_0812_2725.py +++ b/src/sage/tests/arxiv_0812_2725.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.combinat r""" Sage code for computing k-distant crossing numbers. diff --git a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py index 55e6781d0f1..12bdc5861cf 100644 --- a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py +++ b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.combinat r""" This file contains doctests for the Chapter "k-Schur function primer" for the book "k-Schur functions and affine Schubert calculus" diff --git a/src/sage/tests/book_stein_ent.py b/src/sage/tests/book_stein_ent.py index ed6b046de93..6d8a7306878 100644 --- a/src/sage/tests/book_stein_ent.py +++ b/src/sage/tests/book_stein_ent.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.pari """ This file contains all the example code from the published book 'Elementary Number Theory: Primes, Congruences, and Secrets' by @@ -41,18 +42,21 @@ '12457502601536945540' sage: s[-20:] # the last 20 digits (long time) '11752880154053967871' -sage: prime_pi(6) # optional - sage.symbolic + +sage: # needs sage.symbolic +sage: prime_pi(6) 3 -sage: prime_pi(100) # optional - sage.symbolic +sage: prime_pi(100) 25 -sage: prime_pi(3000000) # optional - sage.symbolic +sage: prime_pi(3000000) 216816 -sage: plot(prime_pi, 1,1000, rgbcolor=(0,0,1)) # optional - sage.plot sage.symbolic +sage: plot(prime_pi, 1,1000, rgbcolor=(0,0,1)) # needs sage.plot Graphics object consisting of 1 graphics primitive -sage: P = plot(Li, 2,10000, rgbcolor='purple') # optional - sage.plot sage.symbolic -sage: Q = plot(prime_pi, 2,10000, rgbcolor='black') # optional - sage.plot sage.symbolic -sage: R = plot(sqrt(x)*log(x),2,10000,rgbcolor='red') # optional - sage.plot sage.symbolic -sage: show(P+Q+R,xmin=0, figsize=[8,3]) # optional - sage.plot sage.symbolic +sage: P = plot(Li, 2,10000, rgbcolor='purple') # needs sage.plot +sage: Q = plot(prime_pi, 2,10000, rgbcolor='black') # needs sage.plot +sage: R = plot(sqrt(x)*log(x),2,10000,rgbcolor='red') # needs sage.plot +sage: show(P+Q+R,xmin=0, figsize=[8,3]) # needs sage.plot + sage: R = Integers(3) sage: list(R) [0, 1, 2] @@ -157,15 +161,15 @@ 1.09861228866811 sage: log(19683.0) / log(3.0) 9.00000000000000 -sage: plot(log, 0.1, 10, rgbcolor=(0,0,1)) # optional - sage.plot +sage: plot(log, 0.1, 10, rgbcolor=(0,0,1)) # needs sage.plot Graphics object consisting of 1 graphics primitive sage: p = 53 sage: R = Integers(p) sage: a = R.multiplicative_generator() sage: v = sorted([(a^n, n) for n in range(p-1)]) -sage: G = plot(point(v,pointsize=50,rgbcolor=(0,0,1))) # optional - sage.plot -sage: H = plot(line(v,rgbcolor=(0.5,0.5,0.5))) # optional - sage.plot -sage: G + H # optional - sage.plot +sage: G = plot(point(v,pointsize=50,rgbcolor=(0,0,1))) # needs sage.plot +sage: H = plot(line(v,rgbcolor=(0.5,0.5,0.5))) # needs sage.plot +sage: G + H # needs sage.plot Graphics object consisting of 2 graphics primitives sage: q = 93450983094850938450983409623 sage: q.is_prime() @@ -421,11 +425,14 @@ [1, 2, 7, 30, 157] sage: c = continued_fraction([1,1,1,1,1,1,1,1]) sage: v = [(i, c.p(i)/c.q(i)) for i in range(len(c))] -sage: P = point(v, rgbcolor=(0,0,1), pointsize=40) # optional - sage.plot -sage: L = line(v, rgbcolor=(0.5,0.5,0.5)) # optional - sage.plot -sage: L2 = line([(0,c.value()), (len(c)-1,c.value())], # optional - sage.plot + +sage: # needs sage.plot +sage: P = point(v, rgbcolor=(0,0,1), pointsize=40) +sage: L = line(v, rgbcolor=(0.5,0.5,0.5)) +sage: L2 = line([(0,c.value()), (len(c)-1,c.value())], ....: thickness=0.5, rgbcolor=(0.7,0,0)) -sage: (L + L2 + P).show(xmin=0, ymin=1) # optional - sage.plot +sage: (L + L2 + P).show(xmin=0, ymin=1) + sage: def cf(bits): ....: x = (1 + sqrt(RealField(bits)(5))) / 2 ....: return continued_fraction(x) @@ -497,13 +504,13 @@ sage: E Elliptic Curve defined by y^2 = x^3 - 5*x + 4 over Rational Field -sage: P = E.plot(thickness=4,rgbcolor=(0.1,0.7,0.1)) # optional - sage.plot -sage: P.show(figsize=[4,6]) # optional - sage.plot +sage: P = E.plot(thickness=4,rgbcolor=(0.1,0.7,0.1)) # needs sage.plot +sage: P.show(figsize=[4,6]) # needs sage.plot sage: E = EllipticCurve(GF(37), [1,0]) sage: E Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 37 -sage: E.plot(pointsize=45) # optional - sage.plot +sage: E.plot(pointsize=45) # needs sage.plot Graphics object consisting of 1 graphics primitive sage: E = EllipticCurve([-5,4]) sage: P = E([1,0]); Q = E([0,2]) diff --git a/src/sage/tests/book_stein_modform.py b/src/sage/tests/book_stein_modform.py index a43391ba028..56ee188cd50 100644 --- a/src/sage/tests/book_stein_modform.py +++ b/src/sage/tests/book_stein_modform.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.modular """ This file contains a bunch of tests extracted from the published book 'Modular Forms: a Computational Approach' by William Stein, AMS 2007. diff --git a/src/sage/tests/cmdline.py b/src/sage/tests/cmdline.py index 5a06a349f63..5a577d1ff83 100644 --- a/src/sage/tests/cmdline.py +++ b/src/sage/tests/cmdline.py @@ -110,62 +110,68 @@ def test_executable(args, input="", timeout=100.0, pydebug_ignore_warnings=False Run Sage itself with various options:: - sage: (out, err, ret) = test_executable([ # long time + sage: # long time + sage: (out, err, ret) = test_executable([ ....: "sage"], pydebug_ignore_warnings=True) - sage: out.find(version()) >= 0 # long time + sage: out.find(version()) >= 0 True - sage: err # long time + sage: err '' - sage: ret # long time + sage: ret 0 - sage: (out, err, ret) = test_executable([ # long time + sage: # long time + sage: (out, err, ret) = test_executable([ ....: "sage"], "3^33\n", pydebug_ignore_warnings=True) - sage: out.find(version()) >= 0 # long time + sage: out.find(version()) >= 0 True - sage: out.find("5559060566555523") >= 0 # long time + sage: out.find("5559060566555523") >= 0 True - sage: err # long time + sage: err '' - sage: ret # long time + sage: ret 0 - sage: (out, err, ret) = test_executable([ # long time + sage: # long time + sage: (out, err, ret) = test_executable([ ....: "sage", "-q"], "3^33\n", pydebug_ignore_warnings=True) - sage: out.find(version()) >= 0 # long time + sage: out.find(version()) >= 0 False - sage: out.find("5559060566555523") >= 0 # long time + sage: out.find("5559060566555523") >= 0 True - sage: err # long time + sage: err '' - sage: ret # long time + sage: ret 0 - sage: (out, err, ret) = test_executable([ # long time + sage: # long time + sage: (out, err, ret) = test_executable([ ....: "sage", "-c", "print(3^33)"]) - sage: print(out) # long time + sage: print(out) 5559060566555523 - sage: err # long time + sage: err '' - sage: ret # long time + sage: ret 0 - sage: (out, err, ret) = test_executable([ # long time + sage: # long time + sage: (out, err, ret) = test_executable([ ....: "sage", "--min", "-c", "print(3^33)"]) - sage: print(out) # long time + sage: print(out) 5559060566555523 - sage: err # long time + sage: err '' - sage: ret # long time + sage: ret 0 - sage: (out, err, ret) = test_executable([ # long time + sage: # long time + sage: (out, err, ret) = test_executable([ ....: "sage", "--startuptime"]) - sage: out.find("Slowest module import") >= 0 # long time + sage: out.find("Slowest module import") >= 0 True - sage: err # long time + sage: err '' - sage: ret # long time + sage: ret 0 Test help:: @@ -208,25 +214,27 @@ def test_executable(args, input="", timeout=100.0, pydebug_ignore_warnings=False sage: ret 0 - sage: (out, err, ret) = test_executable(["sage", "--root"]) # optional - sage_spkg - sage: len(out) >= 2 # at least one character + newline; optional - sage_spkg + sage: # optional - sage_spkg + sage: (out, err, ret) = test_executable(["sage", "--root"]) + sage: len(out) >= 2 True - sage: err # optional - sage_spkg + sage: err '' - sage: ret # optional - sage_spkg + sage: ret 0 Test ``sage --info [packages]``:: - sage: out, err, ret = test_executable(["sage", "--info", "sqlite"]) # optional - sage_spkg - sage: print(out) # optional - sage_spkg + sage: # optional - sage_spkg + sage: out, err, ret = test_executable(["sage", "--info", "sqlite"]) + sage: print(out) sqlite... SQLite is a software library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. ... - sage: err # optional - sage_spkg + sage: err '' - sage: ret # optional - sage_spkg + sage: ret 0 Test ``sage-run`` on a Python file, both with an absolute and with a relative path:: @@ -292,17 +300,18 @@ def test_executable(args, input="", timeout=100.0, pydebug_ignore_warnings=False Now test my_script.sage and the preparsed version my_script.sage.py:: - sage: (out, err, ret) = test_executable([ # long time + sage: # long time + sage: (out, err, ret) = test_executable([ ....: "sage", "-t", "--optional=sage", script]) - sage: ret # long time + sage: ret 0 - sage: out.find("All tests passed!") >= 0 # long time + sage: out.find("All tests passed!") >= 0 True - sage: (out, err, ret) = test_executable([ # long time + sage: (out, err, ret) = test_executable([ ....: "sage", "-t", "--optional=sage", script_py]) - sage: ret # long time + sage: ret 0 - sage: out.find("All tests passed!") >= 0 # long time + sage: out.find("All tests passed!") >= 0 True Test that the coding line and doctest are preserved:: @@ -438,13 +447,14 @@ def test_executable(args, input="", timeout=100.0, pydebug_ignore_warnings=False sage: ret 42 - sage: (out, err, ret) = test_executable([ # long time + sage: # long time + sage: (out, err, ret) = test_executable([ ....: "sage", "--ipython"], "\n3**33\n", pydebug_ignore_warnings=True) - sage: out.find("5559060566555523") >= 0 # long time + sage: out.find("5559060566555523") >= 0 True - sage: err # long time + sage: err '' - sage: ret # long time + sage: ret 0 sage: (out, err, ret) = test_executable(["sage", "--python"], "print(3^33)\n") @@ -494,13 +504,14 @@ def test_executable(args, input="", timeout=100.0, pydebug_ignore_warnings=False sage: ret 0 - sage: (out, err, ret) = test_executable([ # long time + sage: # long time + sage: (out, err, ret) = test_executable([ ....: "sage", "--gap", "-q"], "Size(SymmetricGroup(5));\n") - sage: out # long time + sage: out '120\n' - sage: err.replace('gap: halving pool size.', '').strip() # long time + sage: err.replace('gap: halving pool size.', '').strip() '' - sage: ret # long time + sage: ret 0 sage: (out, err, ret) = test_executable([ # long time # optional - gdb @@ -551,12 +562,13 @@ def test_executable(args, input="", timeout=100.0, pydebug_ignore_warnings=False sage: ret 0 - sage: (out, err, ret) = test_executable(["sage", "--R", "--version"]) # optional - r - sage: out.find("R version ") >= 0 # optional - r + sage: # optional - r + sage: (out, err, ret) = test_executable(["sage", "--R", "--version"]) + sage: out.find("R version ") >= 0 True - sage: err # optional - r + sage: err '' - sage: ret # optional - r + sage: ret 0 sage: (out, err, ret) = test_executable(["sage", "--sqlite3", "--version"]) @@ -569,28 +581,31 @@ def test_executable(args, input="", timeout=100.0, pydebug_ignore_warnings=False Check some things requiring an internet connection:: - sage: (out, err, ret) = test_executable(["sage", "--standard"]) # optional - internet - sage: out.find("cython") >= 0 # optional - internet + sage: # optional - internet + sage: (out, err, ret) = test_executable(["sage", "--standard"]) + sage: out.find("cython") >= 0 True - sage: err # optional - internet + sage: err '' - sage: ret # optional - internet + sage: ret 0 - sage: (out, err, ret) = test_executable(["sage", "--optional"]) # optional - internet - sage: out.find("database_cremona_ellcurve") >= 0 # optional - internet + sage: # optional - internet + sage: (out, err, ret) = test_executable(["sage", "--optional"]) + sage: out.find("database_cremona_ellcurve") >= 0 True - sage: err # optional - internet + sage: err '' - sage: ret # optional - internet + sage: ret 0 - sage: (out, err, ret) = test_executable(["sage", "--experimental"]) # optional - internet - sage: out.find("valgrind") >= 0 # optional - internet + sage: # optional - internet + sage: (out, err, ret) = test_executable(["sage", "--experimental"]) + sage: out.find("valgrind") >= 0 True - sage: err # optional - internet + sage: err '' - sage: ret # optional - internet + sage: ret 0 Check an illegal command line option. This outputs an error to stdout, diff --git a/src/sage/tests/combinatorial_hopf_algebras.py b/src/sage/tests/combinatorial_hopf_algebras.py index 6ac40f7aad5..33c0472f404 100644 --- a/src/sage/tests/combinatorial_hopf_algebras.py +++ b/src/sage/tests/combinatorial_hopf_algebras.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.combinat sage.modules r""" Tests For Combinatorial Hopf Algebras diff --git a/src/sage/tests/finite_poset.py b/src/sage/tests/finite_poset.py index 11092c3d966..e6733ef7f5f 100644 --- a/src/sage/tests/finite_poset.py +++ b/src/sage/tests/finite_poset.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.graphs sage.modules """ This file contains test functions that can be used to search bugs by testing random finite posets and lattices. diff --git a/src/sage/tests/gap_packages.py b/src/sage/tests/gap_packages.py index c302b169b8a..b13bba24a83 100644 --- a/src/sage/tests/gap_packages.py +++ b/src/sage/tests/gap_packages.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.gap """ Test the optional GAP packages diff --git a/src/sage/tests/lazy_imports.py b/src/sage/tests/lazy_imports.py index e9bd2aea2c0..8ea93a15ab5 100644 --- a/src/sage/tests/lazy_imports.py +++ b/src/sage/tests/lazy_imports.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.all r""" TESTS: diff --git a/src/sage/tests/modular_group_cohomology.py b/src/sage/tests/modular_group_cohomology.py index be00146dc6f..35bc8b5387f 100644 --- a/src/sage/tests/modular_group_cohomology.py +++ b/src/sage/tests/modular_group_cohomology.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - p_group_cohomology r""" Tests for the optional ``p_group_cohomology`` package. @@ -7,26 +8,26 @@ TESTS:: - sage: from pGroupCohomology import CohomologyRing # optional - p_group_cohomology + sage: from pGroupCohomology import CohomologyRing Computation of a modular cohomology ring of a prime power group in characteristic 2, and comparison with stored result in a database:: - sage: CohomologyRing.set_workspace(tmp_dir()) # optional - p_group_cohomology - sage: H = CohomologyRing(64,14,from_scratch=True) # optional - p_group_cohomology - sage: H.make() # optional - p_group_cohomology - sage: CohomologyRing.set_workspace(tmp_dir()) # optional - p_group_cohomology - sage: H0 = CohomologyRing(64,14) # optional - p_group_cohomology - sage: H.is_isomorphic(H0) # optional - p_group_cohomology + sage: CohomologyRing.set_workspace(tmp_dir()) + sage: H = CohomologyRing(64,14,from_scratch=True) + sage: H.make() + sage: CohomologyRing.set_workspace(tmp_dir()) + sage: H0 = CohomologyRing(64,14) + sage: H.is_isomorphic(H0) ('1*a_2_1', '1*c_2_2', '1*c_4_4', '1*a_1_0', '1*a_1_1', '1*a_3_3') Computation of a modular cohomology ring of a prime power group in odd characteristic, and some algebraic constructions in the cohomology ring:: - sage: H = CohomologyRing(27,4) # optional - p_group_cohomology - sage: H.make() # optional - p_group_cohomology - sage: print(H) # optional - p_group_cohomology + sage: H = CohomologyRing(27,4) + sage: H.make() + sage: print(H) Cohomology ring of Extraspecial 3-group of order 27 and exponent 9 with coefficients in GF(3) @@ -45,14 +46,14 @@ b_2_1*a_3_1, a_1_0*a_5_1, a_3_1*a_5_1] - sage: H.5.massey_power() # optional - p_group_cohomology + sage: H.5.massey_power() : 8-Cocycle in H^*(M27; GF(3)) - sage: H.5.massey_power().as_polynomial() # optional - p_group_cohomology + sage: H.5.massey_power().as_polynomial() '-c_6_2*a_1_0*a_1_1' - sage: H.essential_ideal() # optional - p_group_cohomology + sage: H.essential_ideal() a_1_0*a_1_1, a_1_1*a_3_1 - sage: ascii_art(H.bar_code('LowerCentralSeries')[2]) # known bug (possibly, the output might be correct) # optional - p_group_cohomology + sage: ascii_art(H.bar_code('LowerCentralSeries')[2]) # known bug * *-* *-* @@ -61,11 +62,11 @@ Computation of a modular cohomology ring of a non prime power group in characteristic 2:: - sage: H = CohomologyRing(libgap.AlternatingGroup(6), # optional - p_group_cohomology + sage: H = CohomologyRing(libgap.AlternatingGroup(6), ....: GroupName="A(6)", prime=2, ....: from_scratch=True) - sage: H.make() # optional - p_group_cohomology - sage: print(H) # optional - p_group_cohomology + sage: H.make() + sage: print(H) Cohomology ring of A(6) with coefficients in GF(2) Computation complete diff --git a/src/sage/tests/numpy.py b/src/sage/tests/numpy.py index 8c1c42f385c..5cd78b148d2 100644 --- a/src/sage/tests/numpy.py +++ b/src/sage/tests/numpy.py @@ -1,3 +1,4 @@ +# sage.doctest: needs numpy r""" TESTS: diff --git a/src/sage/tests/parigp.py b/src/sage/tests/parigp.py index 4692b613de4..85eab45423f 100644 --- a/src/sage/tests/parigp.py +++ b/src/sage/tests/parigp.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.pari sage.modules r""" This file is meant to catch errors in the PARI/GP package which are not caught by any other tests. From 66dc5d282e2db6c2770b485bd4caf1c4f6ea1437 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 6 Aug 2023 18:32:57 -0700 Subject: [PATCH 148/463] Update # needs --- src/sage/doctest/fixtures.py | 4 ++-- src/sage/symbolic/function.pyx | 7 ++++--- .../tests/article_heuberger_krenn_kropf_fsm-in-sage.py | 4 ++-- src/sage/tests/book_schilling_zabrocki_kschur_primer.py | 9 +++++---- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/sage/doctest/fixtures.py b/src/sage/doctest/fixtures.py index a3b5e9edda7..9fbfdf86db9 100644 --- a/src/sage/doctest/fixtures.py +++ b/src/sage/doctest/fixtures.py @@ -80,9 +80,9 @@ def reproducible_repr(val): frozenset(['a', 'b', 'c', 'd']) sage: print(reproducible_repr([1, frozenset("cab"), set("bar"), 0])) [1, frozenset(['a', 'b', 'c']), set(['a', 'b', 'r']), 0] - sage: print(reproducible_repr({3.0:"three","2":"two",1:"one"})) + sage: print(reproducible_repr({3.0: "three", "2": "two", 1: "one"})) # optional - sage.rings.real_mpfr {'2': 'two', 1: 'one', 3.00000000000000: 'three'} - sage: print(reproducible_repr("foo\nbar")) # demonstrate default case + sage: print(reproducible_repr("foo\nbar")) # demonstrate default case 'foo\nbar' """ diff --git a/src/sage/symbolic/function.pyx b/src/sage/symbolic/function.pyx index 589c500d00d..792d81ebcc9 100644 --- a/src/sage/symbolic/function.pyx +++ b/src/sage/symbolic/function.pyx @@ -642,10 +642,11 @@ cdef class Function(SageObject): sage: hurwitz_zeta(1/2, b) hurwitz_zeta(1/2, [1.500000000 +/- 1.01e-10]) - sage: iv = RIF(1, 1.0001) - sage: airy_ai(iv) + sage: iv = RIF(1, 1.0001) # needs sage.rings.real_interval_field + + sage: airy_ai(iv) # needs sage.rings.real_interval_field airy_ai(1.0001?) - sage: airy_ai(CIF(iv)) + sage: airy_ai(CIF(iv)) # needs sage.rings.complex_interval_field airy_ai(1.0001?) """ if isinstance(x, (float, complex)): diff --git a/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py b/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py index 3828fa50d1c..6f92f85ec17 100644 --- a/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py +++ b/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py @@ -508,14 +508,14 @@ sage: var('y') # optional - sage.symbolic y - sage: def am_entry(trans): # optional - sage.symbolic + sage: def am_entry(trans): ....: return y^add(trans.word_out) / 2 sage: A = W.adjacency_matrix(entry=am_entry) # optional - sage.symbolic Sage example in fsm-in-sage.tex, line 1097:: - sage: latex.matrix_column_alignment('c') # optional - sage.symbolic + sage: latex.matrix_column_alignment('c') Sage example in fsm-in-sage.tex, line 1099:: diff --git a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py index 12bdc5861cf..2d092c45e59 100644 --- a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py +++ b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py @@ -84,16 +84,17 @@ Sage example in ./kschurnotes/notes-mike-anne.tex, line 406:: - sage: w = W.an_element(); w # long time + sage: # long time + sage: w = W.an_element(); w [ 2 0 0 1 -2] [ 2 0 0 0 -1] [ 1 1 0 0 -1] [ 1 0 1 0 -1] [ 1 0 0 1 -1] - sage: w.reduced_word() # long time + sage: w.reduced_word() [0, 1, 2, 3, 4] - sage: w = W.from_reduced_word([2,1,0]) # long time - sage: w.is_affine_grassmannian() # long time + sage: w = W.from_reduced_word([2,1,0]) + sage: w.is_affine_grassmannian() True Sage example in ./kschurnotes/notes-mike-anne.tex, line 464:: From 8b3ae0b6189650a6d841c0cd29f27cdff4ed966f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 6 Aug 2023 20:45:15 -0700 Subject: [PATCH 149/463] src/sage/tests: Update file-level doctest tag --- src/sage/tests/benchmark.py | 2 +- src/sage/tests/gosper-sum.py | 2 +- src/sage/tests/symbolic-series.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/tests/benchmark.py b/src/sage/tests/benchmark.py index 9f8d665e646..9445a3f7633 100644 --- a/src/sage/tests/benchmark.py +++ b/src/sage/tests/benchmark.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.symbolic +# sage.doctest: needs sage.symbolic """ Benchmarks diff --git a/src/sage/tests/gosper-sum.py b/src/sage/tests/gosper-sum.py index 16d195dc71b..84679ac0ff3 100644 --- a/src/sage/tests/gosper-sum.py +++ b/src/sage/tests/gosper-sum.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.symbolic +# sage.doctest: needs sage.symbolic """ Some tests about Gosper sums. diff --git a/src/sage/tests/symbolic-series.py b/src/sage/tests/symbolic-series.py index 4aff094d364..5e53d1e07af 100644 --- a/src/sage/tests/symbolic-series.py +++ b/src/sage/tests/symbolic-series.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.symbolic +# sage.doctest: needs sage.symbolic """ Tests for the fast univariate series expansion in Pynac ------------------------------------------------------- From f173e10bbfafa6dff97d5da42eac55f7211f22b9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 7 Aug 2023 22:44:23 -0700 Subject: [PATCH 150/463] src/sage/tests: sage -fixdoctests --only-tags --- ...ticle_heuberger_krenn_kropf_fsm-in-sage.py | 46 +++++++++---------- .../book_schilling_zabrocki_kschur_primer.py | 4 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py b/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py index 6f92f85ec17..d0a51a55eff 100644 --- a/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py +++ b/src/sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.graphs +# sage.doctest: needs sage.graphs sage.modules r""" This file contains doctests of the article :: @@ -506,11 +506,11 @@ Sage example in fsm-in-sage.tex, line 1091:: - sage: var('y') # optional - sage.symbolic + sage: var('y') # needs sage.symbolic y sage: def am_entry(trans): ....: return y^add(trans.word_out) / 2 - sage: A = W.adjacency_matrix(entry=am_entry) # optional - sage.symbolic + sage: A = W.adjacency_matrix(entry=am_entry) # needs sage.symbolic Sage example in fsm-in-sage.tex, line 1097:: @@ -520,7 +520,7 @@ Sage example in fsm-in-sage.tex, line 1099:: - sage: latex(A) # optional - sage.symbolic + sage: latex(A) # needs sage.symbolic \left(\begin{array}{ccccccccc} \frac{1}{2} & \frac{1}{2} \, y^{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & \frac{1}{2} & \frac{1}{2} & 0 & 0 & 0 & 0 & 0 \\ @@ -536,95 +536,95 @@ Sage example in fsm-in-sage.tex, line 1109:: - sage: A1mI = (A.subs(y=1) - A.parent().identity_matrix()) # optional - sage.symbolic - sage: (pi_not_normalized,) = A1mI.left_kernel().basis() # optional - sage.symbolic - sage: pi = pi_not_normalized / pi_not_normalized.norm(p=1) # optional - sage.symbolic + sage: A1mI = (A.subs(y=1) - A.parent().identity_matrix()) # needs sage.symbolic + sage: (pi_not_normalized,) = A1mI.left_kernel().basis() # needs sage.symbolic + sage: pi = pi_not_normalized / pi_not_normalized.norm(p=1) # needs sage.symbolic Sage example in fsm-in-sage.tex, line 1110:: - sage: str(pi) # optional - sage.symbolic + sage: str(pi) # needs sage.symbolic '(1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9)' Sage example in fsm-in-sage.tex, line 1117:: - sage: expected_output = derivative(A, y).subs(y=1) * vector(len(W.states())*[1]) # optional - sage.symbolic + sage: expected_output = derivative(A, y).subs(y=1) * vector(len(W.states())*[1]) # needs sage.symbolic Sage example in fsm-in-sage.tex, line 1118:: - sage: latex(expected_output) # optional - sage.symbolic + sage: latex(expected_output) # needs sage.symbolic \left(1,\,0,\,0,\,0,\,\frac{1}{2},\,1,\,1,\,\frac{1}{2},\,1\right) Sage example in fsm-in-sage.tex, line 1126:: - sage: pi * expected_output # optional - sage.symbolic + sage: pi * expected_output # needs sage.symbolic 5/9 Sage example in fsm-in-sage.tex, line 1127:: - sage: latex(pi * expected_output) # optional - sage.symbolic + sage: latex(pi * expected_output) # needs sage.symbolic \frac{5}{9} Sage example in fsm-in-sage.tex, line 1129:: - sage: latex(pi * expected_output) # optional - sage.symbolic + sage: latex(pi * expected_output) # needs sage.symbolic \frac{5}{9} Sage example in fsm-in-sage.tex, line 1145:: - sage: var('k') # optional - sage.symbolic + sage: var('k') # needs sage.symbolic k - sage: moments = W.asymptotic_moments(k) # optional - sage.symbolic + sage: moments = W.asymptotic_moments(k) # needs sage.symbolic Sage example in fsm-in-sage.tex, line 1155:: - sage: latex(moments['expectation']) # optional - sage.symbolic + sage: latex(moments['expectation']) # needs sage.symbolic \frac{5}{9} \, k + \mathcal{O}\left(1\right) Sage example in fsm-in-sage.tex, line 1162:: - sage: latex(moments['variance']) # optional - sage.symbolic + sage: latex(moments['variance']) # needs sage.symbolic \frac{44}{243} \, k + \mathcal{O}\left(1\right) Sage example in fsm-in-sage.tex, line 1192:: - sage: expectation_binary = Id.asymptotic_moments(k)['expectation'] # optional - sage.symbolic + sage: expectation_binary = Id.asymptotic_moments(k)['expectation'] # needs sage.symbolic Sage example in fsm-in-sage.tex, line 1195:: - sage: latex(expectation_binary) # optional - sage.symbolic + sage: latex(expectation_binary) # needs sage.symbolic \frac{1}{2} \, k + \mathcal{O}\left(1\right) Sage example in fsm-in-sage.tex, line 1202:: - sage: expectation_NAF = Weight(NAF).asymptotic_moments(k)['expectation'] # optional - sage.symbolic + sage: expectation_NAF = Weight(NAF).asymptotic_moments(k)['expectation'] # needs sage.symbolic Sage example in fsm-in-sage.tex, line 1205:: - sage: latex(expectation_NAF) # optional - sage.symbolic + sage: latex(expectation_NAF) # needs sage.symbolic \frac{1}{3} \, k + \mathcal{O}\left(1\right) Sage example in fsm-in-sage.tex, line 1211:: - sage: Abs = transducers.abs([-1, 0, 1]) # optional - sage.symbolic + sage: Abs = transducers.abs([-1, 0, 1]) # needs sage.symbolic Sage example in fsm-in-sage.tex, line 1216:: - sage: latex(moments['expectation']) # optional - sage.symbolic + sage: latex(moments['expectation']) # needs sage.symbolic \frac{5}{9} \, k + \mathcal{O}\left(1\right) """ diff --git a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py index 2d092c45e59..7b49e6769b1 100644 --- a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py +++ b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py @@ -578,8 +578,8 @@ Sage example in ./kschurnotes/notes-mike-anne.tex, line 4055:: - sage: t = var('t') # optional - sage.symbolic - sage: for mu in Partitions(5): # optional - sage.symbolic + sage: t = var('t') # needs sage.symbolic + sage: for mu in Partitions(5): # needs sage.symbolic ....: print("{} {}".format(mu, sum(t^T.spin() for T in StrongTableaux(3,[4,1,1],mu)))) [5] 0 [4, 1] t From 72fc063d3849ba8276b2089aa249a2e5c41cb501 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 12 Aug 2023 19:23:47 -0700 Subject: [PATCH 151/463] Update # needs --- src/sage/tests/finite_poset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/tests/finite_poset.py b/src/sage/tests/finite_poset.py index e6733ef7f5f..de92b818bab 100644 --- a/src/sage/tests/finite_poset.py +++ b/src/sage/tests/finite_poset.py @@ -105,7 +105,7 @@ def test_attrcall(name, L): sage: N5 = posets.PentagonPoset() sage: N5.is_modular() == test_attrcall('is_modular', N5) True - sage: N5.is_constructible_by_doublings('convex') == test_attrcall('is_doubling_convex', N5) + sage: N5.is_constructible_by_doublings('convex') == test_attrcall('is_doubling_convex', N5) # needs sage.combinat True """ if name == 'is_doubling_any': From 362e34f98480dcc0a211b31b373dd69759150e55 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 13 Aug 2023 12:31:51 -0700 Subject: [PATCH 152/463] sage --fixdoctests --no-test --- src/sage/tests/finite_poset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/tests/finite_poset.py b/src/sage/tests/finite_poset.py index de92b818bab..d04221dcc13 100644 --- a/src/sage/tests/finite_poset.py +++ b/src/sage/tests/finite_poset.py @@ -105,7 +105,7 @@ def test_attrcall(name, L): sage: N5 = posets.PentagonPoset() sage: N5.is_modular() == test_attrcall('is_modular', N5) True - sage: N5.is_constructible_by_doublings('convex') == test_attrcall('is_doubling_convex', N5) # needs sage.combinat + sage: N5.is_constructible_by_doublings('convex') == test_attrcall('is_doubling_convex', N5) # needs sage.combinat True """ if name == 'is_doubling_any': From f1951b399e581b901a6a128a15c77143dacfe859 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 27 Aug 2023 13:40:45 -0700 Subject: [PATCH 153/463] Update # needs --- src/sage/ext/fast_callable.pyx | 2 +- src/sage/libs/coxeter3/__init__.py | 1 + src/sage/libs/coxeter3/all__sagemath_coxeter3.py | 1 + src/sage/tests/book_schilling_zabrocki_kschur_primer.py | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index bad30e0e605..0a1439b7530 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -1645,7 +1645,7 @@ class IntegerPowerFunction(): pi^2 sage: square(I) # needs sage.symbolic -1 - sage: square(RIF(-1, 1)).str(style='brackets') + sage: square(RIF(-1, 1)).str(style='brackets') # needs sage.rings.real_interval_field '[0.0000000000000000 .. 1.0000000000000000]' sage: IntegerPowerFunction(-1) (^(-1)) diff --git a/src/sage/libs/coxeter3/__init__.py b/src/sage/libs/coxeter3/__init__.py index e69de29bb2d..61138b7bc1a 100644 --- a/src/sage/libs/coxeter3/__init__.py +++ b/src/sage/libs/coxeter3/__init__.py @@ -0,0 +1 @@ +# sage_setup: distribution = sagemath-coxeter3 diff --git a/src/sage/libs/coxeter3/all__sagemath_coxeter3.py b/src/sage/libs/coxeter3/all__sagemath_coxeter3.py index e69de29bb2d..61138b7bc1a 100644 --- a/src/sage/libs/coxeter3/all__sagemath_coxeter3.py +++ b/src/sage/libs/coxeter3/all__sagemath_coxeter3.py @@ -0,0 +1 @@ +# sage_setup: distribution = sagemath-coxeter3 diff --git a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py index 7b49e6769b1..4f91b77e036 100644 --- a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py +++ b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.combinat +# sage.doctest: needs sage.combinat sage.graphs sage.groups r""" This file contains doctests for the Chapter "k-Schur function primer" for the book "k-Schur functions and affine Schubert calculus" From ba7b9f2ed4d2e7b68a82ad610a542a876f005504 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 3 Sep 2023 23:46:22 -0700 Subject: [PATCH 154/463] Add # needs --- src/sage/tests/book_stein_ent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/tests/book_stein_ent.py b/src/sage/tests/book_stein_ent.py index 6d8a7306878..b4d593ff427 100644 --- a/src/sage/tests/book_stein_ent.py +++ b/src/sage/tests/book_stein_ent.py @@ -33,7 +33,7 @@ sage: n.is_prime() # this is instant False sage: p = 2^32582657 - 1 -sage: p.ndigits() +sage: p.ndigits() # needs sage.rings.real_interval_field 9808358 sage: s = p.str(10) # this takes a long time sage: len(s) # s is a very long string (long time) From c506b0690a8107e5ecb7ff4bff4d49f5b585d5c1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 4 Sep 2023 21:55:17 -0700 Subject: [PATCH 155/463] sage.structure: Update # needs --- src/sage/structure/coerce.pyx | 2 ++ src/sage/structure/factorization.py | 7 ++++--- src/sage/structure/parent_old.pyx | 2 +- src/sage/tests/book_stein_modform.py | 2 ++ 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index 8eed934aea3..1e7c4dd1a49 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -517,6 +517,8 @@ cdef class CoercionModel: Check that :trac:`8426` is fixed (see also :trac:`18076`):: sage: import numpy # needs numpy + + sage: # needs sage.rings.real_mpfr sage: x = polygen(RR) sage: numpy.float32('1.5') * x # needs numpy 1.50000000000000*x diff --git a/src/sage/structure/factorization.py b/src/sage/structure/factorization.py index 00571876e39..00ad9658e59 100644 --- a/src/sage/structure/factorization.py +++ b/src/sage/structure/factorization.py @@ -1232,9 +1232,10 @@ def __call__(self, *args, **kwds): sage: F(t=0) 0 - sage: R. = LaurentPolynomialRing(QQ, 1) # needs sage.modules - sage: F = ((x+2)/x**3).factor() # needs sage.modules - sage: F(x=4) # needs sage.modules + sage: # needs sage.libs.pari sage.modules + sage: R. = LaurentPolynomialRing(QQ, 1) + sage: F = ((x+2)/x**3).factor() + sage: F(x=4) 1/64 * 6 """ unit = self.__unit.subs(*args, **kwds) diff --git a/src/sage/structure/parent_old.pyx b/src/sage/structure/parent_old.pyx index c093febf375..c2afaa89000 100644 --- a/src/sage/structure/parent_old.pyx +++ b/src/sage/structure/parent_old.pyx @@ -52,7 +52,7 @@ cdef class Parent(parent.Parent): [(0, 0), (1, 0), (0, 1), (1, 1)] sage: MatrixSpace(GF(3), 1, 1).list() [[0], [1], [2]] - sage: DirichletGroup(3).list() # needs sage.modular + sage: DirichletGroup(3).list() # needs sage.libs.pari sage.modular [Dirichlet character modulo 3 of conductor 1 mapping 2 |--> 1, Dirichlet character modulo 3 of conductor 3 mapping 2 |--> -1] diff --git a/src/sage/tests/book_stein_modform.py b/src/sage/tests/book_stein_modform.py index 56ee188cd50..06e9717ded1 100644 --- a/src/sage/tests/book_stein_modform.py +++ b/src/sage/tests/book_stein_modform.py @@ -5,6 +5,7 @@ TESTS:: + sage: # needs sage.libs.gap sage: G = SL(2,ZZ); G Special Linear Group of degree 2 over Integer Ring sage: S, T = G.gens() @@ -14,6 +15,7 @@ sage: T [1 1] [0 1] + sage: delta_qexp(6) q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) sage: bernoulli(12) From 2a84d764aa25727305cc43eaae5208ba381cfc6a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 8 Sep 2023 22:59:40 -0700 Subject: [PATCH 156/463] sage.tests: Update # needs --- src/sage/tests/book_stein_modform.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/tests/book_stein_modform.py b/src/sage/tests/book_stein_modform.py index 06e9717ded1..667bb057c70 100644 --- a/src/sage/tests/book_stein_modform.py +++ b/src/sage/tests/book_stein_modform.py @@ -1,4 +1,5 @@ -# sage.doctest: needs sage.modular +# sage_setup: distribution = sagemath-repl +# sage.doctest: needs sage.libs.flint sage.modular """ This file contains a bunch of tests extracted from the published book 'Modular Forms: a Computational Approach' by William Stein, AMS 2007. From 3df8c81ab25b71785cc31ae53442d750d2cd58c4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 9 Sep 2023 13:27:47 -0700 Subject: [PATCH 157/463] sage.tests: Update # needs --- src/sage/tests/parigp.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/sage/tests/parigp.py b/src/sage/tests/parigp.py index 85eab45423f..1049149a147 100644 --- a/src/sage/tests/parigp.py +++ b/src/sage/tests/parigp.py @@ -40,32 +40,35 @@ Check that the optional PARI databases work:: - sage: gp.ellinit('"299998a1"') # optional -- pari_elldata + sage: # optional - pari_elldata + sage: gp.ellinit('"299998a1"') [1, 0, 1, 110, -3660, ...] - sage: E = EllipticCurve("1728ba1") - sage: gp(E).ellidentify() # optional -- pari_elldata + sage: E = EllipticCurve("1728ba1") # needs sage.schemes + sage: gp(E).ellidentify() # needs sage.schemes [["1728ba1", [0, 0, 0, -6, 6], [[1, 1]]], [1, 0, 0, 0]] - sage: pari("ellmodulareqn(211)") # optional -- pari_seadata - [x^212 + (-y^7 + 5207*y^6 - 10241606*y^5 + 9430560101*y^4 - 4074860204015*y^3 + 718868274900397*y^2 - 34897101275826114*y + 104096378056356968)*x^211... + sage: pari("ellmodulareqn(211)") # optional - pari_seadata + [x^212 + (-y^7 + 5207*y^6 - 10241606*y^5 + 9430560101*y^4 - 4074860204015*y^3 + + 718868274900397*y^2 - 34897101275826114*y + 104096378056356968)*x^211... The following requires the modular polynomials up to degree 223, while only those up to degree 199 come standard in Sage:: sage: p = next_prime(2^328) - sage: E = EllipticCurve(GF(p), [6,1]) - sage: E.cardinality() # long time (108s on sage.math, 2013), optional -- pari_seadata + sage: E = EllipticCurve(GF(p), [6,1]) # needs sage.schemes + sage: E.cardinality() # long time (108s on sage.math, 2013), optional - pari_seadata, needs sage.schemes 546812681195752981093125556779405341338292357723293496548601032930284335897180749997402596957976244 Create a number field with Galois group `A4`. Group `A4` corresponds to transitive group `(12,3)` in GAP:: + sage: # optional - pari_galpol sage: R. = PolynomialRing(ZZ) - sage: pol = pari("galoisgetpol(12,3)[1]") # optional -- pari_galpol - sage: K. = NumberField(R(pol)) # optional -- pari_galpol - sage: factor(K.discriminant()) # optional -- pari_galpol + sage: pol = pari("galoisgetpol(12,3)[1]") + sage: K. = NumberField(R(pol)) + sage: factor(K.discriminant()) 163^8 - sage: [F.degree() for F,a,b in K.subfields()] # optional -- pari_galpol + sage: [F.degree() for F,a,b in K.subfields()] [1, 3, 4, 4, 4, 4, 6, 6, 6, 12] sage: sorted([12/H.cardinality() for H in AlternatingGroup(4).subgroups()]) [1, 3, 4, 4, 4, 4, 6, 6, 6, 12] From dd20a8c21da480debe4633b043d51f765940bdba Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 9 Jun 2023 00:55:41 -0700 Subject: [PATCH 158/463] More # optional --- src/sage/sat/solvers/sat_lp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/sat/solvers/sat_lp.py b/src/sage/sat/solvers/sat_lp.py index d96ed62b125..dc1ff30d4b7 100644 --- a/src/sage/sat/solvers/sat_lp.py +++ b/src/sage/sat/solvers/sat_lp.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.numerical.mip r""" Solve SAT problems Integer Linear Programming From c9717a3cc1a726384a87368cd23f447b179f0988 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 17:49:17 -0700 Subject: [PATCH 159/463] Modularization fixes for imports --- src/sage/sat/converters/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/sat/converters/__init__.py b/src/sage/sat/converters/__init__.py index 70e0cdfdfaa..bb7b60bbb9c 100644 --- a/src/sage/sat/converters/__init__.py +++ b/src/sage/sat/converters/__init__.py @@ -1,2 +1,5 @@ +from sage.misc.lazy_import import lazy_import + from .anf2cnf import ANF2CNFConverter -from sage.rings.polynomial.pbori.cnf import CNFEncoder as PolyBoRiCNFEncoder + +lazy_import('sage.rings.polynomial.pbori.cnf', 'CNFEncoder', as_='PolyBoRiCNFEncoder') From cc1307b9a7ae98c60fee9faf59a773ca2d0828b2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 17:49:30 -0700 Subject: [PATCH 160/463] More # optional --- src/sage/sat/boolean_polynomials.py | 77 +++++++++++++++-------------- src/sage/sat/converters/polybori.py | 1 + src/sage/sat/solvers/satsolver.pyx | 12 ++--- 3 files changed, 47 insertions(+), 43 deletions(-) diff --git a/src/sage/sat/boolean_polynomials.py b/src/sage/sat/boolean_polynomials.py index 80b1a13d89c..2c5075d6251 100644 --- a/src/sage/sat/boolean_polynomials.py +++ b/src/sage/sat/boolean_polynomials.py @@ -71,8 +71,8 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): We construct a very small-scale AES system of equations:: - sage: sr = mq.SR(1,1,1,4,gf2=True,polybori=True) - sage: while True: # workaround (see :trac:`31891`) + sage: sr = mq.SR(1,1,1,4,gf2=True,polybori=True) # optional - sage.modules + sage: while True: # workaround (see :trac:`31891`) # optional - sage.modules ....: try: ....: F, s = sr.polynomial_system() ....: break @@ -81,66 +81,69 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): and pass it to a SAT solver:: - sage: from sage.sat.boolean_polynomials import solve as solve_sat # optional - pycryptosat - sage: s = solve_sat(F) # optional - pycryptosat - sage: F.subs(s[0]) # optional - pycryptosat + sage: from sage.sat.boolean_polynomials import solve as solve_sat + sage: s = solve_sat(F) # optional - pycryptosat sage.modules + sage: F.subs(s[0]) # optional - pycryptosat sage.modules Polynomial Sequence with 36 Polynomials in 0 Variables This time we pass a few options through to the converter and the solver:: - sage: s = solve_sat(F, c_max_vars_sparse=4, c_cutting_number=8) # optional - pycryptosat - sage: F.subs(s[0]) # optional - pycryptosat + sage: s = solve_sat(F, c_max_vars_sparse=4, c_cutting_number=8) # optional - pycryptosat sage.modules + sage: F.subs(s[0]) # optional - pycryptosat sage.modules Polynomial Sequence with 36 Polynomials in 0 Variables - We construct a very simple system with three solutions and ask for a specific number of solutions:: + We construct a very simple system with three solutions + and ask for a specific number of solutions:: - sage: B. = BooleanPolynomialRing() # optional - pycryptosat - sage: f = a*b # optional - pycryptosat - sage: l = solve_sat([f],n=1) # optional - pycryptosat - sage: len(l) == 1, f.subs(l[0]) # optional - pycryptosat + sage: B. = BooleanPolynomialRing() # optional - pycryptosat sage.modules + sage: f = a*b # optional - pycryptosat sage.modules + sage: l = solve_sat([f],n=1) # optional - pycryptosat sage.modules + sage: len(l) == 1, f.subs(l[0]) # optional - pycryptosat sage.modules (True, 0) - sage: l = solve_sat([a*b],n=2) # optional - pycryptosat - sage: len(l) == 2, f.subs(l[0]), f.subs(l[1]) # optional - pycryptosat + sage: l = solve_sat([a*b],n=2) # optional - pycryptosat sage.modules + sage: len(l) == 2, f.subs(l[0]), f.subs(l[1]) # optional - pycryptosat sage.modules (True, 0, 0) - sage: sorted((d[a], d[b]) for d in solve_sat([a*b],n=3)) # optional - pycryptosat + sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=3)) # optional - pycryptosat sage.modules [(0, 0), (0, 1), (1, 0)] - sage: sorted((d[a], d[b]) for d in solve_sat([a*b],n=4)) # optional - pycryptosat + sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=4)) # optional - pycryptosat sage.modules [(0, 0), (0, 1), (1, 0)] - sage: sorted((d[a], d[b]) for d in solve_sat([a*b],n=infinity)) # optional - pycryptosat + sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=infinity)) # optional - pycryptosat sage.modules [(0, 0), (0, 1), (1, 0)] In the next example we see how the ``target_variables`` parameter works:: - sage: from sage.sat.boolean_polynomials import solve as solve_sat # optional - pycryptosat - sage: R. = BooleanPolynomialRing() # optional - pycryptosat - sage: F = [a+b,a+c+d] # optional - pycryptosat + sage: from sage.sat.boolean_polynomials import solve as solve_sat + sage: R. = BooleanPolynomialRing() # optional - pycryptosat sage.modules + sage: F = [a + b, a + c + d] # optional - pycryptosat sage.modules First the normal use case:: - sage: sorted((D[a], D[b], D[c], D[d]) for D in solve_sat(F,n=infinity)) # optional - pycryptosat + sage: sorted((D[a], D[b], D[c], D[d]) # optional - pycryptosat sage.modules + ....: for D in solve_sat(F, n=infinity)) [(0, 0, 0, 0), (0, 0, 1, 1), (1, 1, 0, 1), (1, 1, 1, 0)] Now we are only interested in the solutions of the variables a and b:: - sage: solve_sat(F,n=infinity,target_variables=[a,b]) # optional - pycryptosat + sage: solve_sat(F,n=infinity,target_variables=[a,b]) # optional - pycryptosat sage.modules [{b: 0, a: 0}, {b: 1, a: 1}] Here, we generate and solve the cubic equations of the AES SBox (see :trac:`26676`):: - sage: from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence # optional - pycryptosat, long time - sage: from sage.sat.boolean_polynomials import solve as solve_sat # optional - pycryptosat, long time - sage: sr = sage.crypto.mq.SR(1, 4, 4, 8, allow_zero_inversions = True) # optional - pycryptosat, long time - sage: sb = sr.sbox() # optional - pycryptosat, long time - sage: eqs = sb.polynomials(degree = 3) # optional - pycryptosat, long time - sage: eqs = PolynomialSequence(eqs) # optional - pycryptosat, long time - sage: variables = map(str, eqs.variables()) # optional - pycryptosat, long time - sage: variables = ",".join(variables) # optional - pycryptosat, long time - sage: R = BooleanPolynomialRing(16, variables) # optional - pycryptosat, long time - sage: eqs = [R(eq) for eq in eqs] # optional - pycryptosat, long time - sage: sls_aes = solve_sat(eqs, n = infinity) # optional - pycryptosat, long time - sage: len(sls_aes) # optional - pycryptosat, long time + sage: from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence + sage: from sage.sat.boolean_polynomials import solve as solve_sat + sage: sr = sage.crypto.mq.SR(1, 4, 4, 8, # long time, optional - pycryptosat sage.modules + ....: allow_zero_inversions=True) + sage: sb = sr.sbox() # long time, optional - pycryptosat sage.modules + sage: eqs = sb.polynomials(degree = 3) # long time, optional - pycryptosat sage.modules + sage: eqs = PolynomialSequence(eqs) # long time, optional - pycryptosat sage.modules + sage: variables = map(str, eqs.variables()) # long time, optional - pycryptosat sage.modules + sage: variables = ",".join(variables) # long time, optional - pycryptosat sage.modules + sage: R = BooleanPolynomialRing(16, variables) # long time, optional - pycryptosat sage.modules + sage: eqs = [R(eq) for eq in eqs] # long time, optional - pycryptosat sage.modules + sage: sls_aes = solve_sat(eqs, n = infinity) # long time, optional - pycryptosat sage.modules + sage: len(sls_aes) # long time, optional - pycryptosat sage.modules 256 TESTS: @@ -148,7 +151,7 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): Test that :trac:`26676` is fixed:: sage: varl = ['k{0}'.format(p) for p in range(29)] - sage: B = BooleanPolynomialRing(names = varl) + sage: B = BooleanPolynomialRing(names=varl) sage: B.inject_variables(verbose=False) sage: keqs = [ ....: k0 + k6 + 1, @@ -162,7 +165,7 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): ....: k9 + k28, ....: k11 + k20] sage: from sage.sat.boolean_polynomials import solve as solve_sat - sage: solve_sat(keqs, n=1, solver=SAT('cryptominisat')) # optional - pycryptosat + sage: solve_sat(keqs, n=1, solver=SAT('cryptominisat')) # optional - pycryptosat [{k28: 0, k26: 1, k24: 0, @@ -187,7 +190,7 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): k2: 0, k1: 0, k0: 0}] - sage: solve_sat(keqs, n=1, solver=SAT('picosat')) # optional - pycosat + sage: solve_sat(keqs, n=1, solver=SAT('picosat')) # optional - pycosat [{k28: 0, k26: 1, k24: 0, diff --git a/src/sage/sat/converters/polybori.py b/src/sage/sat/converters/polybori.py index ca39def12c1..cbf46d4faa2 100644 --- a/src/sage/sat/converters/polybori.py +++ b/src/sage/sat/converters/polybori.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.polynomial.pbori """ An ANF to CNF Converter using a Dense/Sparse Strategy diff --git a/src/sage/sat/solvers/satsolver.pyx b/src/sage/sat/solvers/satsolver.pyx index 1c4ac400cb6..0ed7041c608 100644 --- a/src/sage/sat/solvers/satsolver.pyx +++ b/src/sage/sat/solvers/satsolver.pyx @@ -139,9 +139,9 @@ cdef class SatSolver: sage: from io import StringIO sage: file_object = StringIO("c A sample .cnf file with xor clauses.\np cnf 3 3\n1 2 0\n3 0\nx1 2 3 0") - sage: from sage.sat.solvers.sat_lp import SatLP - sage: solver = SatLP() - sage: solver.read(file_object) + sage: from sage.sat.solvers.sat_lp import SatLP # optional - sage.numerical.mip + sage: solver = SatLP() # optional - sage.numerical.mip + sage: solver.read(file_object) # optional - sage.numerical.mip Traceback (most recent call last): ... NotImplementedError: the solver "an ILP-based SAT Solver" does not support xor clauses @@ -339,7 +339,7 @@ def SAT(solver=None, *args, **kwds): EXAMPLES:: - sage: SAT(solver="LP") + sage: SAT(solver="LP") # optional - sage.numerical.mip an ILP-based SAT Solver TESTS:: @@ -351,12 +351,12 @@ def SAT(solver=None, *args, **kwds): Forcing CryptoMiniSat:: - sage: SAT(solver="cryptominisat") # optional - pycryptosat + sage: SAT(solver="cryptominisat") # optional - pycryptosat CryptoMiniSat solver: 0 variables, 0 clauses. Forcing PicoSat:: - sage: SAT(solver="picosat") # optional - pycosat + sage: SAT(solver="picosat") # optional - pycosat PicoSAT solver: 0 variables, 0 clauses. Forcing Glucose:: From a37b456669e71fbaf06e357fae373c87c576bdc1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 14:37:23 -0700 Subject: [PATCH 161/463] More # optional --- src/sage/sat/boolean_polynomials.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/sage/sat/boolean_polynomials.py b/src/sage/sat/boolean_polynomials.py index 2c5075d6251..6d84171b95d 100644 --- a/src/sage/sat/boolean_polynomials.py +++ b/src/sage/sat/boolean_polynomials.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.polynomial.pbori """ SAT Functions for Boolean Polynomials @@ -71,8 +72,8 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): We construct a very small-scale AES system of equations:: - sage: sr = mq.SR(1,1,1,4,gf2=True,polybori=True) # optional - sage.modules - sage: while True: # workaround (see :trac:`31891`) # optional - sage.modules + sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) # optional - sage.modules sage.rings.finite_rings + sage: while True: # workaround (see :trac:`31891`) # optional - sage.modules sage.rings.finite_rings ....: try: ....: F, s = sr.polynomial_system() ....: break @@ -82,14 +83,14 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): and pass it to a SAT solver:: sage: from sage.sat.boolean_polynomials import solve as solve_sat - sage: s = solve_sat(F) # optional - pycryptosat sage.modules - sage: F.subs(s[0]) # optional - pycryptosat sage.modules + sage: s = solve_sat(F) # optional - pycryptosat sage.modules sage.rings.finite_rings + sage: F.subs(s[0]) # optional - pycryptosat sage.modules sage.rings.finite_rings Polynomial Sequence with 36 Polynomials in 0 Variables This time we pass a few options through to the converter and the solver:: - sage: s = solve_sat(F, c_max_vars_sparse=4, c_cutting_number=8) # optional - pycryptosat sage.modules - sage: F.subs(s[0]) # optional - pycryptosat sage.modules + sage: s = solve_sat(F, c_max_vars_sparse=4, c_cutting_number=8) # optional - pycryptosat sage.modules sage.rings.finite_rings + sage: F.subs(s[0]) # optional - pycryptosat sage.modules sage.rings.finite_rings Polynomial Sequence with 36 Polynomials in 0 Variables We construct a very simple system with three solutions @@ -126,7 +127,7 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): Now we are only interested in the solutions of the variables a and b:: - sage: solve_sat(F,n=infinity,target_variables=[a,b]) # optional - pycryptosat sage.modules + sage: solve_sat(F, n=infinity, target_variables=[a,b]) # optional - pycryptosat sage.modules [{b: 0, a: 0}, {b: 1, a: 1}] Here, we generate and solve the cubic equations of the AES SBox (see :trac:`26676`):: @@ -136,7 +137,7 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): sage: sr = sage.crypto.mq.SR(1, 4, 4, 8, # long time, optional - pycryptosat sage.modules ....: allow_zero_inversions=True) sage: sb = sr.sbox() # long time, optional - pycryptosat sage.modules - sage: eqs = sb.polynomials(degree = 3) # long time, optional - pycryptosat sage.modules + sage: eqs = sb.polynomials(degree=3) # long time, optional - pycryptosat sage.modules sage: eqs = PolynomialSequence(eqs) # long time, optional - pycryptosat sage.modules sage: variables = map(str, eqs.variables()) # long time, optional - pycryptosat sage.modules sage: variables = ",".join(variables) # long time, optional - pycryptosat sage.modules @@ -343,11 +344,11 @@ def learn(F, converter=None, solver=None, max_learnt_length=3, interreduction=Fa We construct a simple system and solve it:: - sage: set_random_seed(2300) # optional - pycryptosat - sage: sr = mq.SR(1,2,2,4,gf2=True,polybori=True) # optional - pycryptosat - sage: F,s = sr.polynomial_system() # optional - pycryptosat - sage: H = learn_sat(F) # optional - pycryptosat - sage: H[-1] # optional - pycryptosat + sage: set_random_seed(2300) + sage: sr = mq.SR(1, 2, 2, 4, gf2=True, polybori=True) # optional - pycryptosat sage.modules sage.rings.finite_rings + sage: F,s = sr.polynomial_system() # optional - pycryptosat sage.modules sage.rings.finite_rings + sage: H = learn_sat(F) # optional - pycryptosat sage.modules sage.rings.finite_rings + sage: H[-1] # optional - pycryptosat sage.modules sage.rings.finite_rings k033 + 1 """ try: From a12c38c19c82b032d752279e8b5e1076bd58fd41 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 23:47:37 -0700 Subject: [PATCH 162/463] More # optional --- src/sage/sat/solvers/dimacs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/sat/solvers/dimacs.py b/src/sage/sat/solvers/dimacs.py index cfe3c7cd4ed..51cffd27402 100644 --- a/src/sage/sat/solvers/dimacs.py +++ b/src/sage/sat/solvers/dimacs.py @@ -490,14 +490,14 @@ def __call__(self, assumptions=None): TESTS:: sage: from sage.sat.boolean_polynomials import solve as solve_sat - sage: sr = mq.SR(1,1,1,4,gf2=True,polybori=True) - sage: while True: # workaround (see :trac:`31891`) + sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) # optional - sage.rings.finite_rings sage.rings.polynomial.pbori + sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.finite_rings sage.rings.polynomial.pbori ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: solve_sat(F, solver=sage.sat.solvers.RSat) # optional - RSat + sage: solve_sat(F, solver=sage.sat.solvers.RSat) # optional - RSat # optional - sage.rings.finite_rings sage.rings.polynomial.pbori """ if assumptions is not None: From e43e09ad70c8d960f6686fc8095e72578a1d631a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 6 Aug 2023 20:45:14 -0700 Subject: [PATCH 163/463] src/sage/sat: Update file-level doctest tag --- src/sage/sat/boolean_polynomials.py | 2 +- src/sage/sat/converters/polybori.py | 2 +- src/sage/sat/solvers/sat_lp.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/sat/boolean_polynomials.py b/src/sage/sat/boolean_polynomials.py index 6d84171b95d..c47cae945d6 100644 --- a/src/sage/sat/boolean_polynomials.py +++ b/src/sage/sat/boolean_polynomials.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.rings.polynomial.pbori +# sage.doctest: needs sage.rings.polynomial.pbori """ SAT Functions for Boolean Polynomials diff --git a/src/sage/sat/converters/polybori.py b/src/sage/sat/converters/polybori.py index cbf46d4faa2..49da6f1819c 100644 --- a/src/sage/sat/converters/polybori.py +++ b/src/sage/sat/converters/polybori.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.rings.polynomial.pbori +# sage.doctest: needs sage.rings.polynomial.pbori """ An ANF to CNF Converter using a Dense/Sparse Strategy diff --git a/src/sage/sat/solvers/sat_lp.py b/src/sage/sat/solvers/sat_lp.py index dc1ff30d4b7..9b65b1d241d 100644 --- a/src/sage/sat/solvers/sat_lp.py +++ b/src/sage/sat/solvers/sat_lp.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.numerical.mip +# sage.doctest: needs sage.numerical.mip r""" Solve SAT problems Integer Linear Programming From 417429f000f0c237b4216c86635b2933f5927b59 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 7 Aug 2023 22:44:22 -0700 Subject: [PATCH 164/463] src/sage/sat: sage -fixdoctests --only-tags --- src/sage/sat/boolean_polynomials.py | 68 ++++++++++++++------------- src/sage/sat/solvers/cryptominisat.py | 33 +++++++------ src/sage/sat/solvers/dimacs.py | 6 +-- src/sage/sat/solvers/picosat.py | 24 +++++----- src/sage/sat/solvers/satsolver.pyx | 8 ++-- 5 files changed, 73 insertions(+), 66 deletions(-) diff --git a/src/sage/sat/boolean_polynomials.py b/src/sage/sat/boolean_polynomials.py index c47cae945d6..dc5fdb69ff0 100644 --- a/src/sage/sat/boolean_polynomials.py +++ b/src/sage/sat/boolean_polynomials.py @@ -72,8 +72,8 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): We construct a very small-scale AES system of equations:: - sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) # optional - sage.modules sage.rings.finite_rings - sage: while True: # workaround (see :trac:`31891`) # optional - sage.modules sage.rings.finite_rings + sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) # needs sage.modules sage.rings.finite_rings + sage: while True: # workaround (see :trac:`31891`) # needs sage.modules sage.rings.finite_rings ....: try: ....: F, s = sr.polynomial_system() ....: break @@ -83,68 +83,70 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): and pass it to a SAT solver:: sage: from sage.sat.boolean_polynomials import solve as solve_sat - sage: s = solve_sat(F) # optional - pycryptosat sage.modules sage.rings.finite_rings - sage: F.subs(s[0]) # optional - pycryptosat sage.modules sage.rings.finite_rings + sage: s = solve_sat(F) # optional - pycryptosat # needs sage.modules sage.rings.finite_rings + sage: F.subs(s[0]) # optional - pycryptosat # needs sage.modules sage.rings.finite_rings Polynomial Sequence with 36 Polynomials in 0 Variables This time we pass a few options through to the converter and the solver:: - sage: s = solve_sat(F, c_max_vars_sparse=4, c_cutting_number=8) # optional - pycryptosat sage.modules sage.rings.finite_rings - sage: F.subs(s[0]) # optional - pycryptosat sage.modules sage.rings.finite_rings + sage: s = solve_sat(F, c_max_vars_sparse=4, c_cutting_number=8) # optional - pycryptosat, needs sage.modules sage.rings.finite_rings + sage: F.subs(s[0]) # optional - pycryptosat # needs sage.modules sage.rings.finite_rings Polynomial Sequence with 36 Polynomials in 0 Variables We construct a very simple system with three solutions and ask for a specific number of solutions:: - sage: B. = BooleanPolynomialRing() # optional - pycryptosat sage.modules - sage: f = a*b # optional - pycryptosat sage.modules - sage: l = solve_sat([f],n=1) # optional - pycryptosat sage.modules - sage: len(l) == 1, f.subs(l[0]) # optional - pycryptosat sage.modules + sage: # optional - pycryptosat, needs sage.modules + sage: B. = BooleanPolynomialRing() + sage: f = a*b + sage: l = solve_sat([f],n=1) + sage: len(l) == 1, f.subs(l[0]) (True, 0) - sage: l = solve_sat([a*b],n=2) # optional - pycryptosat sage.modules - sage: len(l) == 2, f.subs(l[0]), f.subs(l[1]) # optional - pycryptosat sage.modules + sage: l = solve_sat([a*b],n=2) # optional - pycryptosat # needs sage.modules + sage: len(l) == 2, f.subs(l[0]), f.subs(l[1]) # optional - pycryptosat # needs sage.modules (True, 0, 0) - sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=3)) # optional - pycryptosat sage.modules + sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=3)) # optional - pycryptosat, needs sage.modules [(0, 0), (0, 1), (1, 0)] - sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=4)) # optional - pycryptosat sage.modules + sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=4)) # optional - pycryptosat, needs sage.modules [(0, 0), (0, 1), (1, 0)] - sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=infinity)) # optional - pycryptosat sage.modules + sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=infinity)) # optional - pycryptosat, needs sage.modules [(0, 0), (0, 1), (1, 0)] In the next example we see how the ``target_variables`` parameter works:: sage: from sage.sat.boolean_polynomials import solve as solve_sat - sage: R. = BooleanPolynomialRing() # optional - pycryptosat sage.modules - sage: F = [a + b, a + c + d] # optional - pycryptosat sage.modules + sage: R. = BooleanPolynomialRing() # optional - pycryptosat # needs sage.modules + sage: F = [a + b, a + c + d] # optional - pycryptosat # needs sage.modules First the normal use case:: - sage: sorted((D[a], D[b], D[c], D[d]) # optional - pycryptosat sage.modules + sage: sorted((D[a], D[b], D[c], D[d]) # optional - pycryptosat # needs sage.modules ....: for D in solve_sat(F, n=infinity)) [(0, 0, 0, 0), (0, 0, 1, 1), (1, 1, 0, 1), (1, 1, 1, 0)] Now we are only interested in the solutions of the variables a and b:: - sage: solve_sat(F, n=infinity, target_variables=[a,b]) # optional - pycryptosat sage.modules + sage: solve_sat(F, n=infinity, target_variables=[a,b]) # optional - pycryptosat, needs sage.modules [{b: 0, a: 0}, {b: 1, a: 1}] Here, we generate and solve the cubic equations of the AES SBox (see :trac:`26676`):: + sage: # long time, optional - pycryptosat, needs sage.modules sage: from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence sage: from sage.sat.boolean_polynomials import solve as solve_sat - sage: sr = sage.crypto.mq.SR(1, 4, 4, 8, # long time, optional - pycryptosat sage.modules + sage: sr = sage.crypto.mq.SR(1, 4, 4, 8, ....: allow_zero_inversions=True) - sage: sb = sr.sbox() # long time, optional - pycryptosat sage.modules - sage: eqs = sb.polynomials(degree=3) # long time, optional - pycryptosat sage.modules - sage: eqs = PolynomialSequence(eqs) # long time, optional - pycryptosat sage.modules - sage: variables = map(str, eqs.variables()) # long time, optional - pycryptosat sage.modules - sage: variables = ",".join(variables) # long time, optional - pycryptosat sage.modules - sage: R = BooleanPolynomialRing(16, variables) # long time, optional - pycryptosat sage.modules - sage: eqs = [R(eq) for eq in eqs] # long time, optional - pycryptosat sage.modules - sage: sls_aes = solve_sat(eqs, n = infinity) # long time, optional - pycryptosat sage.modules - sage: len(sls_aes) # long time, optional - pycryptosat sage.modules + sage: sb = sr.sbox() + sage: eqs = sb.polynomials(degree=3) + sage: eqs = PolynomialSequence(eqs) + sage: variables = map(str, eqs.variables()) + sage: variables = ",".join(variables) + sage: R = BooleanPolynomialRing(16, variables) + sage: eqs = [R(eq) for eq in eqs] + sage: sls_aes = solve_sat(eqs, n = infinity) + sage: len(sls_aes) 256 TESTS: @@ -345,10 +347,10 @@ def learn(F, converter=None, solver=None, max_learnt_length=3, interreduction=Fa We construct a simple system and solve it:: sage: set_random_seed(2300) - sage: sr = mq.SR(1, 2, 2, 4, gf2=True, polybori=True) # optional - pycryptosat sage.modules sage.rings.finite_rings - sage: F,s = sr.polynomial_system() # optional - pycryptosat sage.modules sage.rings.finite_rings - sage: H = learn_sat(F) # optional - pycryptosat sage.modules sage.rings.finite_rings - sage: H[-1] # optional - pycryptosat sage.modules sage.rings.finite_rings + sage: sr = mq.SR(1, 2, 2, 4, gf2=True, polybori=True) # optional - pycryptosat, needs sage.modules sage.rings.finite_rings + sage: F,s = sr.polynomial_system() # optional - pycryptosat # needs sage.modules sage.rings.finite_rings + sage: H = learn_sat(F) # optional - pycryptosat # needs sage.modules sage.rings.finite_rings + sage: H[-1] # optional - pycryptosat # needs sage.modules sage.rings.finite_rings k033 + 1 """ try: diff --git a/src/sage/sat/solvers/cryptominisat.py b/src/sage/sat/solvers/cryptominisat.py index d2a8ae9e5a6..82f1ffd9086 100644 --- a/src/sage/sat/solvers/cryptominisat.py +++ b/src/sage/sat/solvers/cryptominisat.py @@ -182,12 +182,13 @@ def __call__(self, assumptions=None): EXAMPLES:: + sage: # optional - pycryptosat sage: from sage.sat.solvers.cryptominisat import CryptoMiniSat - sage: solver = CryptoMiniSat() # optional - pycryptosat - sage: solver.add_clause((1,2)) # optional - pycryptosat - sage: solver.add_clause((-1,2)) # optional - pycryptosat - sage: solver.add_clause((-1,-2)) # optional - pycryptosat - sage: solver() # optional - pycryptosat + sage: solver = CryptoMiniSat() + sage: solver.add_clause((1,2)) + sage: solver.add_clause((-1,2)) + sage: solver.add_clause((-1,-2)) + sage: solver() (None, False, True) sage: solver.add_clause((1,-2)) # optional - pycryptosat @@ -231,23 +232,25 @@ def clauses(self, filename=None): EXAMPLES:: + sage: # optional - pycryptosat sage: from sage.sat.solvers import CryptoMiniSat - sage: solver = CryptoMiniSat() # optional - pycryptosat - sage: solver.add_clause((1,2,3,4,5,6,7,8,-9)) # optional - pycryptosat - sage: solver.add_xor_clause((1,2,3,4,5,6,7,8,9), rhs=True) # optional - pycryptosat - sage: solver.clauses() # optional - pycryptosat + sage: solver = CryptoMiniSat() + sage: solver.add_clause((1,2,3,4,5,6,7,8,-9)) + sage: solver.add_xor_clause((1,2,3,4,5,6,7,8,9), rhs=True) + sage: solver.clauses() [((1, 2, 3, 4, 5, 6, 7, 8, -9), False, None), ((1, 2, 3, 4, 5, 6, 7, 8, 9), True, True)] DIMACS format output:: + sage: # optional - pycryptosat sage: from sage.sat.solvers import CryptoMiniSat - sage: solver = CryptoMiniSat() # optional - pycryptosat - sage: solver.add_clause((1, 2, 4)) # optional - pycryptosat - sage: solver.add_clause((1, 2, -4)) # optional - pycryptosat - sage: fn = tmp_filename() # optional - pycryptosat - sage: solver.clauses(fn) # optional - pycryptosat - sage: print(open(fn).read()) # optional - pycryptosat + sage: solver = CryptoMiniSat() + sage: solver.add_clause((1, 2, 4)) + sage: solver.add_clause((1, 2, -4)) + sage: fn = tmp_filename() + sage: solver.clauses(fn) + sage: print(open(fn).read()) p cnf 4 2 1 2 4 0 1 2 -4 0 diff --git a/src/sage/sat/solvers/dimacs.py b/src/sage/sat/solvers/dimacs.py index 51cffd27402..51e81a925a1 100644 --- a/src/sage/sat/solvers/dimacs.py +++ b/src/sage/sat/solvers/dimacs.py @@ -490,14 +490,14 @@ def __call__(self, assumptions=None): TESTS:: sage: from sage.sat.boolean_polynomials import solve as solve_sat - sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) # optional - sage.rings.finite_rings sage.rings.polynomial.pbori - sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.finite_rings sage.rings.polynomial.pbori + sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) # needs sage.rings.finite_rings sage.rings.polynomial.pbori + sage: while True: # workaround (see :trac:`31891`) # needs sage.rings.finite_rings sage.rings.polynomial.pbori ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: solve_sat(F, solver=sage.sat.solvers.RSat) # optional - RSat # optional - sage.rings.finite_rings sage.rings.polynomial.pbori + sage: solve_sat(F, solver=sage.sat.solvers.RSat) # optional - rsat, needs sage.rings.finite_rings sage.rings.polynomial.pbori """ if assumptions is not None: diff --git a/src/sage/sat/solvers/picosat.py b/src/sage/sat/solvers/picosat.py index a1a80e71794..a88f69da883 100644 --- a/src/sage/sat/solvers/picosat.py +++ b/src/sage/sat/solvers/picosat.py @@ -147,12 +147,13 @@ def __call__(self, assumptions=None): EXAMPLES:: + sage: # optional - pycosat sage: from sage.sat.solvers.picosat import PicoSAT - sage: solver = PicoSAT() # optional - pycosat - sage: solver.add_clause((1,2)) # optional - pycosat - sage: solver.add_clause((-1,2)) # optional - pycosat - sage: solver.add_clause((-1,-2)) # optional - pycosat - sage: solver() # optional - pycosat + sage: solver = PicoSAT() + sage: solver.add_clause((1,2)) + sage: solver.add_clause((-1,2)) + sage: solver.add_clause((-1,-2)) + sage: solver() (None, False, True) sage: solver.add_clause((1,-2)) # optional - pycosat @@ -207,13 +208,14 @@ def clauses(self, filename=None): DIMACS format output:: + sage: # optional - pycosat sage: from sage.sat.solvers.picosat import PicoSAT - sage: solver = PicoSAT() # optional - pycosat - sage: solver.add_clause((1, 2, 4)) # optional - pycosat - sage: solver.add_clause((1, 2, -4)) # optional - pycosat - sage: fn = tmp_filename() # optional - pycosat - sage: solver.clauses(fn) # optional - pycosat - sage: print(open(fn).read()) # optional - pycosat + sage: solver = PicoSAT() + sage: solver.add_clause((1, 2, 4)) + sage: solver.add_clause((1, 2, -4)) + sage: fn = tmp_filename() + sage: solver.clauses(fn) + sage: print(open(fn).read()) p cnf 4 2 1 2 4 0 1 2 -4 0 diff --git a/src/sage/sat/solvers/satsolver.pyx b/src/sage/sat/solvers/satsolver.pyx index 0ed7041c608..83735c86989 100644 --- a/src/sage/sat/solvers/satsolver.pyx +++ b/src/sage/sat/solvers/satsolver.pyx @@ -139,9 +139,9 @@ cdef class SatSolver: sage: from io import StringIO sage: file_object = StringIO("c A sample .cnf file with xor clauses.\np cnf 3 3\n1 2 0\n3 0\nx1 2 3 0") - sage: from sage.sat.solvers.sat_lp import SatLP # optional - sage.numerical.mip - sage: solver = SatLP() # optional - sage.numerical.mip - sage: solver.read(file_object) # optional - sage.numerical.mip + sage: from sage.sat.solvers.sat_lp import SatLP # needs sage.numerical.mip + sage: solver = SatLP() # needs sage.numerical.mip + sage: solver.read(file_object) # needs sage.numerical.mip Traceback (most recent call last): ... NotImplementedError: the solver "an ILP-based SAT Solver" does not support xor clauses @@ -339,7 +339,7 @@ def SAT(solver=None, *args, **kwds): EXAMPLES:: - sage: SAT(solver="LP") # optional - sage.numerical.mip + sage: SAT(solver="LP") # needs sage.numerical.mip an ILP-based SAT Solver TESTS:: From 69d7cdaa2fc1e71915a30e914a072509005db9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Nov 2023 10:02:16 +0100 Subject: [PATCH 165/463] ruff auto-fix for C4 in modular --- src/sage/modular/abvar/abvar.py | 8 ++++---- src/sage/modular/abvar/homspace.py | 2 +- src/sage/modular/arithgroup/arithgroup_perm.py | 4 ++-- src/sage/modular/arithgroup/congroup_gammaH.py | 10 +++++----- src/sage/modular/btquotients/btquotient.py | 2 +- src/sage/modular/dirichlet.py | 2 +- src/sage/modular/etaproducts.py | 2 +- src/sage/modular/hypergeometric_motive.py | 2 +- src/sage/modular/local_comp/smoothchar.py | 8 ++++---- .../modular/modform_hecketriangle/abstract_space.py | 4 ++-- .../modular/modform_hecketriangle/analytic_type.py | 4 ++-- src/sage/modular/modform_hecketriangle/constructor.py | 4 ++-- src/sage/modular/modform_hecketriangle/element.py | 2 +- .../modform_hecketriangle/hecke_triangle_groups.py | 2 +- src/sage/modular/modform_hecketriangle/space.py | 4 ++-- src/sage/modular/modform_hecketriangle/subspace.py | 2 +- src/sage/modular/modsym/ambient.py | 2 +- src/sage/modular/modsym/boundary.py | 2 +- src/sage/modular/modsym/ghlist.py | 2 +- src/sage/modular/modsym/relation_matrix.py | 4 ++-- src/sage/modular/multiple_zeta.py | 6 +++--- src/sage/modular/multiple_zeta_F_algebra.py | 2 +- 22 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/sage/modular/abvar/abvar.py b/src/sage/modular/abvar/abvar.py index 4f23ab768fd..f47e1fc7448 100644 --- a/src/sage/modular/abvar/abvar.py +++ b/src/sage/modular/abvar/abvar.py @@ -2060,8 +2060,8 @@ def newform_level(self, none_if_not_known=False): if none_if_not_known: return None level = LCM([f.level() for f in self.newform_decomposition('a')]) - groups = sorted(set([f.group() for f in - self.newform_decomposition('a')])) + groups = sorted({f.group() for f in + self.newform_decomposition('a')}) if len(groups) == 1: groups = groups[0] self.__newform_level = level, groups @@ -3870,7 +3870,7 @@ def _factors_with_same_label(self, other): if not isinstance(other, ModularAbelianVariety_abstract): raise TypeError("other must be an abelian variety") D = self.decomposition() - C = set([A.newform_label() for A in other.decomposition()]) + C = {A.newform_label() for A in other.decomposition()} Z = [] for X in D: lbl = X.newform_label() @@ -4899,7 +4899,7 @@ def tamagawa_number_bounds(self, p): else: raise NotImplementedError("Atkin-Lehner at p must act as a scalar") else: - mul_primes = sorted(set([p] + [q for q in prime_range(2, 2 * self.dimension() + 2)])) + mul_primes = sorted(set([p] + list(prime_range(2, 2 * self.dimension() + 2)))) div = Integer(div) mul = Integer(mul) mul_primes = tuple(mul_primes) diff --git a/src/sage/modular/abvar/homspace.py b/src/sage/modular/abvar/homspace.py index 964df397a93..ab1544d2698 100644 --- a/src/sage/modular/abvar/homspace.py +++ b/src/sage/modular/abvar/homspace.py @@ -570,7 +570,7 @@ def calculate_generators(self): return if (self.domain() == self.codomain()) and (self.domain().dimension() == 1): - self._gens = tuple([ identity_matrix(ZZ,2) ]) + self._gens = ( identity_matrix(ZZ,2), ) return phi = self.domain()._isogeny_to_product_of_powers() diff --git a/src/sage/modular/arithgroup/arithgroup_perm.py b/src/sage/modular/arithgroup/arithgroup_perm.py index eb0e645559a..8204995e1d1 100644 --- a/src/sage/modular/arithgroup/arithgroup_perm.py +++ b/src/sage/modular/arithgroup/arithgroup_perm.py @@ -1798,7 +1798,7 @@ def cusp_widths(self,exp=False): """ inv = self.S2()**2 L = self.L() - cusps = set(c[0] for c in L.cycle_tuples(singletons=True)) + cusps = {c[0] for c in L.cycle_tuples(singletons=True)} if exp: widths = {} else: @@ -2603,7 +2603,7 @@ def odd_subgroups(self): s3 = PermutationConstructor([x + tuple(y + n for y in x) for x in s3cycs]) H = ArithmeticSubgroup_Permutation(S2=s2,S3=s3) - bucket = set([H]) + bucket = {H} res = [H] # We use a set *and* a list since checking whether an element is in a # set is very fast, but on the other hand we want the order the results diff --git a/src/sage/modular/arithgroup/congroup_gammaH.py b/src/sage/modular/arithgroup/congroup_gammaH.py index c9e53fdf3a8..60df7b2add9 100644 --- a/src/sage/modular/arithgroup/congroup_gammaH.py +++ b/src/sage/modular/arithgroup/congroup_gammaH.py @@ -146,7 +146,7 @@ def _normalize_H(H, level): for h in H: if gcd(h, level) > 1: raise ArithmeticError('The generators %s must be units modulo %s' % (H, level)) - H = set(u for u in H if u > 1) + H = {u for u in H if u > 1} final_H = set() for h in H: inv_h = h.inverse_mod(level) @@ -1140,7 +1140,7 @@ def ncusps(self): c = ZZ(0) for d in (d for d in N.divisors() if d**2 <= N): Nd = lcm(d, N // d) - Hd = set([x % Nd for x in H]) + Hd = {x % Nd for x in H} lenHd = len(Hd) if Nd - 1 not in Hd: lenHd *= 2 @@ -1182,7 +1182,7 @@ def nregcusps(self): c = ZZ(0) for d in (d for d in divisors(N) if d**2 <= N): Nd = lcm(d, N // d) - Hd = set([x % Nd for x in H]) + Hd = {x % Nd for x in H} if Nd - 1 not in Hd: summand = euler_phi(d) * euler_phi(N // d) // (2 * len(Hd)) if d**2 == N: @@ -1395,7 +1395,7 @@ def _list_subgroup(N, gens): sage: sage.modular.arithgroup.congroup_gammaH._list_subgroup(11, [3]) [1, 3, 4, 5, 9] """ - H = set([1]) + H = {1} N = int(N) for g in gens: if gcd(g, N) != 1: @@ -1405,7 +1405,7 @@ def _list_subgroup(N, gens): while not (gk in H): gk = (gk * g) % N sbgrp.append(gk) - H = set([(x * h) % N for x in sbgrp for h in H]) + H = {(x * h) % N for x in sbgrp for h in H} return sorted(H) diff --git a/src/sage/modular/btquotients/btquotient.py b/src/sage/modular/btquotients/btquotient.py index 3c7bceb0aa3..acb47da55e7 100644 --- a/src/sage/modular/btquotients/btquotient.py +++ b/src/sage/modular/btquotients/btquotient.py @@ -3710,7 +3710,7 @@ def _compute_quotient(self, check=True): 'from expected.') self._nontorsion_generators = nontorsion_generators - self._boundary = dict([(vv.rep, vv) for vv in vertex_list]) + self._boundary = {vv.rep: vv for vv in vertex_list} self._edge_list = edge_list self._vertex_list = vertex_list self._num_edges = num_edges diff --git a/src/sage/modular/dirichlet.py b/src/sage/modular/dirichlet.py index e752cc36b59..568e7c678f0 100644 --- a/src/sage/modular/dirichlet.py +++ b/src/sage/modular/dirichlet.py @@ -1282,7 +1282,7 @@ def galois_orbit(self, sort=True): P = self.parent() z = self.element() o = int(z.additive_order()) - Auts = set([m % o for m in P._automorphisms()]) + Auts = {m % o for m in P._automorphisms()} v = [P.element_class(P, m * z, check=False) for m in Auts] if sort: v.sort() diff --git a/src/sage/modular/etaproducts.py b/src/sage/modular/etaproducts.py index b17a99068a8..700b369b5df 100644 --- a/src/sage/modular/etaproducts.py +++ b/src/sage/modular/etaproducts.py @@ -558,7 +558,7 @@ def basis(self, reduce=True): nf = (i < S.ncols() and S[i, i]) or 0 # ? good_vects.append((vect * 24 / gcd(nf, 24)).list()) for v in good_vects: - v.append(-sum([r for r in v])) + v.append(-sum(list(v))) dicts = [] for v in good_vects: dicts.append({}) diff --git a/src/sage/modular/hypergeometric_motive.py b/src/sage/modular/hypergeometric_motive.py index 0db87ac9f66..b26e5c39be5 100644 --- a/src/sage/modular/hypergeometric_motive.py +++ b/src/sage/modular/hypergeometric_motive.py @@ -661,7 +661,7 @@ def wild_primes(self): [2, 3, 5] """ gamma = self.gamma_array() - return sorted(set([p for n in gamma.keys() for (p, _) in n.factor()])) + return sorted({p for n in gamma.keys() for (p, _) in n.factor()}) def zigzag(self, x, flip_beta=False): r""" diff --git a/src/sage/modular/local_comp/smoothchar.py b/src/sage/modular/local_comp/smoothchar.py index 62d80dc560a..1e4c25fe096 100644 --- a/src/sage/modular/local_comp/smoothchar.py +++ b/src/sage/modular/local_comp/smoothchar.py @@ -1103,7 +1103,7 @@ def quadratic_chars(self): q = 1 ram = [self.from_dirichlet(chi) for chi in DirichletGroup(self.prime() ** q, QQ) if not chi.is_trivial()] nr = self.character(0, [-1]) - return sorted([nr] + [f for f in ram] + [f*nr for f in ram]) + return sorted([nr] + list(ram) + [f*nr for f in ram]) class SmoothCharacterGroupQuadratic(SmoothCharacterGroupGeneric): r""" @@ -1793,12 +1793,12 @@ def exponents(self, c): c = ZZ(c) p = self.prime() if c == 0: - return tuple([0]) + return (0,) elif c == 1: - return tuple([p - 1, 0]) + return (p - 1, 0) elif p > 3 or self._unif_sqr == 3 or c <= 3: d = (c + 1) // 2 - return tuple([p**(d - 1) * (p - 1), p**(c // 2), 0]) + return (p**(d - 1) * (p - 1), p**(c // 2), 0) else: # awkward case, see above return self.ideal(c).idealstar(2).gens_orders() + (0,) diff --git a/src/sage/modular/modform_hecketriangle/abstract_space.py b/src/sage/modular/modform_hecketriangle/abstract_space.py index e0c4506122d..d1c52cc3b8f 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_space.py +++ b/src/sage/modular/modform_hecketriangle/abstract_space.py @@ -761,7 +761,7 @@ def aut_factor(self, gamma, t): elif (gamma.is_reflection()): return self._ep * (t/QQbar(I))**self._weight else: - L = [v for v in gamma.word_S_T()[0]] + L = list(gamma.word_S_T()[0]) aut_f = ZZ(1) while (len(L) > 0): M = L.pop(-1) @@ -1857,7 +1857,7 @@ def _quasi_form_matrix(self, min_exp=0, order_1=ZZ(0), incr_prec_by=0): return A B = A - A = A.delete_rows([r for r in range(column_size + (row_size-column_size)//2 - 1, row_size)]) + A = A.delete_rows(list(range(column_size + (row_size-column_size)//2 - 1, row_size))) # Next we simply delete row by row. Note that A is still modified here... while (B.rank() == column_size): diff --git a/src/sage/modular/modform_hecketriangle/analytic_type.py b/src/sage/modular/modform_hecketriangle/analytic_type.py index bdbc34a778a..e5fc53abb25 100644 --- a/src/sage/modular/modform_hecketriangle/analytic_type.py +++ b/src/sage/modular/modform_hecketriangle/analytic_type.py @@ -445,7 +445,7 @@ def __init__(self): 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(dict(enumerate(L._elements)), inplace=False) FiniteLatticePoset.__init__(self, hasse_diagram=H, elements=L._elements, category=L.category(), @@ -485,7 +485,7 @@ def __call__(self, *args, **kwargs): True """ if len(args) > 1: - return super().__call__([arg for arg in args], **kwargs) + return super().__call__(list(args), **kwargs) else: return super().__call__(*args, **kwargs) diff --git a/src/sage/modular/modform_hecketriangle/constructor.py b/src/sage/modular/modform_hecketriangle/constructor.py index 3a9e21fa852..040aa01add7 100644 --- a/src/sage/modular/modform_hecketriangle/constructor.py +++ b/src/sage/modular/modform_hecketriangle/constructor.py @@ -129,8 +129,8 @@ def rational_type(f, n=ZZ(3), base_ring=ZZ): num = R(f.numerator()) denom = R(f.denominator()) - ep_num = set([ZZ.one() - 2*((sum([g.exponents()[0][m] for m in [1, 2]])) % 2) for g in dhom(num).monomials()]) - ep_denom = set([ZZ.one() - 2*((sum([g.exponents()[0][m] for m in [1, 2]])) % 2) for g in dhom(denom).monomials()]) + ep_num = {ZZ.one() - 2*((sum([g.exponents()[0][m] for m in [1, 2]])) % 2) for g in dhom(num).monomials()} + ep_denom = {ZZ.one() - 2*((sum([g.exponents()[0][m] for m in [1, 2]])) % 2) for g in dhom(denom).monomials()} if (n == infinity): hom_num = R( num.subs(x=x**4, y=y**2, z=z**2) ) diff --git a/src/sage/modular/modform_hecketriangle/element.py b/src/sage/modular/modform_hecketriangle/element.py index b8cac1e9f52..4f58baafff5 100644 --- a/src/sage/modular/modform_hecketriangle/element.py +++ b/src/sage/modular/modform_hecketriangle/element.py @@ -337,7 +337,7 @@ def lseries(self, num_prec=None, max_imaginary_part=0, max_asymp_coeffs=40): # num_coeffs = L.num_coeffs() num_coeffs = L.num_coeffs(1.2) - coeff_vector = [coeff for coeff in self.q_expansion_vector(min_exp=0, max_exp=num_coeffs + 1, fix_d=True)] + coeff_vector = list(self.q_expansion_vector(min_exp=0, max_exp=num_coeffs + 1, fix_d=True)) pari_precode = "coeff = {};".format(coeff_vector) L.init_coeffs(v="coeff[k+1]", pari_precode=pari_precode, diff --git a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py index 6c73cc50d40..b37898fc024 100644 --- a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py +++ b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py @@ -803,7 +803,7 @@ def root_extension_embedding(self, D, K=None): else: K = AlgebraicField() - L = [emb for emb in F.embeddings(K)] + L = list(F.embeddings(K)) # Three possibilities up to numerical artefacts: # (1) emb = e, purely imaginary diff --git a/src/sage/modular/modform_hecketriangle/space.py b/src/sage/modular/modform_hecketriangle/space.py index 9df1e2d60ba..e897808ef23 100644 --- a/src/sage/modular/modform_hecketriangle/space.py +++ b/src/sage/modular/modform_hecketriangle/space.py @@ -327,7 +327,7 @@ def coordinate_vector(self, v): 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 = list(vector_part_in_subspace.coordinate_vector()) coord_vector += coord_part return self._module(vector(self.coeff_ring(), coord_vector)) @@ -499,7 +499,7 @@ def coordinate_vector(self, v): 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 = list(vector_part_in_subspace.coordinate_vector()) coord_vector += coord_part return self._module(vector(self.coeff_ring(), coord_vector)) diff --git a/src/sage/modular/modform_hecketriangle/subspace.py b/src/sage/modular/modform_hecketriangle/subspace.py index 4475f71530a..504c5fc1936 100644 --- a/src/sage/modular/modform_hecketriangle/subspace.py +++ b/src/sage/modular/modform_hecketriangle/subspace.py @@ -208,7 +208,7 @@ def __init__(self, ambient_space, basis, check): Module.__init__(self, base=ambient_space.base_ring()) self._ambient_space = ambient_space - self._basis = [v for v in basis] + self._basis = list(basis) # self(v) instead would somehow mess up the coercion model 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]) diff --git a/src/sage/modular/modsym/ambient.py b/src/sage/modular/modsym/ambient.py index a0e40c27785..89ba2741eac 100644 --- a/src/sage/modular/modsym/ambient.py +++ b/src/sage/modular/modsym/ambient.py @@ -2260,7 +2260,7 @@ def integral_structure(self, algorithm='default'): # The attribute _mod2term is set by self.compute_presentation(). # It is a list of pairs (n, c), such that the ith element of the list # is equivalent to c times the n-th basis Manin symbol. - G = set([i for i, _ in self._mod2term]) + G = {i for i, _ in self._mod2term} # Now G is a set of integer i such that these integers gives # indices of Manin symbols that together generate the integral diff --git a/src/sage/modular/modsym/boundary.py b/src/sage/modular/modsym/boundary.py index e90a5d165f6..903c57e9b96 100644 --- a/src/sage/modular/modsym/boundary.py +++ b/src/sage/modular/modsym/boundary.py @@ -567,7 +567,7 @@ def __call__(self, x): return sum([c * self._coerce_in_manin_symbol(v) for c, v in S]) elif is_FreeModuleElement(x): - y = {i: xi for i, xi in enumerate(x)} + y = dict(enumerate(x)) return BoundarySpaceElement(self, y) raise TypeError("Coercion of %s (of type %s) into %s not (yet) defined." % (x, type(x), self)) diff --git a/src/sage/modular/modsym/ghlist.py b/src/sage/modular/modsym/ghlist.py index 5df29f52af9..2e74217f851 100644 --- a/src/sage/modular/modsym/ghlist.py +++ b/src/sage/modular/modsym/ghlist.py @@ -48,7 +48,7 @@ def __init__(self, group): N = group.level() v = group._coset_reduction_data()[0] N = group.level() - coset_reps = set([a for a, b, _ in v if b == 1]) + coset_reps = {a for a, b, _ in v if b == 1} w = [group._reduce_coset(x*u, x*v) for x in coset_reps for u,v in p1list.P1List(N).list()] w = sorted(set(w)) self.__list = w diff --git a/src/sage/modular/modsym/relation_matrix.py b/src/sage/modular/modsym/relation_matrix.py index 5885812d36c..0533ea36f09 100644 --- a/src/sage/modular/modsym/relation_matrix.py +++ b/src/sage/modular/modsym/relation_matrix.py @@ -320,7 +320,7 @@ def gens_to_basis_matrix(syms, relation_matrix, mod, field, sparse): basis_set = set(A.nonpivots()) pivots = A.pivots() - basis_mod2 = set([j for j, c in mod if c != 0]) + basis_mod2 = {j for j, c in mod if c != 0} basis_set = basis_set.intersection(basis_mod2) basis = sorted(basis_set) @@ -333,7 +333,7 @@ def gens_to_basis_matrix(syms, relation_matrix, mod, field, sparse): M = MatrixSpace(field, len(syms), len(basis), sparse=sparse) B = M(0) - cols_index = dict([(basis[i], i) for i in range(len(basis))]) + cols_index = {basis[i]: i for i in range(len(basis))} for i in basis_mod2: t, l = search(basis, i) diff --git a/src/sage/modular/multiple_zeta.py b/src/sage/modular/multiple_zeta.py index 494d183e805..cefcb3b3c65 100644 --- a/src/sage/modular/multiple_zeta.py +++ b/src/sage/modular/multiple_zeta.py @@ -277,7 +277,7 @@ def composition_to_iterated(w, reverse=False) -> tuple[int, ...]: sage: composition_to_iterated((1,2), True) (1, 0, 1) """ - word = tuple() + word = () loop_over = reversed(w) if reverse else w for letter in loop_over: word += (1,) + (0,) * (letter - 1) @@ -1175,7 +1175,7 @@ def simplify_full(self, basis=None): """ if basis is None: basis = self.parent().basis_brown - support = set(sum(d) for d in self.support()) + support = {sum(d) for d in self.support()} result = self.parent().zero() for d in sorted(support): h = self.homogeneous_component(d) @@ -1994,7 +1994,7 @@ def __bool__(self) -> bool: P = self.parent() deg = P.degree_on_basis phi = P.phi - for d in sorted(set(deg(w) for w in self.support())): + for d in sorted({deg(w) for w in self.support()}): z = self.homogeneous_component(d) if not phi(z).is_zero(): return True diff --git a/src/sage/modular/multiple_zeta_F_algebra.py b/src/sage/modular/multiple_zeta_F_algebra.py index 251310de6b8..89ac3436cb2 100644 --- a/src/sage/modular/multiple_zeta_F_algebra.py +++ b/src/sage/modular/multiple_zeta_F_algebra.py @@ -121,7 +121,7 @@ def basis_f_odd_iterator(n, start=3) -> Iterator[tuple]: (3, 11)] """ if n == 0: - yield tuple() + yield () return if n % 2 and n >= start: yield (n,) From 71331829d84dc26b2c914d2ad5e1edc70e194d46 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 6 Nov 2023 08:03:05 -0800 Subject: [PATCH 166/463] src/sage/tests/book_stein_ent.py: Use block tag --- src/sage/tests/book_stein_ent.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/sage/tests/book_stein_ent.py b/src/sage/tests/book_stein_ent.py index b4d593ff427..2c43a840cdc 100644 --- a/src/sage/tests/book_stein_ent.py +++ b/src/sage/tests/book_stein_ent.py @@ -50,12 +50,14 @@ 25 sage: prime_pi(3000000) 216816 -sage: plot(prime_pi, 1,1000, rgbcolor=(0,0,1)) # needs sage.plot + +sage: # needs sage.plot sage.symbolic +sage: plot(prime_pi, 1,1000, rgbcolor=(0,0,1)) Graphics object consisting of 1 graphics primitive -sage: P = plot(Li, 2,10000, rgbcolor='purple') # needs sage.plot -sage: Q = plot(prime_pi, 2,10000, rgbcolor='black') # needs sage.plot -sage: R = plot(sqrt(x)*log(x),2,10000,rgbcolor='red') # needs sage.plot -sage: show(P+Q+R,xmin=0, figsize=[8,3]) # needs sage.plot +sage: P = plot(Li, 2,10000, rgbcolor='purple') +sage: Q = plot(prime_pi, 2,10000, rgbcolor='black') +sage: R = plot(sqrt(x)*log(x), 2,10000, rgbcolor='red') +sage: show(P + Q + R, xmin=0, figsize=[8,3]) sage: R = Integers(3) sage: list(R) From d1c66423cf61be17b69dea107df2bf071c3923fd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 6 Nov 2023 08:09:38 -0800 Subject: [PATCH 167/463] src/sage/sat/boolean_polynomials.py: Use file-level # optional/needs --- src/sage/sat/boolean_polynomials.py | 53 ++++++++++++++--------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/sage/sat/boolean_polynomials.py b/src/sage/sat/boolean_polynomials.py index dc5fdb69ff0..32753175384 100644 --- a/src/sage/sat/boolean_polynomials.py +++ b/src/sage/sat/boolean_polynomials.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.rings.polynomial.pbori +# sage.doctest: optional - pycryptosat, needs sage.modules sage.rings.polynomial.pbori """ SAT Functions for Boolean Polynomials @@ -72,8 +72,8 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): We construct a very small-scale AES system of equations:: - sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) # needs sage.modules sage.rings.finite_rings - sage: while True: # workaround (see :trac:`31891`) # needs sage.modules sage.rings.finite_rings + sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) + sage: while True: # workaround (see :trac:`31891`) ....: try: ....: F, s = sr.polynomial_system() ....: break @@ -83,57 +83,56 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): and pass it to a SAT solver:: sage: from sage.sat.boolean_polynomials import solve as solve_sat - sage: s = solve_sat(F) # optional - pycryptosat # needs sage.modules sage.rings.finite_rings - sage: F.subs(s[0]) # optional - pycryptosat # needs sage.modules sage.rings.finite_rings + sage: s = solve_sat(F) + sage: F.subs(s[0]) Polynomial Sequence with 36 Polynomials in 0 Variables This time we pass a few options through to the converter and the solver:: - sage: s = solve_sat(F, c_max_vars_sparse=4, c_cutting_number=8) # optional - pycryptosat, needs sage.modules sage.rings.finite_rings - sage: F.subs(s[0]) # optional - pycryptosat # needs sage.modules sage.rings.finite_rings + sage: s = solve_sat(F, c_max_vars_sparse=4, c_cutting_number=8) + sage: F.subs(s[0]) Polynomial Sequence with 36 Polynomials in 0 Variables We construct a very simple system with three solutions and ask for a specific number of solutions:: - sage: # optional - pycryptosat, needs sage.modules sage: B. = BooleanPolynomialRing() sage: f = a*b sage: l = solve_sat([f],n=1) sage: len(l) == 1, f.subs(l[0]) (True, 0) - sage: l = solve_sat([a*b],n=2) # optional - pycryptosat # needs sage.modules - sage: len(l) == 2, f.subs(l[0]), f.subs(l[1]) # optional - pycryptosat # needs sage.modules + sage: l = solve_sat([a*b],n=2) + sage: len(l) == 2, f.subs(l[0]), f.subs(l[1]) (True, 0, 0) - sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=3)) # optional - pycryptosat, needs sage.modules + sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=3)) [(0, 0), (0, 1), (1, 0)] - sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=4)) # optional - pycryptosat, needs sage.modules + sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=4)) [(0, 0), (0, 1), (1, 0)] - sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=infinity)) # optional - pycryptosat, needs sage.modules + sage: sorted((d[a], d[b]) for d in solve_sat([a*b], n=infinity)) [(0, 0), (0, 1), (1, 0)] In the next example we see how the ``target_variables`` parameter works:: sage: from sage.sat.boolean_polynomials import solve as solve_sat - sage: R. = BooleanPolynomialRing() # optional - pycryptosat # needs sage.modules - sage: F = [a + b, a + c + d] # optional - pycryptosat # needs sage.modules + sage: R. = BooleanPolynomialRing() + sage: F = [a + b, a + c + d] First the normal use case:: - sage: sorted((D[a], D[b], D[c], D[d]) # optional - pycryptosat # needs sage.modules + sage: sorted((D[a], D[b], D[c], D[d]) ....: for D in solve_sat(F, n=infinity)) [(0, 0, 0, 0), (0, 0, 1, 1), (1, 1, 0, 1), (1, 1, 1, 0)] Now we are only interested in the solutions of the variables a and b:: - sage: solve_sat(F, n=infinity, target_variables=[a,b]) # optional - pycryptosat, needs sage.modules + sage: solve_sat(F, n=infinity, target_variables=[a,b]) [{b: 0, a: 0}, {b: 1, a: 1}] Here, we generate and solve the cubic equations of the AES SBox (see :trac:`26676`):: - sage: # long time, optional - pycryptosat, needs sage.modules + sage: # long time sage: from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence sage: from sage.sat.boolean_polynomials import solve as solve_sat sage: sr = sage.crypto.mq.SR(1, 4, 4, 8, @@ -145,7 +144,7 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): sage: variables = ",".join(variables) sage: R = BooleanPolynomialRing(16, variables) sage: eqs = [R(eq) for eq in eqs] - sage: sls_aes = solve_sat(eqs, n = infinity) + sage: sls_aes = solve_sat(eqs, n=infinity) sage: len(sls_aes) 256 @@ -168,7 +167,7 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): ....: k9 + k28, ....: k11 + k20] sage: from sage.sat.boolean_polynomials import solve as solve_sat - sage: solve_sat(keqs, n=1, solver=SAT('cryptominisat')) # optional - pycryptosat + sage: solve_sat(keqs, n=1, solver=SAT('cryptominisat')) [{k28: 0, k26: 1, k24: 0, @@ -342,16 +341,16 @@ def learn(F, converter=None, solver=None, max_learnt_length=3, interreduction=Fa EXAMPLES:: - sage: from sage.sat.boolean_polynomials import learn as learn_sat # optional - pycryptosat + sage: from sage.sat.boolean_polynomials import learn as learn_sat We construct a simple system and solve it:: - sage: set_random_seed(2300) - sage: sr = mq.SR(1, 2, 2, 4, gf2=True, polybori=True) # optional - pycryptosat, needs sage.modules sage.rings.finite_rings - sage: F,s = sr.polynomial_system() # optional - pycryptosat # needs sage.modules sage.rings.finite_rings - sage: H = learn_sat(F) # optional - pycryptosat # needs sage.modules sage.rings.finite_rings - sage: H[-1] # optional - pycryptosat # needs sage.modules sage.rings.finite_rings - k033 + 1 + sage: set_random_seed(2300) + sage: sr = mq.SR(1, 2, 2, 4, gf2=True, polybori=True) + sage: F,s = sr.polynomial_system() + sage: H = learn_sat(F) + sage: H[-1] + k033 + 1 """ try: len(F) From 3860c75944c5f536e682a74a20520c18cadc18b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Nov 2023 17:54:41 +0100 Subject: [PATCH 168/463] Update src/sage/rings/integer.pyx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Köppe --- src/sage/rings/integer.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 744e8d37cf8..667d0bcbb13 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -3823,7 +3823,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): else: # self is big -- it doesn't fit in unsigned long. if start <= 2 and mpz_even_p(self.value): - mpz_set_ui(x.value,2) + mpz_set_ui(x.value, 2) return x if start <= 3 and mpz_divisible_ui_p(self.value,3): mpz_set_ui(x.value,3) From 6c514c9898973466c09af48eedb28d66d4e11f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Nov 2023 17:54:57 +0100 Subject: [PATCH 169/463] Update src/sage/rings/integer.pyx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Köppe --- src/sage/rings/integer.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 667d0bcbb13..36fa4eb56ff 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -3825,7 +3825,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): if start <= 2 and mpz_even_p(self.value): mpz_set_ui(x.value, 2) return x - if start <= 3 and mpz_divisible_ui_p(self.value,3): + if start <= 3 and mpz_divisible_ui_p(self.value, 3): mpz_set_ui(x.value,3) return x if start <= 5 and mpz_divisible_ui_p(self.value,5): From 8955ceb13acccf55fef6958802f69c16e1f7c17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Nov 2023 17:55:41 +0100 Subject: [PATCH 170/463] Update src/sage/rings/integer.pyx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Köppe --- src/sage/rings/integer.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 36fa4eb56ff..52a2498eafa 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -2871,7 +2871,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): from sage.functions.log import function_log return function_log(self,dont_call_method_on_arg=True)/\ - function_log(m,dont_call_method_on_arg=True) + function_log(m, dont_call_method_on_arg=True) def exp(self, prec=None): r""" From 3453deaec6049dfb508673760d68a6ed21d3cbc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Nov 2023 17:55:59 +0100 Subject: [PATCH 171/463] Update src/sage/rings/integer.pyx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Köppe --- src/sage/rings/integer.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 52a2498eafa..b86e6c26fa9 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -2870,7 +2870,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return elog from sage.functions.log import function_log - return function_log(self,dont_call_method_on_arg=True)/\ + return function_log(self, dont_call_method_on_arg=True)/\ function_log(m, dont_call_method_on_arg=True) def exp(self, prec=None): From e48fa7fc9ff23bac8e5e19aedd8f507c970cbf37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Nov 2023 17:56:21 +0100 Subject: [PATCH 172/463] Update src/sage/rings/integer.pyx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Köppe --- src/sage/rings/integer.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index b86e6c26fa9..ba5818ed327 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -3829,7 +3829,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): mpz_set_ui(x.value,3) return x if start <= 5 and mpz_divisible_ui_p(self.value,5): - mpz_set_ui(x.value,5) + mpz_set_ui(x.value, 5) return x # x.value = floor(sqrt(self.value)) From 4d5efc6e96a955a5bbb51002cc960008bac0fd84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Nov 2023 17:56:33 +0100 Subject: [PATCH 173/463] Update src/sage/rings/integer.pyx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Köppe --- src/sage/rings/integer.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index ba5818ed327..6774df8b4c2 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -3826,9 +3826,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): mpz_set_ui(x.value, 2) return x if start <= 3 and mpz_divisible_ui_p(self.value, 3): - mpz_set_ui(x.value,3) + mpz_set_ui(x.value, 3) return x - if start <= 5 and mpz_divisible_ui_p(self.value,5): + if start <= 5 and mpz_divisible_ui_p(self.value, 5): mpz_set_ui(x.value, 5) return x From d3e4c701e32fd4061df0b51e247043de7001bad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Nov 2023 17:56:48 +0100 Subject: [PATCH 174/463] Update src/sage/rings/integer.pyx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Köppe --- src/sage/rings/integer.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 6774df8b4c2..e6e19f1c6b6 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -4073,7 +4073,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: 0.support() Traceback (most recent call last): ... - ArithmeticError: Support of 0 not defined + ArithmeticError: support of 0 not defined """ if self.is_zero(): raise ArithmeticError("Support of 0 not defined") From 0d3d2fc53d3c1b732a0e59f909be5044d5861e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Nov 2023 17:56:56 +0100 Subject: [PATCH 175/463] Update src/sage/rings/integer.pyx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Köppe --- src/sage/rings/integer.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index e6e19f1c6b6..4a3ce95f609 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -4076,7 +4076,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ArithmeticError: support of 0 not defined """ if self.is_zero(): - raise ArithmeticError("Support of 0 not defined") + raise ArithmeticError("support of 0 not defined") return sage.arith.all.prime_factors(self) def coprime_integers(self, m): From b86d8920bf5dbb8e69ddb2216e92218805c538e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Nov 2023 17:59:31 +0100 Subject: [PATCH 176/463] suggested details --- src/sage/rings/integer.pyx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 4a3ce95f609..b1856bb9243 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -207,8 +207,7 @@ new_gen_from_integer = None cdef extern from *: int unlikely(int) nogil # Defined by Cython -cdef object numpy_long_interface = {'typestr': '=i4' if sizeof(long) == 4 - else '=i8'} +cdef object numpy_long_interface = {'typestr': '=i4' if sizeof(long) == 4 else '=i8'} cdef object numpy_int64_interface = {'typestr': '=i8'} cdef object numpy_object_interface = {'typestr': '|O'} @@ -5274,8 +5273,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return (self, zero) if get_data else False _small_primes_table[:] = [ - 0,1,1,1,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0, # 001, 03,..., 49 - 0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0, # 051, 53,..., 99 + 0,1,1,1,0,1,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0, # 1,3,...,49 + 0,1,0,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,0, # 51,53,...,99 1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,0,1, # 101,103,...,149 1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,1,0,1,1, # 151,153,...,199 0,0,0,0,0,1,0,0,0,0,0,1,0,1,1,0,1,0,0,1,1,0,0,0,0, # 201,203,...,249 From 46a14410e260666ba5359cc01d63df93855730c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Nov 2023 20:44:48 +0100 Subject: [PATCH 177/463] suggested fix --- src/sage/modular/abvar/homspace.py | 36 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/sage/modular/abvar/homspace.py b/src/sage/modular/abvar/homspace.py index ab1544d2698..d0e192d2808 100644 --- a/src/sage/modular/abvar/homspace.py +++ b/src/sage/modular/abvar/homspace.py @@ -168,15 +168,15 @@ - Craig Citro, Robert Bradshaw (2008-03): Rewrote with modabvar overhaul """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 William Stein # # 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 copy import copy @@ -188,7 +188,6 @@ from . import morphism -import sage.rings.integer_ring from sage.rings.infinity import Infinity from sage.rings.ring import Ring @@ -276,7 +275,7 @@ def _matrix_space(self): sage: Hom(J0(11), J0(22))._matrix_space Full MatrixSpace of 2 by 4 dense matrices over Integer Ring """ - return MatrixSpace(ZZ,2*self.domain().dimension(), 2*self.codomain().dimension()) + return MatrixSpace(ZZ, 2*self.domain().dimension(), 2*self.codomain().dimension()) def _element_constructor_from_element_class(self, *args, **keywords): """ @@ -479,7 +478,7 @@ def free_module(self): """ self.calculate_generators() V = ZZ**(4*self.domain().dimension() * self.codomain().dimension()) - return V.submodule([ V(m.matrix().list()) for m in self.gens() ]) + return V.submodule([V(m.matrix().list()) for m in self.gens()]) def gen(self, i=0): """ @@ -570,7 +569,7 @@ def calculate_generators(self): return if (self.domain() == self.codomain()) and (self.domain().dimension() == 1): - self._gens = ( identity_matrix(ZZ,2), ) + self._gens = (identity_matrix(ZZ, 2),) return phi = self.domain()._isogeny_to_product_of_powers() @@ -583,9 +582,9 @@ def calculate_generators(self): Mt = psi.complementary_isogeny().matrix() R = ZZ**(4*self.domain().dimension()*self.codomain().dimension()) - gens = R.submodule([ (M*self._get_matrix(g)*Mt).list() - for g in im_gens ]).saturation().basis() - self._gens = tuple([ self._get_matrix(g) for g in gens ]) + gens = R.submodule([(M*self._get_matrix(g)*Mt).list() + for g in im_gens]).saturation().basis() + self._gens = tuple([self._get_matrix(g) for g in gens]) def _calculate_product_gens(self): """ @@ -746,7 +745,8 @@ def _calculate_simple_gens(self): Mf = f.matrix() Mg = g.matrix() - return [ Mf * self._get_matrix(e) * Mg for e in ls ] + return [Mf * self._get_matrix(e) * Mg for e in ls] + # NOTE/WARNING/TODO: Below in the __init__, etc. we do *not* check # that the input gens are give something that spans a sub*ring*, as apposed @@ -820,7 +820,7 @@ def __init__(self, A, gens=None, category=None): if gens is None: self._gens = None else: - self._gens = tuple([ self._get_matrix(g) for g in gens ]) + self._gens = tuple([self._get_matrix(g) for g in gens]) self._is_full_ring = gens is None def _repr_(self): @@ -903,7 +903,7 @@ def index_in_saturation(self): A = self.abelian_variety() d = A.dimension() M = ZZ**(4*d**2) - gens = [ x.matrix().list() for x in self.gens() ] + gens = [x.matrix().list() for x in self.gens()] R = M.submodule(gens) return R.index_in_saturation() @@ -934,8 +934,8 @@ def discriminant(self): 2 """ g = self.gens() - M = Matrix(ZZ,len(g), [ (g[i]*g[j]).trace() - for i in range(len(g)) for j in range(len(g)) ]) + M = Matrix(ZZ, len(g), [(g[i]*g[j]).trace() + for i in range(len(g)) for j in range(len(g))]) return M.determinant() def image_of_hecke_algebra(self, check_every=1): @@ -1002,18 +1002,18 @@ def image_of_hecke_algebra(self, check_every=1): EndVecZ = ZZ**(4*d**2) if d == 1: - self.__hecke_algebra_image = EndomorphismSubring(A, [[1,0,0,1]]) + self.__hecke_algebra_image = EndomorphismSubring(A, [[1, 0, 0, 1]]) return self.__hecke_algebra_image V = EndVecZ.submodule([A.hecke_operator(1).matrix().list()]) - for n in range(2,M.sturm_bound()+1): + for n in range(2, M.sturm_bound()+1): if (check_every > 0 and n % check_every == 0 and V.dimension() == d and V.index_in_saturation() == 1): break - V += EndVecZ.submodule([ A.hecke_operator(n).matrix().list() ]) + V += EndVecZ.submodule([A.hecke_operator(n).matrix().list()]) self.__hecke_algebra_image = EndomorphismSubring(A, V.basis()) return self.__hecke_algebra_image From f33ad68d24485d137b4e04f65f881055a67918ce Mon Sep 17 00:00:00 2001 From: Lorenz Panny <84067835+yyyyx4@users.noreply.github.com> Date: Tue, 7 Nov 2023 09:35:03 +0100 Subject: [PATCH 178/463] reviewer comment Co-authored-by: Travis Scrimshaw --- src/sage/schemes/elliptic_curves/mod_poly.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/schemes/elliptic_curves/mod_poly.py b/src/sage/schemes/elliptic_curves/mod_poly.py index 88af6185a7b..cb8cd703f69 100644 --- a/src/sage/schemes/elliptic_curves/mod_poly.py +++ b/src/sage/schemes/elliptic_curves/mod_poly.py @@ -163,4 +163,5 @@ def _set_cache_bound(bnd): """ global _cache_bound _cache_bound = bnd + classical_modular_polynomial.set_cache_bound = _set_cache_bound From d3767f0b4b99da2f74c6ef1703234f598929870c Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Tue, 7 Nov 2023 10:40:41 +0100 Subject: [PATCH 179/463] corrections from review --- src/sage/rings/polynomial/laurent_polynomial_ideal.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 924ce7ed7d3..d569dc06101 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -195,9 +195,7 @@ def __contains__(self, f): sage: x + 3*y in I True - We test that these changes allow to use this method in the inivariate case. - - TESTS:: + This also works in the univariate case:: sage: P. = LaurentPolynomialRing(QQ) sage: I = P.ideal([x^2 + 3*x]) @@ -215,7 +213,7 @@ def __contains__(self, f): def gens_reduced(self): """ - A reduced system of generators. + Return a reduced system of generators. EXAMPLES:: From 5f96b24e3cfc7c77ad436c00bb92ecdbaedd1006 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Thu, 9 Nov 2023 08:27:06 +0100 Subject: [PATCH 180/463] typos --- src/sage/graphs/generic_graph.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 9e1923cc9fa..af107b74f31 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -8070,17 +8070,17 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", Traceback (most recent call last): ... ValueError: parameters s, t, and use_edge_labels can not be used in - combinaiton with algorithms 'backtrack' and 'heuristic' + combination with algorithms 'backtrack' and 'heuristic' sage: G.longest_path(algorithm='heuristic', t=2) Traceback (most recent call last): ... ValueError: parameters s, t, and use_edge_labels can not be used in - combinaiton with algorithms 'backtrack' and 'heuristic' + combination with algorithms 'backtrack' and 'heuristic' sage: G.longest_path(algorithm='heuristic', use_edge_labels=True) Traceback (most recent call last): ... ValueError: parameters s, t, and use_edge_labels can not be used in - combinaiton with algorithms 'backtrack' and 'heuristic' + combination with algorithms 'backtrack' and 'heuristic' """ self._scream_if_not_simple() @@ -8095,7 +8095,7 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", if algorithm == 'heuristic': if s is not None or t is not None or use_edge_labels: raise ValueError("parameters s, t, and use_edge_labels can not " - "be used in combinaiton with algorithms " + "be used in combination with algorithms " "'backtrack' and 'heuristic'") # Quick improvement From 2fbaf8afc0216f318898d7066f6e318e8b7f3e96 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Thu, 9 Nov 2023 08:55:01 +0100 Subject: [PATCH 181/463] deprecate algorithm backtrack --- src/sage/graphs/generic_graph.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index af107b74f31..b6d2fc13917 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -7907,8 +7907,7 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", * ``"MILP"`` returns an exact answer. - * ``"backtrack"`` will be renamed ``"heuristic"`` in the future. A - warning is raised when used. + * ``"backtrack"`` is renamed ``"heuristic"`` (:issue:`36574`). * ``"heuristic"`` is a randomized heuristic for finding a long path in an unweighted (di)graph. This heuristic does not take into account @@ -8064,39 +8063,38 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", sage: G = graphs.PathGraph(3) sage: P = G.longest_path(algorithm='backtrack') - doctest:...: FutureWarning: algorithm 'backtrack' will be renamed 'heuristic' in the future. + doctest:...: DeprecationWarning: algorithm 'backtrack' is deprecated. + Use algorithm 'heuristic' instead. See https://github.com/sagemath/sage/issues/36574 for details. sage: G.longest_path(algorithm='heuristic', s=0) Traceback (most recent call last): ... ValueError: parameters s, t, and use_edge_labels can not be used in - combination with algorithms 'backtrack' and 'heuristic' + combination with algorithm 'heuristic' sage: G.longest_path(algorithm='heuristic', t=2) Traceback (most recent call last): ... ValueError: parameters s, t, and use_edge_labels can not be used in - combination with algorithms 'backtrack' and 'heuristic' + combination with algorithm 'heuristic' sage: G.longest_path(algorithm='heuristic', use_edge_labels=True) Traceback (most recent call last): ... ValueError: parameters s, t, and use_edge_labels can not be used in - combination with algorithms 'backtrack' and 'heuristic' + combination with algorithm 'heuristic' """ self._scream_if_not_simple() if algorithm not in ("backtrack", "heuristic", "MILP"): raise ValueError("algorithm must be either 'backtrack', 'heuristic' or 'MILP'") if algorithm == "backtrack": - from sage.misc.superseded import warning - warning(36574, - "algorithm 'backtrack' will be renamed 'heuristic' in the future.", - FutureWarning) + from sage.misc.superseded import deprecation + deprecation(36574, "algorithm 'backtrack' is deprecated. " + "Use algorithm 'heuristic' instead.") algorithm = 'heuristic' if algorithm == 'heuristic': if s is not None or t is not None or use_edge_labels: raise ValueError("parameters s, t, and use_edge_labels can not " - "be used in combination with algorithms " - "'backtrack' and 'heuristic'") + "be used in combination with algorithm 'heuristic'") # Quick improvement if not self.is_connected(): From fe0b6255475ce182833898d0175354f6c58a33e9 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Mon, 30 Oct 2023 23:21:36 +0900 Subject: [PATCH 182/463] Add pull_from_function_field --- src/sage/schemes/curves/affine_curve.py | 168 ++++++++++++++++---- src/sage/schemes/curves/projective_curve.py | 68 +++++++- 2 files changed, 201 insertions(+), 35 deletions(-) diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py index ce8c0ff0655..194353c79c4 100644 --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -2118,9 +2118,11 @@ def function(self, f): INPUT: - - ``f`` -- an element of the coordinate ring of either the curve or its + - ``f`` -- an element of the fraction field of the coordinate ring of the curve or its ambient space. + OUTPUT: An element of the function field of this curve. + EXAMPLES:: sage: # needs sage.rings.finite_rings @@ -2161,38 +2163,76 @@ def coordinate_functions(self): """ return self._coordinate_functions + def pull_from_function_field(self, f): + """ + Return the fraction corresponding to ``f``. + + INPUT: + + - ``f`` -- an element of the function field + + OUTPUT: + + A fraction of polynomials in the coordinate ring of this curve. + + EXAMPLES:: + + sage: # needs sage.rings.finite_rings + sage: A. = AffineSpace(GF(8), 2) + sage: C = Curve(x^5 + y^5 + x*y + 1) + sage: F = C.function_field() + sage: C.pull_from_function_field(F.gen()) + y + sage: C.pull_from_function_field(F.one()) + 1 + sage: C.pull_from_function_field(F.zero()) + 0 + sage: f1 = F.gen() + sage: f2 = F.base_ring().gen() + sage: C.function(C.pull_from_function_field(f1)) == f1 + True + sage: C.function(C.pull_from_function_field(f2)) == f2 + True + """ + return self._pull_from_function_field(f) + @lazy_attribute def _nonsingular_model(self): """ Return the data of a nonsingular model of the curve. The data consists of an abstract function field `M` and a map from the - coordinate ring `R` of the ambient space of the curve into the function - field. The coordinate ring of the curve is thus the quotient of `R` by - the kernel of the map. + fraction field of the coordinate ring `R` of the ambient space of the curve to the function + field. The coordinate ring of the curve is the quotient of `R` by + the kernel of the map restricted to `R`. + TESTS:: - sage: A. = AffineSpace(GF(11), 3) sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) sage: C._nonsingular_model (Function field in z defined by z^3 + 10*x, Ring morphism: - From: Multivariate Polynomial Ring in x, y, z - over Finite Field of size 11 + From: Fraction Field of Multivariate Polynomial Ring in x, y, z over Finite Field of size 11 To: Function field in z defined by z^3 + 10*x Defn: x |--> x y |--> z^2 - z |--> z) + z |--> z, + Ring morphism: + From: Function field in z defined by z^3 + 10*x + To: Fraction Field of Multivariate Polynomial Ring in x, y, z over Finite Field of size 11) """ + from sage.structure.sequence import Sequence + from sage.rings.fraction_field import FractionField from sage.rings.function_field.constructor import FunctionField + from sage.rings.function_field.maps import FunctionFieldRingMorphism k = self.base_ring() - I0 = self.defining_ideal() + I = self.defining_ideal() # invlex is the lex order with x < y < z for R = k[x,y,z] for instance - R = I0.parent().ring().change_ring(order='invlex') - I0 = I0.change_ring(R) + R = I.parent().ring().change_ring(order='invlex') + I0 = I.change_ring(R) n = R.ngens() names = R.variable_names() @@ -2228,6 +2268,7 @@ def _nonsingular_model(self): # syzygy for z. Now x is the generator of a rational function field F0; # y is the generator of the extension F1 of F0 by f3; z is the # generator of the extension F2 of F1 by f2. + basis = list(gbasis) syzygy = {} for i in range(n): @@ -2241,11 +2282,11 @@ def _nonsingular_model(self): basis.append(f) break - indep = [i for i in range(n) if i not in syzygy] - if len(indep) != 1: + # sanity check + indeps = [i for i in range(n) if i not in syzygy] + if len(indeps) != 1: raise TypeError("not a curve") - else: - indep = indep[0] + indep = indeps[0] F = FunctionField(k, names[indep]) coords = {indep: F.gen()} @@ -2258,20 +2299,60 @@ def _nonsingular_model(self): F = F.extension(f, names[i]) coords[i] = F.gen() - if F.base_field() is not F: # proper extension + proper_extension = F.base_field() is not F # and n is 1 + + if proper_extension: N, from_N, to_N = F.simple_model() M, from_M, to_M = N.separable_model() coordinate_functions = tuple([to_M(to_N(F(coords[i]))) for i in range(n)]) - else: # rational function field - M = F + else: + M = F # is rational function field coordinate_functions = tuple([coords[i] for i in range(n)]) - lift_to_function_field = hom(R, M, coordinate_functions) + # map to M + + FR = FractionField(I.ring()) + map_to_function_field = hom(FR, M, coordinate_functions) + + # map from M + + def convert(f, i): + if i == indep: + i = i - 1 + if i < 0: + return f._x # fraction representing rational function field element + fx = f._x # polynomial representing function field element + if not fx: + fxlist = [fx.base_ring().zero()] + else: + fxlist = fx.list() + coeffs = Sequence(convert(c, i - 1) for c in fxlist) + B = coeffs.universe() + S = B[names[i]] + return S(coeffs) + + z = M.gen() + + if proper_extension: + Z = FR(convert(from_N(from_M(z)), n - 1)) + + def evaluate(f): + coeffs = f._x.list() + v = 0 + while coeffs: + v = v * Z + coeffs.pop()._x + return FR(v) + else: + def evaluate(f): + return FR(f._x) + + map_from_function_field = FunctionFieldRingMorphism(Hom(M, FR), evaluate) # sanity check - assert all(lift_to_function_field(f).is_zero() for f in I0.gens()) + assert all(map_to_function_field(f).is_zero() for f in I.gens()) + assert map_to_function_field(map_from_function_field(z)) == z - return M, lift_to_function_field + return M, map_to_function_field, map_from_function_field @lazy_attribute def _function_field(self): @@ -2290,7 +2371,7 @@ def _function_field(self): @lazy_attribute def _lift_to_function_field(self): """ - Return the map to function field of the curve. + Return the map to the function field of the curve. TESTS:: @@ -2298,8 +2379,7 @@ def _lift_to_function_field(self): sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) sage: C._lift_to_function_field Ring morphism: - From: Multivariate Polynomial Ring in x, y, z - over Finite Field of size 11 + From: Fraction Field of Multivariate Polynomial Ring in x, y, z over Finite Field of size 11 To: Function field in z defined by z^3 + 10*x Defn: x |--> x y |--> z^2 @@ -2321,16 +2401,34 @@ def _coordinate_functions(self): """ return self._nonsingular_model[1].im_gens() + @lazy_attribute + def _pull_from_function_field(self): + """ + Return the map from the function field of the curve. + + TESTS:: + + sage: A. = AffineSpace(GF(11), 3) + sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) + sage: C._pull_from_function_field + Ring morphism: + From: Function field in z defined by z^3 + 10*x + To: Fraction Field of Multivariate Polynomial Ring in x, y, z over Finite Field of size 11 + """ + return self._nonsingular_model[2] + @lazy_attribute def _singularities(self): """ - Return a list of the pairs of singular closed points and the places above it. + Return a list of the pairs of a singular closed point and the places + above it. TESTS:: - sage: A. = AffineSpace(GF(7^2), 2) # needs sage.rings.finite_rings - sage: C = Curve(x^2 - x^4 - y^4) # needs sage.rings.finite_rings - sage: C._singularities # long time # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: A. = AffineSpace(GF(7^2), 2) + sage: C = Curve(x^2 - x^4 - y^4) + sage: C._singularities # long time [(Point (x, y), [Place (x, 1/x*y^3 + 1/x*y^2 + 1), Place (x, 1/x*y^3 + 1/x*y^2 + 6)])] """ @@ -2370,9 +2468,10 @@ def singular_closed_points(self): EXAMPLES:: - sage: A. = AffineSpace(GF(7^2), 2) # needs sage.rings.finite_rings - sage: C = Curve(x^2 - x^4 - y^4) # needs sage.rings.finite_rings - sage: C.singular_closed_points() # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: A. = AffineSpace(GF(7^2), 2) + sage: C = Curve(x^2 - x^4 - y^4) + sage: C.singular_closed_points() [Point (x, y)] :: @@ -2726,11 +2825,12 @@ class IntegralAffinePlaneCurve_finite_field(AffinePlaneCurve_finite_field, Integ EXAMPLES:: - sage: A. = AffineSpace(GF(8), 2) # needs sage.rings.finite_rings - sage: C = Curve(x^5 + y^5 + x*y + 1); C # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: A. = AffineSpace(GF(8), 2) + sage: C = Curve(x^5 + y^5 + x*y + 1); C Affine Plane Curve over Finite Field in z3 of size 2^3 defined by x^5 + y^5 + x*y + 1 - sage: C.function_field() # needs sage.rings.finite_rings + sage: C.function_field() Function field in y defined by y^5 + x*y + x^5 + 1 """ _point = IntegralAffinePlaneCurvePoint_finite_field diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index 5a4f9f5f4ce..1cd62149bc9 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -2325,7 +2325,13 @@ def __call__(self, *args): def function(self, f): """ - Return the function field element coerced from ``x``. + Return the function field element coerced from ``f``. + + INPUT: + + - ``f`` -- an element in the fraction field of the coordinate ring + + OUTPUT: An element of the function field EXAMPLES:: @@ -2373,6 +2379,39 @@ def coordinate_functions(self, i=None): inv = ~coords[i] return tuple([coords[j]*inv for j in range(len(coords)) if j != i]) + def pull_from_function_field(self, f): + """ + Return the fraction corresponding to ``f``. + + INPUT: + + - ``f`` -- an element of the function field + + OUTPUT: + + A fraction of homogeneous polynomials in the coordinate ring of this curve. + + EXAMPLES:: + + sage: # needs sage.rings.finite_rings + sage: P. = ProjectiveSpace(GF(4), 2) + sage: C = Curve(x^5 + y^5 + x*y*z^3 + z^5) + sage: F = C.function_field() + sage: C.pull_from_function_field(F.gen()) + z/x + sage: C.pull_from_function_field(F.one()) + 1 + sage: C.pull_from_function_field(F.zero()) + 0 + sage: f1 = F.gen() + sage: f2 = F.base_ring().gen() + sage: C.function(C.pull_from_function_field(f1)) == f1 + True + sage: C.function(C.pull_from_function_field(f2)) == f2 + True + """ + return self._pull_from_function_field(f) + @lazy_attribute def _function_field(self): """ @@ -2425,6 +2464,33 @@ def _coordinate_functions(self): coords.insert(self._open_affine_index, self._function_field.one()) return tuple(coords) + @lazy_attribute + def _pull_from_function_field(self): + """ + Return the map to the function field of the curve. + + TESTS:: + + sage: P. = ProjectiveSpace(GF(5), 2) + sage: C = Curve(y^2*z^7 - x^9 - x*z^8) + sage: F = C.function_field() + sage: f = F.random_element() + sage: C.function(C._pull_from_function_field(f)) == f + True + """ + F = self._function_field + S = self.ambient_space().coordinate_ring() + phi = self._open_affine._nonsingular_model[2] + i = self._open_affine_index + + def pull(f): + pf = phi(f) + num = S(pf.numerator()).homogenize(i) + den = S(pf.denominator()).homogenize(i) + return num / den * S.gen(i) ** (den.total_degree() - num.total_degree()) + + return pull + @lazy_attribute def _singularities(self): """ From 465bb927ec0e4bfbf46d9a029f6a21eabcd8e88c Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Tue, 31 Oct 2023 10:37:16 +0900 Subject: [PATCH 183/463] Style fixes --- src/sage/schemes/curves/affine_curve.py | 22 ++++++++++++--------- src/sage/schemes/curves/projective_curve.py | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py index 194353c79c4..97d4bc08dd3 100644 --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -2118,8 +2118,8 @@ def function(self, f): INPUT: - - ``f`` -- an element of the fraction field of the coordinate ring of the curve or its - ambient space. + - ``f`` -- an element of the fraction field of the coordinate ring of + the curve or its ambient space. OUTPUT: An element of the function field of this curve. @@ -2202,9 +2202,9 @@ def _nonsingular_model(self): Return the data of a nonsingular model of the curve. The data consists of an abstract function field `M` and a map from the - fraction field of the coordinate ring `R` of the ambient space of the curve to the function - field. The coordinate ring of the curve is the quotient of `R` by - the kernel of the map restricted to `R`. + fraction field of the coordinate ring `R` of the ambient space of the + curve to the function field. The coordinate ring of the curve is the + quotient of `R` by the kernel of the map restricted to `R`. TESTS:: @@ -2213,14 +2213,16 @@ def _nonsingular_model(self): sage: C._nonsingular_model (Function field in z defined by z^3 + 10*x, Ring morphism: - From: Fraction Field of Multivariate Polynomial Ring in x, y, z over Finite Field of size 11 + From: Fraction Field of Multivariate Polynomial Ring in x, y, z + over Finite Field of size 11 To: Function field in z defined by z^3 + 10*x Defn: x |--> x y |--> z^2 z |--> z, Ring morphism: From: Function field in z defined by z^3 + 10*x - To: Fraction Field of Multivariate Polynomial Ring in x, y, z over Finite Field of size 11) + To: Fraction Field of Multivariate Polynomial Ring in x, y, z + over Finite Field of size 11) """ from sage.structure.sequence import Sequence from sage.rings.fraction_field import FractionField @@ -2379,7 +2381,8 @@ def _lift_to_function_field(self): sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) sage: C._lift_to_function_field Ring morphism: - From: Fraction Field of Multivariate Polynomial Ring in x, y, z over Finite Field of size 11 + From: Fraction Field of Multivariate Polynomial Ring in x, y, z + over Finite Field of size 11 To: Function field in z defined by z^3 + 10*x Defn: x |--> x y |--> z^2 @@ -2413,7 +2416,8 @@ def _pull_from_function_field(self): sage: C._pull_from_function_field Ring morphism: From: Function field in z defined by z^3 + 10*x - To: Fraction Field of Multivariate Polynomial Ring in x, y, z over Finite Field of size 11 + To: Fraction Field of Multivariate Polynomial Ring in x, y, z + over Finite Field of size 11 """ return self._nonsingular_model[2] diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index 1cd62149bc9..fcb87d9e31c 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -2331,7 +2331,7 @@ def function(self, f): - ``f`` -- an element in the fraction field of the coordinate ring - OUTPUT: An element of the function field + OUTPUT: An element of the function field. EXAMPLES:: From 64c755e5d7cb14acbb55c4aea1e8cbc9a4c15c2c Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 9 Nov 2023 21:44:47 +0900 Subject: [PATCH 184/463] Fix an example --- src/sage/schemes/curves/affine_curve.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py index 97d4bc08dd3..d329b21fddf 100644 --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -2209,6 +2209,7 @@ def _nonsingular_model(self): TESTS:: + sage: A. = AffineSpace(GF(11), 3) sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) sage: C._nonsingular_model (Function field in z defined by z^3 + 10*x, From 28655bd2072d07f99535ca8f94c840b2064b20f7 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 9 Nov 2023 14:49:49 +0100 Subject: [PATCH 185/463] fix point_of_order() for l==p --- src/sage/schemes/elliptic_curves/ell_field.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 064aeeed78b..d29ae37c1ae 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -2122,7 +2122,8 @@ def ffext(poly): if not m: raise NotImplementedError('only prime-power orders are currently supported') - xpoly = E.division_polynomial(n) // E.division_polynomial(n//l) + xpoly = E.division_polynomial(n).radical() + xpoly //= E.division_polynomial(n//l).radical() if xpoly.degree() < 1: # supersingular and l == p raise ValueError('curve does not have any points of the specified order') From 36af1591299737a8acfb6a3151a59bf92ee87d13 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 9 Nov 2023 15:49:17 +0100 Subject: [PATCH 186/463] add .inseparable_degree() method --- .../elliptic_curves/ell_curve_isogeny.py | 25 +-- src/sage/schemes/elliptic_curves/hom.py | 168 +++++++++++++++--- .../schemes/elliptic_curves/hom_composite.py | 58 ++---- .../schemes/elliptic_curves/hom_frobenius.py | 55 +----- .../schemes/elliptic_curves/hom_scalar.py | 79 +++----- src/sage/schemes/elliptic_curves/hom_sum.py | 88 +++++---- .../schemes/elliptic_curves/hom_velusqrt.py | 18 +- .../elliptic_curves/weierstrass_morphism.py | 29 ++- 8 files changed, 273 insertions(+), 247 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index 75d10d147d6..1ab3981b4cf 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -2879,28 +2879,19 @@ def kernel_polynomial(self): self.__init_kernel_polynomial() return self.__kernel_polynomial - def is_separable(self): + def inseparable_degree(self): r""" - Determine whether or not this isogeny is separable. + Return the inseparable degree of this isogeny. - Since :class:`EllipticCurveIsogeny` only implements - separable isogenies, this method always returns ``True``. + Since this class only implements separable isogenies, + this method always returns one. - EXAMPLES:: - - sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) - sage: phi = EllipticCurveIsogeny(E, E((0,0))) - sage: phi.is_separable() - True - - :: + TESTS:: - sage: E = EllipticCurve('11a1') - sage: phi = EllipticCurveIsogeny(E, E.torsion_points()) - sage: phi.is_separable() - True + sage: EllipticCurveIsogeny.inseparable_degree(None) + 1 """ - return True + return Integer(1) def _set_pre_isomorphism(self, preWI): """ diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index fe95bb7e2b3..9133fe13691 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -674,41 +674,115 @@ def is_normalized(self): ALGORITHM: We check if :meth:`scaling_factor` returns `1`. """ - return self.scaling_factor() == 1 + return self.scaling_factor().is_one() - def is_separable(self): + def inseparable_degree(self): r""" - Determine whether or not this morphism is separable. + Return the inseparable degree of this isogeny. Implemented by child classes. For examples, see: - - :meth:`EllipticCurveIsogeny.is_separable` - - :meth:`sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism.is_separable` - - :meth:`sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite.is_separable` - - :meth:`sage.schemes.elliptic_curves.hom_sum.EllipticCurveHom_sum.is_separable` - - :meth:`sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar.is_separable` - - :meth:`sage.schemes.elliptic_curves.hom_frobenius.EllipticCurveHom_frobenius.is_separable` + - :meth:`EllipticCurveIsogeny.inseparable_degree` + - :meth:`sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism.inseparable_degree` + - :meth:`sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite.inseparable_degree` + - :meth:`sage.schemes.elliptic_curves.hom_sum.EllipticCurveHom_sum.inseparable_degree` + - :meth:`sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar.inseparable_degree` + - :meth:`sage.schemes.elliptic_curves.hom_frobenius.EllipticCurveHom_frobenius.inseparable_degree` TESTS:: sage: from sage.schemes.elliptic_curves.hom import EllipticCurveHom - sage: EllipticCurveHom.is_separable(None) + sage: EllipticCurveHom.inseparable_degree(None) Traceback (most recent call last): ... NotImplementedError: ... """ raise NotImplementedError('children must implement') - def is_surjective(self): + def is_separable(self): r""" - Determine whether or not this morphism is surjective. + Determine whether or not this morphism is a separable isogeny. - .. NOTE:: + EXAMPLES:: + + sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) + sage: phi = EllipticCurveIsogeny(E, E((0,0))) + sage: phi.is_separable() + True + + :: + + sage: E = EllipticCurve('11a1') + sage: phi = EllipticCurveIsogeny(E, E.torsion_points()) + sage: phi.is_separable() + True + + :: + + sage: E = EllipticCurve(GF(31337), [0,1]) # needs sage.rings.finite_rings + sage: {f.is_separable() for f in E.automorphisms()} # needs sage.rings.finite_rings + {True} + + :: + + sage: # needs sage.rings.finite_rings + sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite + sage: E = EllipticCurve(GF(7^2), [3,2]) + sage: P = E.lift_x(1) + sage: phi = EllipticCurveHom_composite(E, P); phi + Composite morphism of degree 7 = 7: + From: Elliptic Curve defined by y^2 = x^3 + 3*x + 2 + over Finite Field in z2 of size 7^2 + To: Elliptic Curve defined by y^2 = x^3 + 3*x + 2 + over Finite Field in z2 of size 7^2 + sage: phi.is_separable() + True + + :: + + sage: E = EllipticCurve(GF(11), [4,4]) + sage: E.scalar_multiplication(11).is_separable() + False + sage: E.scalar_multiplication(-11).is_separable() + False + sage: E.scalar_multiplication(777).is_separable() + True + sage: E.scalar_multiplication(-1).is_separable() + True + sage: E.scalar_multiplication(77).is_separable() + False + sage: E.scalar_multiplication(121).is_separable() + False - This method currently always returns ``True``, since a - non-constant map of algebraic curves must be surjective, - and Sage does not yet implement the constant zero map. - This will probably change in the future. + :: + + sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius + sage: E = EllipticCurve(GF(11), [1,1]) + sage: pi = EllipticCurveHom_frobenius(E) + sage: pi.degree() + 11 + sage: pi.is_separable() + False + sage: pi = EllipticCurveHom_frobenius(E, 0) + sage: pi.degree() + 1 + sage: pi.is_separable() + True + + :: + + sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) + sage: phi = E.isogeny(E((1,2)), algorithm='velusqrt') + sage: phi.is_separable() + True + """ + if self.is_zero(): + raise ValueError('constant zero map is not an isogeny') + return self.inseparable_degree().is_one() + + def is_surjective(self): + r""" + Determine whether or not this morphism is surjective. EXAMPLES:: @@ -741,6 +815,9 @@ def is_injective(self): r""" Determine whether or not this morphism has trivial kernel. + The kernel is trivial if and only if this morphism is a + purely inseparable isogeny. + EXAMPLES:: sage: E = EllipticCurve('11a1') @@ -763,22 +840,59 @@ def is_injective(self): sage: phi = EllipticCurveIsogeny(E, E(0)) sage: phi.is_injective() True + + :: + + sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite + sage: E = EllipticCurve([1,0]) + sage: phi = EllipticCurveHom_composite(E, E(0,0)) + sage: phi.is_injective() + False + sage: E = EllipticCurve_from_j(GF(3).algebraic_closure()(0)) + sage: nu = EllipticCurveHom_composite.from_factors(E.automorphisms()) + sage: nu + Composite morphism of degree 1 = 1^12: + From: Elliptic Curve defined by y^2 = x^3 + x + over Algebraic closure of Finite Field of size 3 + To: Elliptic Curve defined by y^2 = x^3 + x + over Algebraic closure of Finite Field of size 3 + sage: nu.is_injective() + True + + :: + + sage: E = EllipticCurve(GF(23), [1,0]) + sage: E.scalar_multiplication(4).is_injective() + False + sage: E.scalar_multiplication(5).is_injective() + False + sage: E.scalar_multiplication(1).is_injective() + True + sage: E.scalar_multiplication(-1).is_injective() + True + sage: E.scalar_multiplication(23).is_injective() + True + sage: E.scalar_multiplication(-23).is_injective() + True + sage: E.scalar_multiplication(0).is_injective() + False + + :: + + sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius + sage: E = EllipticCurve(GF(11), [1,1]) + sage: pi = EllipticCurveHom_frobenius(E, 5) + sage: pi.is_injective() + True """ - if not self.is_separable(): - # TODO: should implement .separable_degree() or similar - raise NotImplementedError - return self.degree() == 1 + if self.is_zero(): + return False + return self.inseparable_degree() == self.degree() def is_zero(self): r""" Check whether this elliptic-curve morphism is the zero map. - .. NOTE:: - - This function currently always returns ``True`` as Sage - does not yet implement the constant zero morphism. This - will probably change in the future. - EXAMPLES:: sage: E = EllipticCurve(j=GF(7)(0)) diff --git a/src/sage/schemes/elliptic_curves/hom_composite.py b/src/sage/schemes/elliptic_curves/hom_composite.py index e457c9854ee..ed87349bdcd 100644 --- a/src/sage/schemes/elliptic_curves/hom_composite.py +++ b/src/sage/schemes/elliptic_curves/hom_composite.py @@ -814,30 +814,6 @@ def dual(self): phis = (phi.dual() for phi in self._phis[::-1]) return EllipticCurveHom_composite.from_factors(phis) - def is_separable(self): - """ - Determine whether this composite isogeny is separable. - - A composition of isogenies is separable if and only if - all factors are. - - EXAMPLES:: - - sage: # needs sage.rings.finite_rings - sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(7^2), [3,2]) - sage: P = E.lift_x(1) - sage: phi = EllipticCurveHom_composite(E, P); phi - Composite morphism of degree 7 = 7: - From: Elliptic Curve defined by y^2 = x^3 + 3*x + 2 - over Finite Field in z2 of size 7^2 - To: Elliptic Curve defined by y^2 = x^3 + 3*x + 2 - over Finite Field in z2 of size 7^2 - sage: phi.is_separable() - True - """ - return all(phi.is_separable() for phi in self._phis) - def formal(self, prec=20): """ Return the formal isogeny corresponding to this composite @@ -899,29 +875,21 @@ def scaling_factor(self): """ return prod(phi.scaling_factor() for phi in self._phis) - def is_injective(self): - """ - Determine whether this composite morphism has trivial kernel. + def inseparable_degree(self): + r""" + Return the inseparable degree of this morphism. - In other words, return ``True`` if and only if ``self`` is a - purely inseparable isogeny. + Like the degree, the inseparable degree is multiplicative + under composition, so this method returns the product of + the inseparable degrees of the factors. EXAMPLES:: - sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve([1,0]) - sage: phi = EllipticCurveHom_composite(E, E(0,0)) - sage: phi.is_injective() - False - sage: E = EllipticCurve_from_j(GF(3).algebraic_closure()(0)) - sage: nu = EllipticCurveHom_composite.from_factors(E.automorphisms()) - sage: nu - Composite morphism of degree 1 = 1^12: - From: Elliptic Curve defined by y^2 = x^3 + x - over Algebraic closure of Finite Field of size 3 - To: Elliptic Curve defined by y^2 = x^3 + x - over Algebraic closure of Finite Field of size 3 - sage: nu.is_injective() - True + sage: E = EllipticCurve(j=GF(11^5).random_element()) + sage: phi = E.frobenius_isogeny(2) * E.scalar_multiplication(77) + sage: type(phi) + + sage: phi.inseparable_degree() + 1331 """ - return all(phi.is_injective() for phi in self._phis) + return prod(phi.inseparable_degree() for phi in self._phis) diff --git a/src/sage/schemes/elliptic_curves/hom_frobenius.py b/src/sage/schemes/elliptic_curves/hom_frobenius.py index fb4496aedbb..edd6180f0db 100644 --- a/src/sage/schemes/elliptic_curves/hom_frobenius.py +++ b/src/sage/schemes/elliptic_curves/hom_frobenius.py @@ -309,20 +309,6 @@ def _repr_(self): # EllipticCurveHom methods - def degree(self): - """ - Return the degree of this Frobenius isogeny. - - EXAMPLES:: - - sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius - sage: E = EllipticCurve(GF(11), [1,1]) - sage: pi = EllipticCurveHom_frobenius(E, 4) - sage: pi.degree() - 14641 - """ - return self._degree - def rational_maps(self): """ Return the explicit rational maps defining this Frobenius @@ -515,44 +501,21 @@ def dual(self): iso = find_post_isomorphism(Phi * self, scalar_mul) return iso * Phi - def is_separable(self): - """ - Determine whether or not this Frobenius isogeny is separable. - - Since Frobenius isogenies are purely inseparable, this method - returns ``True`` if and only if the degree is `1`. - - EXAMPLES:: - - sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius - sage: E = EllipticCurve(GF(11), [1,1]) - sage: pi = EllipticCurveHom_frobenius(E) - sage: pi.degree() - 11 - sage: pi.is_separable() - False - sage: pi = EllipticCurveHom_frobenius(E, 0) - sage: pi.degree() - 1 - sage: pi.is_separable() - True + def inseparable_degree(self): """ - return self._degree == 1 - - def is_injective(self): - """ - Determine whether or not this Frobenius isogeny has trivial - kernel. + Return the degree of this Frobenius isogeny. - Since Frobenius isogenies are purely inseparable, this method - always returns ``True``. + Since this class implements only purely inseparable isogenies, + the inseparable degree equals the degree. EXAMPLES:: sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius sage: E = EllipticCurve(GF(11), [1,1]) - sage: pi = EllipticCurveHom_frobenius(E, 5) - sage: pi.is_injective() + sage: pi = EllipticCurveHom_frobenius(E, 4) + sage: pi.inseparable_degree() + 14641 + sage: pi.inseparable_degree() == pi.degree() True """ - return True + return self._degree diff --git a/src/sage/schemes/elliptic_curves/hom_scalar.py b/src/sage/schemes/elliptic_curves/hom_scalar.py index 66e675250f9..03f042fd830 100644 --- a/src/sage/schemes/elliptic_curves/hom_scalar.py +++ b/src/sage/schemes/elliptic_curves/hom_scalar.py @@ -452,69 +452,38 @@ def dual(self): """ return self - def is_separable(self): - """ - Determine whether this scalar-multiplication map is a - separable isogeny. (This is the case if and only if the - scalar `m` is coprime to the characteristic.) + def inseparable_degree(self): + r""" + Return the inseparable degree of this scalar-multiplication map. EXAMPLES:: - sage: E = EllipticCurve(GF(11), [4,4]) - sage: E.scalar_multiplication(11).is_separable() - False - sage: E.scalar_multiplication(-11).is_separable() - False - sage: E.scalar_multiplication(777).is_separable() - True - sage: E.scalar_multiplication(-1).is_separable() - True - sage: E.scalar_multiplication(77).is_separable() + sage: E = EllipticCurve(GF(7), [0,1]) + sage: E.is_supersingular() False - sage: E.scalar_multiplication(121).is_separable() - False - - TESTS:: - - sage: E.scalar_multiplication(0).is_separable() - Traceback (most recent call last): - ... - ValueError: [0] is not an isogeny - """ - if self._m.is_zero(): - raise ValueError('[0] is not an isogeny') - return bool(self.scaling_factor()) + sage: E.scalar_multiplication(4).inseparable_degree() + 1 + sage: E.scalar_multiplication(-7).inseparable_degree() + 7 - def is_injective(self): - """ - Determine whether this scalar multiplication defines an - injective map (over the algebraic closure). - - Equivalently, return ``True`` if and only if this scalar - multiplication is a purely inseparable isogeny. - - EXAMPLES:: + :: - sage: E = EllipticCurve(GF(23), [1,0]) - sage: E.scalar_multiplication(4).is_injective() - False - sage: E.scalar_multiplication(5).is_injective() - False - sage: E.scalar_multiplication(1).is_injective() - True - sage: E.scalar_multiplication(-1).is_injective() - True - sage: E.scalar_multiplication(23).is_injective() + sage: E = EllipticCurve(GF(7), [1,0]) + sage: E.is_supersingular() True - sage: E.scalar_multiplication(-23).is_injective() - True - sage: E.scalar_multiplication(0).is_injective() - False + sage: E.scalar_multiplication(4).inseparable_degree() + 1 + sage: E.scalar_multiplication(-7).inseparable_degree() + 49 """ - if self._m.is_zero(): - return False - p = self._domain.base_ring().characteristic() - return self._m.abs().is_power_of(p) and self._domain.is_supersingular() + p = self.base_ring().characteristic() + if not p: + return ZZ.one() + v = self._m.valuation(p) + if not v: + return ZZ.one() + rk = 1 + self._domain.is_supersingular() + return p**(rk*v) def __neg__(self): """ diff --git a/src/sage/schemes/elliptic_curves/hom_sum.py b/src/sage/schemes/elliptic_curves/hom_sum.py index cfe6a7e85a6..703a8b71185 100644 --- a/src/sage/schemes/elliptic_curves/hom_sum.py +++ b/src/sage/schemes/elliptic_curves/hom_sum.py @@ -257,25 +257,17 @@ def to_isogeny_chain(self): raise ValueError('zero morphism cannot be written as a composition of isogenies') p = self.base_ring().characteristic() - insep = 0 + insep = self.inseparable_degree().valuation(p) if p else 0 + scalar = 1 #TODO Can we detect scalar factors earlier to save some extensions below? ker = [] for l,m in deg.factor(): if l == p: # possibly inseparable - try: - P = point_of_order(self.domain(), l**m) - except ValueError: - # supersingular; every p-isogeny is purely inseparable - insep = m - continue - Q = self._eval(P) - u = order_from_multiple(Q, l**m).valuation(l) - if u < m: - pt = l**u * P - pt.set_order(l**(m-u)) - ker.append(pt) - insep = u + if insep < m: + # kernel of the separable p-power part is unique + P = point_of_order(self.domain(), p**(m-insep)) + ker.append(P) continue # F = self.domain().division_field(l**m) #FIXME this can be used once #35936 is done; workaround below @@ -616,29 +608,59 @@ def dual(self): psi.dual.set_cache(self) return psi - def is_separable(self): + @cached_method + def inseparable_degree(self): r""" - Test whether this sum morphism is a separable isogeny. + Compute the inseparable degree of this sum morphism. EXAMPLES:: - sage: E = EllipticCurve(GF(5^2), [0,1]) - sage: m2 = E.scalar_multiplication(2) + sage: E = EllipticCurve(GF(7), [0,1]) sage: m3 = E.scalar_multiplication(3) - sage: m2.is_separable() - True - sage: E.frobenius() - -5 - sage: (m2 + m3).is_separable() - False - sage: (m2 - m2).is_separable() - Traceback (most recent call last): - ... - ValueError: zero morphism is not an isogeny + sage: m3.inseparable_degree() + 1 + sage: m4 = E.scalar_multiplication(4) + sage: m7 = m3 + m4; m7 + Sum morphism: + From: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 + To: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 + Via: (Scalar-multiplication endomorphism [3] of Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7, Scalar-multiplication endomorphism [4] of Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7) + sage: m7.degree() + 49 + sage: m7.inseparable_degree() + 7 + + A supersingular example:: + + sage: E = EllipticCurve(GF(7), [1,0]) + sage: m3 = E.scalar_multiplication(3) + sage: m3.inseparable_degree() + 1 + sage: m4 = E.scalar_multiplication(4) + sage: m7 = m3 + m4; m7 + Sum morphism: + From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7 + To: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7 + Via: (Scalar-multiplication endomorphism [3] of Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7, Scalar-multiplication endomorphism [4] of Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7) + sage: m7.inseparable_degree() + 49 """ - deg = self.degree() - if deg.is_zero(): + if self.is_zero(): raise ValueError('zero morphism is not an isogeny') - if not self.domain().base_field().characteristic().divides(deg): - return True - return self.to_isogeny_chain().is_separable() + + p = self.base_ring().characteristic() + if not p: + return ZZ.one() + + m = self.degree().valuation(p) + if not m: + return ZZ.one() + + try: + P = point_of_order(self.domain(), p**m) + except ValueError: + # supersingular; every p-isogeny is purely inseparable + return p**m + + Q = self._eval(P) + return order_from_multiple(Q, p**m) diff --git a/src/sage/schemes/elliptic_curves/hom_velusqrt.py b/src/sage/schemes/elliptic_curves/hom_velusqrt.py index 4bc84d944f8..fbe4887dbae 100644 --- a/src/sage/schemes/elliptic_curves/hom_velusqrt.py +++ b/src/sage/schemes/elliptic_curves/hom_velusqrt.py @@ -1173,21 +1173,21 @@ def scaling_factor(self): """ return self._pre_iso.scaling_factor() * self._post_iso.scaling_factor() - def is_separable(self): + def inseparable_degree(self): r""" - Determine whether or not this isogeny is separable. + Return the inseparable degree of this square-root Vélu + isogeny. Since :class:`EllipticCurveHom_velusqrt` only implements - separable isogenies, this method always returns ``True``. + separable isogenies, this method always returns one. - EXAMPLES:: + TESTS:: - sage: E = EllipticCurve(GF(17), [0,0,0,3,0]) - sage: phi = E.isogeny(E((1,2)), algorithm='velusqrt') - sage: phi.is_separable() - True + sage: from sage.schemes.elliptic_curves.hom_velusqrt import EllipticCurveHom_velusqrt + sage: EllipticCurveHom_velusqrt.inseparable_degree(None) + 1 """ - return True + return Integer(1) def _random_example_for_testing(): diff --git a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py index 57ff015a2b2..d6027e2d195 100644 --- a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py +++ b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py @@ -849,21 +849,6 @@ def kernel_polynomial(self): """ return self._poly_ring(1) - def is_separable(self): - r""" - Determine whether or not this isogeny is separable. - - Since :class:`WeierstrassIsomorphism` only implements - isomorphisms, this method always returns ``True``. - - EXAMPLES:: - - sage: E = EllipticCurve(GF(31337), [0,1]) # needs sage.rings.finite_rings - sage: {f.is_separable() for f in E.automorphisms()} # needs sage.rings.finite_rings - {True} - """ - return True - def dual(self): """ Return the dual isogeny of this isomorphism. @@ -956,6 +941,20 @@ def scaling_factor(self): """ return self.u + def inseparable_degree(self): + r""" + Return the inseparable degree of this Weierstrass isomorphism. + + For isomorphisms, this method always returns one. + + TESTS:: + + sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism + sage: WeierstrassIsomorphism.inseparable_degree(None) + 1 + """ + return Integer(1) + def identity_morphism(E): r""" From 7b4199f51b85bed8d1975d4a6897d0da6ac623ad Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 9 Nov 2023 16:36:23 +0100 Subject: [PATCH 187/463] streamline use of Cauchy-Schwarz bound for degree computation --- src/sage/schemes/elliptic_curves/hom_sum.py | 62 ++++++++++++--------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/hom_sum.py b/src/sage/schemes/elliptic_curves/hom_sum.py index 703a8b71185..15db537f6c8 100644 --- a/src/sage/schemes/elliptic_curves/hom_sum.py +++ b/src/sage/schemes/elliptic_curves/hom_sum.py @@ -45,8 +45,7 @@ from sage.misc.cachefunc import cached_method from sage.structure.sequence import Sequence -from sage.arith.misc import integer_floor, gcd -from sage.functions.other import sqrt +from sage.arith.misc import gcd from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring import polygen @@ -325,24 +324,24 @@ def to_isogeny_chain(self): # EllipticCurveHom methods - def _degree_bound(self): + def _degree_bounds(self): r""" - Return an upper bound on the degree of this sum morphism. - - ALGORITHM: Induction using the bound - `|\deg(f+g) - \deg(f) - \deg(g)| \leq 2\sqrt{\deg(f)\cdot\deg(g)}`; - see for instance Lemma V.1.2 of [Sil2009]_. + Return a lower and upper bound on the degree of this sum morphism. EXAMPLES:: - sage: E = EllipticCurve(GF(101), [5,5]) - sage: phi = E.isogenies_prime_degree(7)[0] - sage: (phi + phi)._degree_bound() - 28 - sage: (phi + phi).degree() - 28 - sage: (phi - phi)._degree_bound() - 28 + sage: E = EllipticCurve(GF(307), [5,5]) + sage: phi = E.isogenies_prime_degree(3)[0]; phi + Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 307 to Elliptic Curve defined by y^2 = x^3 + 227*x + 163 over Finite Field of size 307 + sage: psi = next(iso*psi for psi in E.isogenies_prime_degree(43) + ....: for iso in psi.codomain().isomorphisms(phi.codomain())); psi + Isogeny of degree 43 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 307 to Elliptic Curve defined by y^2 = x^3 + 227*x + 163 over Finite Field of size 307 + sage: (phi + psi)._degree_bounds() + (24, 68) + sage: (phi + psi).degree() + 61 + sage: (phi - phi)._degree_bounds() + (0, 12) sage: (phi - phi).degree() 0 @@ -351,15 +350,25 @@ def _degree_bound(self): sage: E = EllipticCurve(GF(443), [1,1]) sage: pi = E.frobenius_endomorphism() sage: m1 = E.scalar_multiplication(1) - sage: (pi - m1)._degree_bound() - 486 + sage: (pi - m1)._degree_bounds() + (402, 486) + sage: (pi - m1)._degree_bounds() == Hasse_bounds(443) + True sage: (pi - m1).degree() 433 + + ALGORITHM: Repeated application of the Cauchy-Schwarz inequality, + here in the form + `|\deg(f+g) - \deg(f) - \deg(g)| \leq 2\sqrt{\deg(f)\cdot\deg(g)}`. + See for instance Lemma V.1.2 of [Sil2009]_. """ - B = ZZ(0) + lo, hi = ZZ.zero(), ZZ.zero() for phi in self._phis: - B += phi.degree() + 2*sqrt(B * phi.degree()) - return integer_floor(B) + m = (hi * phi.degree()).isqrt() + hi += phi.degree() + 2*m + lo += phi.degree() - 2*m + lo = max(lo, 0) + return lo, hi def _compute_degree(self): r""" @@ -406,10 +415,11 @@ def _compute_degree(self): # compute the kernel polynomial using the addition formulas? from sage.rings.finite_rings.integer_mod import Mod - M = self._degree_bound() + 1 - deg = Mod(0,1) + lo, hi = self._degree_bounds() + M = hi - lo + 1 + rem = Mod(0,1) for l in Primes(): - if deg.modulus() >= M: + if rem.modulus() >= M: break try: P = point_of_order(self._domain, l) @@ -418,9 +428,9 @@ def _compute_degree(self): Q = self.dual()._eval(self._eval(P)) d = discrete_log(Q, P, ord=l, operation='+') - deg = deg.crt(Mod(d, l)) + rem = rem.crt(Mod(d-lo, l)) - self._degree = ZZ(deg) + self._degree = lo + rem.lift() self.dual()._degree = self._degree @staticmethod From a2e1aae2baf923a8329748f7fb9d219c59f59cfe Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 10 Nov 2023 09:51:51 +0100 Subject: [PATCH 188/463] some tiny docstring corrections --- src/sage/schemes/elliptic_curves/hom_frobenius.py | 2 +- src/sage/schemes/elliptic_curves/hom_sum.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/hom_frobenius.py b/src/sage/schemes/elliptic_curves/hom_frobenius.py index edd6180f0db..0c1254e15b0 100644 --- a/src/sage/schemes/elliptic_curves/hom_frobenius.py +++ b/src/sage/schemes/elliptic_curves/hom_frobenius.py @@ -503,7 +503,7 @@ def dual(self): def inseparable_degree(self): """ - Return the degree of this Frobenius isogeny. + Return the inseparable degree of this Frobenius isogeny. Since this class implements only purely inseparable isogenies, the inseparable degree equals the degree. diff --git a/src/sage/schemes/elliptic_curves/hom_sum.py b/src/sage/schemes/elliptic_curves/hom_sum.py index 15db537f6c8..6660035634d 100644 --- a/src/sage/schemes/elliptic_curves/hom_sum.py +++ b/src/sage/schemes/elliptic_curves/hom_sum.py @@ -202,8 +202,8 @@ def summands(self): def to_isogeny_chain(self): r""" Convert this formal sum of elliptic-curve morphisms into a - :class:`EllipticCurveHom_composite` object representing the - same morphism. + :class:`~sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite` + object representing the same morphism. EXAMPLES:: @@ -466,7 +466,7 @@ def degree(self): r""" Return the degree of this sum morphism. - EXAMPLES: + EXAMPLES:: sage: E = EllipticCurve(GF(101), [5,5]) sage: phi = E.isogenies_prime_degree(7)[0] From fbe441ef29fc8cab483337837dc24215a35f048d Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 10 Nov 2023 09:59:31 +0100 Subject: [PATCH 189/463] add .separable_degree() to complement .inseparable_degree() --- src/sage/schemes/elliptic_curves/hom.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 9133fe13691..fb7855993ea 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -699,6 +699,28 @@ def inseparable_degree(self): """ raise NotImplementedError('children must implement') + def separable_degree(self): + r""" + Return the separable degree of this isogeny. + + The separable degree is the result of dividing the :meth:`degree` + by the :meth:`inseparable_degree`. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(11), [5,5]) + sage: E.is_supersingular() + False + sage: E.scalar_multiplication(-77).separable_degree() + 539 + sage: E = EllipticCurve(GF(11), [5,0]) + sage: E.is_supersingular() + True + sage: E.scalar_multiplication(-77).separable_degree() + 49 + """ + return self.degree() // self.inseparable_degree() + def is_separable(self): r""" Determine whether or not this morphism is a separable isogeny. @@ -887,7 +909,7 @@ def is_injective(self): """ if self.is_zero(): return False - return self.inseparable_degree() == self.degree() + return self.separable_degree().is_one() def is_zero(self): r""" From 560bf2a2017b7049eb51aa3216d563d8da1cf66a Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 10 Nov 2023 15:22:58 +0100 Subject: [PATCH 190/463] n-division polynomial has repeated roots when p|n --- src/sage/schemes/elliptic_curves/ell_field.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 0d27c622b7a..ed052e42f0b 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1049,7 +1049,7 @@ def division_field(self, n, names='t', map=False, **kwds): verbose("Adjoining X-coordinates of %s-torsion points" % n) F = self.base_ring() - f = self.division_polynomial(n) + f = self.division_polynomial(n).radical() if n == 2 or f.is_constant(): # For n = 2, the division field is the splitting field of From dfd4aa53824b9651c2139ed4387b85734d57b137 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 10 Nov 2023 15:29:19 +0100 Subject: [PATCH 191/463] "fix" doctest for 32-bit machines --- src/sage/schemes/elliptic_curves/ell_field.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index ed052e42f0b..eeb37db72ed 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -977,7 +977,7 @@ def division_field(self, n, names='t', map=False, **kwds): sage: K. = NumberField(x^2 + 1) sage: E = EllipticCurve([0,0,0,0,i]) sage: L,emb = E.division_field(6, names='b', map=True); L - Number Field in b with defining polynomial x^24 + 12*x^23 + 66*x^22 - 504*x^21 + 92415*x^20 + 1372020*x^19 + 9791248*x^18 + 9161712*x^17 + 2248687014*x^16 + 39282444252*x^15 + 319379172870*x^14 + 1647604458936*x^13 + 6124888492503*x^12 + 17596271352348*x^11 + 40654930682496*x^10 + 76552797892176*x^9 + 116296878586974*x^8 + 139157022368196*x^7 + 127681305928690*x^6 + 87539428627680*x^5 + 43598049444279*x^4 + 15182945758692*x^3 + 3479289119772*x^2 + 468890060424*x + 28234163953 + Number Field in b with defining polynomial x^24 + 12*x^23 + ... sage: E.change_ring(emb).torsion_subgroup().invariants() (6, 6) From 0c801304bf2435a606250c2ddd0a7b73557c7c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Thu, 26 Oct 2023 10:51:08 -0300 Subject: [PATCH 192/463] Fix bug in QF.find_primitive_p_divisible_vector__next When the vector [0,...,0,1] is a zero mod p, it was missed from the iteration. Fix by check and return it if this is the case. A doctest triggering the bug is included. --- src/sage/quadratic_forms/quadratic_form__neighbors.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sage/quadratic_forms/quadratic_form__neighbors.py b/src/sage/quadratic_forms/quadratic_form__neighbors.py index fb781e20122..9b9b62a0689 100644 --- a/src/sage/quadratic_forms/quadratic_form__neighbors.py +++ b/src/sage/quadratic_forms/quadratic_form__neighbors.py @@ -74,6 +74,10 @@ def find_primitive_p_divisible_vector__next(self, p, v=None): sage: v = Q.find_primitive_p_divisible_vector__next(5, v); v (1, 0) sage: v = Q.find_primitive_p_divisible_vector__next(5, v); v + sage: v = Q.find_primitive_p_divisible_vector__next(2) ; v + (0, 1) + sage: v = Q.find_primitive_p_divisible_vector__next(2, v) ; v + (1, 0) sage: Q = QuadraticForm(QQ, matrix.diagonal([1,1,1,1])) sage: v = Q.find_primitive_p_divisible_vector__next(2) sage: Q(v) @@ -83,6 +87,9 @@ def find_primitive_p_divisible_vector__next(self, p, v=None): n = self.dim() if v is None: w = vector(ZZ, [0] * (n - 1) + [1]) + a = self(w) + if a in ZZ and (a % p == 0): + return w else: w = deepcopy(v) From e773be6a959511fff1e1ebb78b5e34e82f6bdee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Thu, 26 Oct 2023 10:57:26 -0300 Subject: [PATCH 193/463] Add return_matrix option for QF.find_p_neighbor_from_vec Similar to QF.is_globally_equivalent_to, etc. --- .../quadratic_form__neighbors.py | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/sage/quadratic_forms/quadratic_form__neighbors.py b/src/sage/quadratic_forms/quadratic_form__neighbors.py index 9b9b62a0689..ec853cd52ef 100644 --- a/src/sage/quadratic_forms/quadratic_form__neighbors.py +++ b/src/sage/quadratic_forms/quadratic_form__neighbors.py @@ -139,7 +139,7 @@ def find_primitive_p_divisible_vector__next(self, p, v=None): return w -def find_p_neighbor_from_vec(self, p, y): +def find_p_neighbor_from_vec(self, p, y, return_matrix=False): r""" Return the `p`-neighbor of ``self`` defined by ``y``. @@ -154,25 +154,32 @@ def find_p_neighbor_from_vec(self, p, y): - ``p`` -- a prime number - ``y`` -- a vector with `q(y) \in p \ZZ` - ``odd`` -- (default: ``False``) if `p=2`, return also odd neighbors + - ``return_matrix`` -- (boolean, default ``False``) return + the transformation matrix instead of the quadratic form EXAMPLES:: + sage: # needs sage.libs.pari sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) sage: v = vector([0,2,1,1]) - sage: X = Q.find_p_neighbor_from_vec(3, v); X # needs sage.libs.pari + sage: X = Q.find_p_neighbor_from_vec(3, v); X Quadratic form in 4 variables over Integer Ring with coefficients: [ 1 0 0 0 ] [ * 1 4 4 ] [ * * 5 12 ] [ * * * 9 ] + sage: B = Q.find_p_neighbor_from_vec(3, v, return_matrix=True) + sage: Q(B) == X + True Since the base ring and the domain are not yet separate, for rational, half integral forms we just pretend the base ring is `\ZZ`:: + sage: # needs sage.libs.pari sage: Q = QuadraticForm(QQ, matrix.diagonal([1,1,1,1])) sage: v = vector([1,1,1,1]) - sage: Q.find_p_neighbor_from_vec(2, v) # needs sage.libs.pari + sage: Q.find_p_neighbor_from_vec(2, v) Quadratic form in 4 variables over Rational Field with coefficients: [ 1/2 1 1 1 ] [ * 1 1 2 ] @@ -234,9 +241,12 @@ def find_p_neighbor_from_vec(self, p, y): # by definition this is the p-neighbor of L at y # assert B.det().abs() == 1 - QF = self.parent() - Gnew = (B*G*B.T).change_ring(R) - return QF(Gnew) + if return_matrix: + return B.T + else: + QF = self.parent() + Gnew = (B*G*B.T).change_ring(R) + return QF(Gnew) def neighbor_iteration(seeds, p, mass=None, max_classes=ZZ(10)**3, From 522edd143dd44697818fe156a2be1f24f545ca88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Wed, 8 Nov 2023 18:36:33 -0300 Subject: [PATCH 194/463] Fix bug in QF.ternary.extend() This breaks TernaryQF.find_p_neighbor_from_vec(). --- src/sage/quadratic_forms/ternary.pyx | 19 +++++++++++++++++++ src/sage/quadratic_forms/ternary_qf.py | 7 +++++++ 2 files changed, 26 insertions(+) diff --git a/src/sage/quadratic_forms/ternary.pyx b/src/sage/quadratic_forms/ternary.pyx index 28dd9514c30..6e7c4389083 100644 --- a/src/sage/quadratic_forms/ternary.pyx +++ b/src/sage/quadratic_forms/ternary.pyx @@ -955,7 +955,26 @@ def extend(v): [ 30 0 -7] sage: M.det() 2 + + TESTS:: + + sage: M = matrix(3, extend( (0, 0, 1) )) + sage: M.det() + 1 + sage: M.column(0) + (0, 0, 1) + sage: M = matrix(3, extend( (0, 0, -2) )) + sage: M.det() + 2 + sage: M.column(0) + (0, 0, -2) """ + if v[0] == v[1] == 0: + if v[2] < 0: + return v[0], 0, 1, v[1], 1, 0, v[2], 0, 0 + else: + return v[0], 1, 0, v[1], 0, 1, v[2], 0, 0 + b1 = xgcd(v[0], v[1]) b2 = xgcd(b1[1], b1[2]) b3 = xgcd(b1[0], v[2]) diff --git a/src/sage/quadratic_forms/ternary_qf.py b/src/sage/quadratic_forms/ternary_qf.py index fa4499566a9..2f3a57fa713 100644 --- a/src/sage/quadratic_forms/ternary_qf.py +++ b/src/sage/quadratic_forms/ternary_qf.py @@ -918,6 +918,13 @@ def find_p_neighbor_from_vec(self, p, v, mat=False): [ 0 -3/11 13/11] sage: Q(M) == Q11 True + + Test that it works with (0, 0, 1):: + + sage: Q.find_p_neighbor_from_vec(3, (0,0,1)) + Ternary quadratic form with integer coefficients: + [1 3 3] + [-2 0 -1] """ if mat: q, M = _find_p_neighbor_from_vec(self._a, self._b, self._c, self._r, self._s, self._t, p, v, mat) From 23f671571c3a4b9a3cd838085c4eaa37bbcc20de Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sun, 12 Nov 2023 17:25:41 +0100 Subject: [PATCH 195/463] Updated SageMath version to 10.2.rc2 --- 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_bliss/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_coxeter3/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_mcqd/install-requires.txt | 2 +- build/pkgs/sagemath_meataxe/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- build/pkgs/sagemath_sirocco/install-requires.txt | 2 +- build/pkgs/sagemath_tdlib/install-requires.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 38 files changed, 45 insertions(+), 45 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index b1b171fb1a1..7294ca6763a 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.2.rc1 +version: 10.2.rc2 doi: 10.5281/zenodo.593563 -date-released: 2023-11-10 +date-released: 2023-11-12 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 8ceae8bb576..bf28f5b89de 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.2.rc1, Release Date: 2023-11-10 +SageMath version 10.2.rc2, Release Date: 2023-11-12 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index d8c83c023b0..ed5acb9cc09 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=e0eb47055f79c8898be61aa53b45d7c243b9f22c -md5=05af6b3eb911bb709dff596cf1e05546 -cksum=796740784 +sha1=6564d23ce7b0af645ecf5ec5461f82942ca9561e +md5=425ddadf2e8f5808916be6567802033d +cksum=2694227517 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 8f8f1069ddc..9789b687e7f 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -0e598caa6f70248990092065e8948fba56d0867f +883e05f8ee0f97b25cf28c97859c615d9ea314f7 diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 326aa7578ec..72d982128c2 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.2rc1 +sage-conf ~= 10.2rc2 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index de534e08518..b3ec06fd6bd 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.2rc1 +sage-docbuild ~= 10.2rc2 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index 3c0a80511a3..32b2a0f11c4 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.2rc1 +sage-setup ~= 10.2rc2 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index 4a13b95c8f6..cb0ef8de582 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.2rc1 +sage-sws2rst ~= 10.2rc2 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 9dd84a6d4d7..f7ce9fc4363 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 -sagemath-standard ~= 10.2rc1 +sagemath-standard ~= 10.2rc2 diff --git a/build/pkgs/sagemath_bliss/install-requires.txt b/build/pkgs/sagemath_bliss/install-requires.txt index c66665c1f4d..45ef2f3037c 100644 --- a/build/pkgs/sagemath_bliss/install-requires.txt +++ b/build/pkgs/sagemath_bliss/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.2rc1 +sagemath-bliss ~= 10.2rc2 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index a1695d082b4..ead89ac718b 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.2rc1 +sagemath-categories ~= 10.2rc2 diff --git a/build/pkgs/sagemath_coxeter3/install-requires.txt b/build/pkgs/sagemath_coxeter3/install-requires.txt index b9db4ef19c8..1fcaeb1578e 100644 --- a/build/pkgs/sagemath_coxeter3/install-requires.txt +++ b/build/pkgs/sagemath_coxeter3/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.2rc1 +sagemath-coxeter3 ~= 10.2rc2 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index f704a57eb7e..c7125057ba4 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.2rc1 +sagemath-environment ~= 10.2rc2 diff --git a/build/pkgs/sagemath_mcqd/install-requires.txt b/build/pkgs/sagemath_mcqd/install-requires.txt index 947642f6baf..30adf8786bb 100644 --- a/build/pkgs/sagemath_mcqd/install-requires.txt +++ b/build/pkgs/sagemath_mcqd/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.2rc1 +sagemath-mcqd ~= 10.2rc2 diff --git a/build/pkgs/sagemath_meataxe/install-requires.txt b/build/pkgs/sagemath_meataxe/install-requires.txt index b05223e6735..e2ea89298af 100644 --- a/build/pkgs/sagemath_meataxe/install-requires.txt +++ b/build/pkgs/sagemath_meataxe/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.2rc1 +sagemath-meataxe ~= 10.2rc2 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index 8245904bf01..7f040ebe9a2 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.2rc1 +sagemath-objects ~= 10.2rc2 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 83c797f99a3..27ebea3e770 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.2rc1 +sagemath-repl ~= 10.2rc2 diff --git a/build/pkgs/sagemath_sirocco/install-requires.txt b/build/pkgs/sagemath_sirocco/install-requires.txt index f828bbac488..4fb6d1a07b5 100644 --- a/build/pkgs/sagemath_sirocco/install-requires.txt +++ b/build/pkgs/sagemath_sirocco/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.2rc1 +sagemath-sirocco ~= 10.2rc2 diff --git a/build/pkgs/sagemath_tdlib/install-requires.txt b/build/pkgs/sagemath_tdlib/install-requires.txt index cd0d3390b93..b00874fb242 100644 --- a/build/pkgs/sagemath_tdlib/install-requires.txt +++ b/build/pkgs/sagemath_tdlib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.2rc1 +sagemath-tdlib ~= 10.2rc2 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/src/VERSION.txt b/src/VERSION.txt index a9591a7f98d..9a33c5df14e 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.2.rc1 +10.2.rc2 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 6ba84d36e70..8bcbb63baec 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.2.rc1' -SAGE_RELEASE_DATE='2023-11-10' -SAGE_VERSION_BANNER='SageMath version 10.2.rc1, Release Date: 2023-11-10' +SAGE_VERSION='10.2.rc2' +SAGE_RELEASE_DATE='2023-11-12' +SAGE_VERSION_BANNER='SageMath version 10.2.rc2, Release Date: 2023-11-12' diff --git a/src/sage/version.py b/src/sage/version.py index 087d777c94b..4dc5fe09e63 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.2.rc1' -date = '2023-11-10' -banner = 'SageMath version 10.2.rc1, Release Date: 2023-11-10' +version = '10.2.rc2' +date = '2023-11-12' +banner = 'SageMath version 10.2.rc2, Release Date: 2023-11-12' From 5a24b4818a26c3b9114a9c78a39cfe442df33804 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 22 Oct 2023 14:23:54 +0000 Subject: [PATCH 196/463] tree_decomposition.pyx: Format and style improvements --- .../tree_decomposition.pyx | 78 +++++++++---------- 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 90f14298c5a..83d2cccee1e 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -104,13 +104,15 @@ Methods from sage.sets.set import Set from sage.misc.cachefunc import cached_function -from itertools import chain from sage.features import PythonModule from sage.sets.disjoint_set import DisjointSet from sage.rings.infinity import Infinity from sage.graphs.distances_all_pairs cimport c_distances_all_pairs from cysignals.memory cimport sig_calloc, sig_free +from itertools import chain +from collections.abc import Iterable + def is_valid_tree_decomposition(G, T): r""" @@ -206,9 +208,7 @@ def is_valid_tree_decomposition(G, T): raise ValueError("the second parameter must be a tree") for X in T: - try: - _ = list(X) - except TypeError: + if not isinstance(X, Iterable): raise ValueError("the vertices of T must be iterables") # 1. The union of the bags equals V @@ -438,7 +438,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): INPUT: - - ``g`` -- a sage Graph + - ``g`` -- a Sage Graph - ``k`` -- integer (default: ``None``); indicates the width to be considered. When ``k`` is an integer, the method checks that the graph has @@ -466,12 +466,12 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): ALGORITHM: - This function virtually explores the graph of all pairs ``(vertex_cut,cc)``, + This function virtually explores the graph of all pairs ``(vertex_cut, cc)``, where ``vertex_cut`` is a vertex cut of the graph of cardinality `\leq k+1`, and ``connected_component`` is a connected component of the graph induced by ``G-vertex_cut``. - We deduce that the pair ``(vertex_cut,cc)`` is feasible with tree-width `k` + We deduce that the pair ``(vertex_cut, cc)`` is feasible with tree-width `k` if ``cc`` is empty, or if a vertex ``v`` from ``vertex_cut`` can be replaced with a vertex from ``cc``, such that the pair ``(vertex_cut+v,cc-v)`` is feasible. @@ -498,14 +498,14 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): sage: graphs.PetersenGraph().treewidth(certificate=True) Tree decomposition: Graph on 6 vertices - The treewidth of a 2d grid is its smallest side:: + The treewidth of a 2-dimensional grid is its smallest side:: sage: graphs.Grid2dGraph(2,5).treewidth() 2 sage: graphs.Grid2dGraph(3,5).treewidth() 3 - When parameter ``kmin`` is specified, the method search for a + When parameter ``kmin`` is specified, the method searches for a tree-decomposition of width at least ``kmin``:: sage: g = graphs.PetersenGraph() @@ -598,7 +598,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): sage: graphs.PetersenGraph().treewidth(k=35) True - sage: graphs.PetersenGraph().treewidth(k=35,certificate=True) + sage: graphs.PetersenGraph().treewidth(k=35, certificate=True) Tree decomposition: Graph on 1 vertex Bad input:: @@ -609,34 +609,27 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): ValueError: k(=-3) must be a nonnegative integer """ # Check Input - if algorithm is None or algorithm == 'tdlib': - try: - import sage.graphs.graph_decompositions.tdlib as tdlib - tdlib_found = True - except ImportError: - tdlib_found = False - - elif algorithm != "sage": + if algorithm not in [None, 'tdlib', 'sage']: raise ValueError("'algorithm' must be equal to 'tdlib', 'sage', or None") + try: + import sage.graphs.graph_decompositions.tdlib as tdlib + tdlib_found = True + except ImportError: + tdlib_found = False + if algorithm is None: - if tdlib_found: - algorithm = 'tdlib' - else: - algorithm = 'sage' + algorithm = 'tdlib' if tdlib_found else 'sage' - if k is not None and k < 0: - raise ValueError("k(={}) must be a nonnegative integer".format(k)) + if (k is not None) and k < 0: + raise ValueError(f"k(={k}) must be a nonnegative integer") # Stupid cases from sage.graphs.graph import Graph if not g.order(): if certificate: return Graph() - elif k is None: - return -1 - else: - return True + return -1 if k is None else True if k is not None and k >= g.order() - 1: if certificate: @@ -661,10 +654,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): if certificate: return T if (k is None or width <= k) else False - elif k is None: - return width - else: - return width <= k + return width if k is None else width <= k # The treewidth of a graph is the maximum over its atoms. So, we decompose # the graph by clique minimal separators, compute the treewidth of each of @@ -672,6 +662,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): # This decomposition also deals with disconnected cases. atoms, cliques = g.atoms_and_clique_separators() if cliques: + # If we do not need the tree decomposition if not certificate: if k is None: for a in atoms: @@ -681,16 +672,17 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): return False else: return all(g.subgraph(a).treewidth(algorithm=algorithm, k=k) for a in atoms) - else: - # We compute the tree decomposition of each atom - T = [] - for a in atoms: - ga = g.subgraph(a) - Ta = ga.treewidth(algorithm=algorithm, certificate=True, kmin=kmin) - kmin = max(kmin, width_of_tree_decomposition(ga, Ta, check=False)) - T.append(Ta) - # and merge the resulting trees - return _from_tree_decompositions_of_atoms_to_tree_decomposition(T, cliques) + + # Otherwise, compute the tree decomposition of each atom + T = [] + for a in atoms: + ga = g.subgraph(a) + Ta = ga.treewidth(algorithm=algorithm, certificate=True, kmin=kmin) + kmin = max(kmin, width_of_tree_decomposition(ga, Ta, check=False)) + T.append(Ta) + + # Merge the resulting trees + return _from_tree_decompositions_of_atoms_to_tree_decomposition(T, cliques) # Forcing k to be defined if k is None: @@ -768,7 +760,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): G.add_edges(((Set(x), Set(y)) for x, y in TD), loops=False) # The Tree-Decomposition may contain a lot of useless nodes. - # We merge all edges between two sets S,S' where S is a subset of S' + # We merge all edges between two sets S, S' where S is a subset of S' G = reduced_tree_decomposition(G) G.name("Tree decomposition") From 6694eb5e0001cba6ee2c62dd12a186679236fc7e Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 26 Oct 2023 13:56:47 +0000 Subject: [PATCH 197/463] tree_decomposition.pyx: Prelim version of `make_nice_tree_decomposition` --- .../tree_decomposition.pyx | 166 +++++++++++++++++- 1 file changed, 163 insertions(+), 3 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 83d2cccee1e..78e071450d9 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -82,9 +82,7 @@ The treewidth of a clique is `n-1` and its treelength is 1:: .. TODO: - - Add method to return a *nice* tree decomposition - - Approximation of treelength based on - :meth:`~sage.graphs.graph.Graph.lex_M` + - Approximation of treelength based on :meth:`~sage.graphs.graph.Graph.lex_M` - Approximation of treelength based on BFS Layering - upgrade tdlib to 0.9.0 :trac:`30813` @@ -766,6 +764,168 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): G.name("Tree decomposition") return G +def make_nice_tree_decomposition(T): + r""" + Return a *nice* tree-decomposition of the tree-decomposition `T`. + + https://kam.mff.cuni.cz/~ashutosh/lectures/lec06.pdf + + A *nice* tree-decomposition is a rooted binary tree with four types of + nodes: + - Leaf nodes have no children and bag size 1; + - Introduce nodes have one child. The child has the same vertices as the + parent with one deleted; + - Forget nodes have one child. The child has the same vertices as the parent + with one added. + - Join nodes have two children, both identical to the parent. + + .. WARNING:: + + This method assumes that the vertices of the input tree `T` are hashable + and have attribute ``issuperset``, e.g., ``frozenset`` or + :class:`~sage.sets.set.Set_object_enumerated_with_category`. + + INPUT: + + - ``T`` -- a tree-decomposition + """ + from sage.graphs.graph import Graph + if not isinstance(T, Graph): + raise ValueError("T must be a tree-decomposition") + + name = "Nice tree-decomposition of {}".format(T.name()) + if not T: + return Graph(name=name) + + # P1: The tree is rooted. + # We choose a root and orient the edges in root to leaves direction. + leaves = [u for u in T if T.degree(u) == 1] + root = leaves.pop() + from sage.graphs.digraph import DiGraph + DT = DiGraph(T.breadth_first_search(start=root, edges=True), + format='list_of_edges') + + # We relabel the graph in range 0..|T|-1 + bag_to_int = DT.relabel(inplace=True, return_map=True) + # get the new name of the root + root = bag_to_int[root] + # and force bags to be of type Set to simplify the code + bag = {ui: Set(u) for u, ui in bag_to_int.items()} + + # P2: The root and the leaves have empty bags. + # To do so, we add to each leaf node l of DT a children with empty bag. + # We also add a new root with empty bag. + root, old_root = DT.add_vertex(), root + DT.add_edge(root, old_root) + bag[root] = Set() + for vi, u in enumerate(leaves, start=root + 1): + DT.add_edge(bag_to_int[u], vi) + bag[vi] = Set() + + # P3: Ensure that each vertex of DT has at most 2 children. + # If b has k > 2 children (c1, c2, ..., c_k). We disconnect (c1, ... ck-1) + # from b, introduce k - 2 new vertices (b1, b2, .., bk-2), make ci the + # children of bi for 1 <= i <= k-2, make ck-1 the second children of bk-2, + # make bi the second children of b_i-1, and finally make b1 the second + # children of b. Each vertex bi has the same bag has b. + for ui in list(DT): # the list(..) is needed since we modify DT + if DT.out_degree(ui) > 2: + children = DT.neighbors_out(ui) + children.pop() # one vertex remains a child of ui + DT.delete_edges((ui, vi) for v in children) + new_vertices = [DT.add_vertex() for _ in range(len(children) - 1)] + DT.add_edge(ui, new_vertices[0]) + DT.add_path(new_vertices) + DT.add_edges(zip(new_vertices, children)) + DT.add_edge(new_vertices[-1], children[-1]) + bag.update((vi, bag[ui]) for vi in new_vertices) + + # P4: If b has 2 children c1 and c2, then bag[b] == bag[c1] == bag[c2] + for ui in list(DT): + if DT.out_degree(ui) < 2: + continue + for vi in DT.neighbor_out_iterator(ui): + if bag[ui] != bag[vi]: + DT.delete_edge(ui, vi) + wi = DT.add_vertex() + DT.add_path([ui, wi, vi]) + bag[wi] = bag[ui] + + # P5: if b has a single child c, then one of the following conditions holds: + # (i) bag[c] is a subset of bag[b] and |bag[b]| == |bag[c]| + 1 + # (ii) bag[b] is a subset of bag[c] and |bag[c]| == |bag[b]| + 1 + + def add_path_of_introduce(ui, vi): + """ + Replace arc (ui, vi) by a path of introduce vertices. + """ + if len(bag[ui]) + 1 == len(bag[vi]): + return + diff = list(bag[vi] - bag[ui]) + diff.pop() # when all vertices are added, we are on vi + xi = ui + for w in diff: + wi = DT.add_vertex() + bag[wi] = bag[xi].union(Set((w,))) + DT.add_edge(xi, wi) + xi = wi + DT.add_edge(xi, vi) + DT.delete_edge(ui, vi) + + def add_path_of_forget(ui, vi): + """ + Replace arc (ui, vi) by a path of forget vertices. + """ + if len(bag[vi]) + 1 == len(bag[ui]): + return + diff = list(bag[ui] - bag[vi]) + diff.pop() # when all vertices are removed, we are on vi + xi = ui + for w in diff: + wi = DT.add_vertex() + bag[wi] = bag[xi] - Set((w,)) + DT.add_edge(xi, wi) + xi = wi + DT.add_edge(xi, vi) + DT.delete_edge(ui, vi) + + for ui in list(DT): + if DT.out_degree(ui) != 1: + continue + + vi = next(DT.neighbor_out_iterator(ui)) + bag_ui, bag_vi = bag[ui], bag[vi] + + if bag_ui == bag_vi: + # We can merge the vertices + if DT.in_degree(ui) == 1: + parent = next(DT.neighbor_in_iterator(ui)) + DT.add_edge(parent, vi) + else: + root = vi + DT.delete_vertex(ui) + + elif bag_ui.issubset(bag_vi): + add_path_of_introduce(ui, vi) + + elif bag_vi.issubset(bag_ui): + add_path_of_forget(ui, vi) + + else: + # We must first forget some nodes and then introduce new nodes + wi = DT.add_vertex() + bag[wi] = bag[ui] & bag[vi] + DT.add_path([ui, wi, vi]) + DT.delete_edge(ui, vi) + add_path_of_forget(ui, wi) + add_path_of_introduce(wi, vi) + + # We now return the result + nice = Graph(DT, name=name) + nice.relabel(inplace=True, + perm={u: (i, bag[u]) for i, u in enumerate(nice.breadth_first_search(start=root))}) + return nice + # # Treelength From a1cbbdb016fbcd7b9021dad785e3996986dca161 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 26 Oct 2023 14:41:20 +0000 Subject: [PATCH 198/463] tree_decomposition.pyx: Format and simplify docstring and code before Step 3 (P3 in current code) --- .../tree_decomposition.pyx | 150 ++++++++++-------- 1 file changed, 81 insertions(+), 69 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 78e071450d9..3b0723ef6f6 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -766,18 +766,26 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): def make_nice_tree_decomposition(T): r""" - Return a *nice* tree-decomposition of the tree-decomposition `T`. + Return a *nice* tree decomposition (TD) of the TD `T`. - https://kam.mff.cuni.cz/~ashutosh/lectures/lec06.pdf + A *nice* TD `NT` is a rooted tree with four types of nodes: - A *nice* tree-decomposition is a rooted binary tree with four types of - nodes: - - Leaf nodes have no children and bag size 1; - - Introduce nodes have one child. The child has the same vertices as the - parent with one deleted; - - Forget nodes have one child. The child has the same vertices as the parent - with one added. - - Join nodes have two children, both identical to the parent. + - *Leaf* nodes have no children and bag size 1; + - *Introduce* nodes have one child: If `v \in NT` is an introduce node and + `w \in NT` its child, then `Bag(v) = Bag(w) \cup { x }`, where `x` is the + introduced node; + - *Forget* nodes have one child: If `v \in NT` is a forget node and + `w \in NT` its child, then `Bag(v) = Bag(w) \setminus { x }`, where `x` is the + forgotten node; + - *Join* nodes have two children, both identical to the parent. + + INPUT:: + + - ``T`` -- a tree decomposition + + OUTPUT:: + + A nice tree decomposition. .. WARNING:: @@ -785,70 +793,74 @@ def make_nice_tree_decomposition(T): and have attribute ``issuperset``, e.g., ``frozenset`` or :class:`~sage.sets.set.Set_object_enumerated_with_category`. - INPUT: + TESTS:: - - ``T`` -- a tree-decomposition + TODO + + EXAMPLES:: + + TODO """ from sage.graphs.graph import Graph if not isinstance(T, Graph): - raise ValueError("T must be a tree-decomposition") + raise ValueError("Input must be a valid tree decomposition") - name = "Nice tree-decomposition of {}".format(T.name()) + name = f"Nice tree decomposition of {T.name()}" if not T: return Graph(name=name) - # P1: The tree is rooted. - # We choose a root and orient the edges in root to leaves direction. + # Step 1: Ensure the tree is directed and has a root + # Choose a root and orient the edges from root-to-leaves direction leaves = [u for u in T if T.degree(u) == 1] root = leaves.pop() from sage.graphs.digraph import DiGraph - DT = DiGraph(T.breadth_first_search(start=root, edges=True), - format='list_of_edges') - - # We relabel the graph in range 0..|T|-1 - bag_to_int = DT.relabel(inplace=True, return_map=True) - # get the new name of the root - root = bag_to_int[root] - # and force bags to be of type Set to simplify the code - bag = {ui: Set(u) for u, ui in bag_to_int.items()} - - # P2: The root and the leaves have empty bags. - # To do so, we add to each leaf node l of DT a children with empty bag. + directed_tree = DiGraph(T.breadth_first_search(start=root, edges=True), + format='list_of_edges') + + # Relabel the graph in range (0, |T| - 1) + bags_to_int = directed_tree.relabel(inplace=True, return_map=True) + # Get the new name of the root node + root = bags_to_int[root] + # Force bags to be of type Set to simplify code + bag = {ui: Set(u) for u, ui in bags_to_int.items()} + + # Step 2: Add the root node and the leaf nodes, with empty bags + # To each leaf node of `directed_tree`, we add a child with empty bag. # We also add a new root with empty bag. - root, old_root = DT.add_vertex(), root - DT.add_edge(root, old_root) + root, old_root = directed_tree.add_vertex(), root + directed_tree.add_edge(root, old_root) bag[root] = Set() for vi, u in enumerate(leaves, start=root + 1): - DT.add_edge(bag_to_int[u], vi) + directed_tree.add_edge(bags_to_int[u], vi) bag[vi] = Set() - # P3: Ensure that each vertex of DT has at most 2 children. + # P3: Ensure that each vertex of directed_tree has at most 2 children. # If b has k > 2 children (c1, c2, ..., c_k). We disconnect (c1, ... ck-1) # from b, introduce k - 2 new vertices (b1, b2, .., bk-2), make ci the # children of bi for 1 <= i <= k-2, make ck-1 the second children of bk-2, # make bi the second children of b_i-1, and finally make b1 the second # children of b. Each vertex bi has the same bag has b. - for ui in list(DT): # the list(..) is needed since we modify DT - if DT.out_degree(ui) > 2: - children = DT.neighbors_out(ui) + for ui in list(directed_tree): # the list(..) is needed since we modify directed_tree + if directed_tree.out_degree(ui) > 2: + children = directed_tree.neighbors_out(ui) children.pop() # one vertex remains a child of ui - DT.delete_edges((ui, vi) for v in children) - new_vertices = [DT.add_vertex() for _ in range(len(children) - 1)] - DT.add_edge(ui, new_vertices[0]) - DT.add_path(new_vertices) - DT.add_edges(zip(new_vertices, children)) - DT.add_edge(new_vertices[-1], children[-1]) + directed_tree.delete_edges((ui, vi) for v in children) + new_vertices = [directed_tree.add_vertex() for _ in range(len(children) - 1)] + directed_tree.add_edge(ui, new_vertices[0]) + directed_tree.add_path(new_vertices) + directed_tree.add_edges(zip(new_vertices, children)) + directed_tree.add_edge(new_vertices[-1], children[-1]) bag.update((vi, bag[ui]) for vi in new_vertices) # P4: If b has 2 children c1 and c2, then bag[b] == bag[c1] == bag[c2] - for ui in list(DT): - if DT.out_degree(ui) < 2: + for ui in list(directed_tree): + if directed_tree.out_degree(ui) < 2: continue - for vi in DT.neighbor_out_iterator(ui): + for vi in directed_tree.neighbor_out_iterator(ui): if bag[ui] != bag[vi]: - DT.delete_edge(ui, vi) - wi = DT.add_vertex() - DT.add_path([ui, wi, vi]) + directed_tree.delete_edge(ui, vi) + wi = directed_tree.add_vertex() + directed_tree.add_path([ui, wi, vi]) bag[wi] = bag[ui] # P5: if b has a single child c, then one of the following conditions holds: @@ -865,12 +877,12 @@ def make_nice_tree_decomposition(T): diff.pop() # when all vertices are added, we are on vi xi = ui for w in diff: - wi = DT.add_vertex() + wi = directed_tree.add_vertex() bag[wi] = bag[xi].union(Set((w,))) - DT.add_edge(xi, wi) + directed_tree.add_edge(xi, wi) xi = wi - DT.add_edge(xi, vi) - DT.delete_edge(ui, vi) + directed_tree.add_edge(xi, vi) + directed_tree.delete_edge(ui, vi) def add_path_of_forget(ui, vi): """ @@ -882,28 +894,28 @@ def make_nice_tree_decomposition(T): diff.pop() # when all vertices are removed, we are on vi xi = ui for w in diff: - wi = DT.add_vertex() + wi = directed_tree.add_vertex() bag[wi] = bag[xi] - Set((w,)) - DT.add_edge(xi, wi) + directed_tree.add_edge(xi, wi) xi = wi - DT.add_edge(xi, vi) - DT.delete_edge(ui, vi) + directed_tree.add_edge(xi, vi) + directed_tree.delete_edge(ui, vi) - for ui in list(DT): - if DT.out_degree(ui) != 1: + for ui in list(directed_tree): + if directed_tree.out_degree(ui) != 1: continue - vi = next(DT.neighbor_out_iterator(ui)) + vi = next(directed_tree.neighbor_out_iterator(ui)) bag_ui, bag_vi = bag[ui], bag[vi] if bag_ui == bag_vi: # We can merge the vertices - if DT.in_degree(ui) == 1: - parent = next(DT.neighbor_in_iterator(ui)) - DT.add_edge(parent, vi) + if directed_tree.in_degree(ui) == 1: + parent = next(directed_tree.neighbor_in_iterator(ui)) + directed_tree.add_edge(parent, vi) else: root = vi - DT.delete_vertex(ui) + directed_tree.delete_vertex(ui) elif bag_ui.issubset(bag_vi): add_path_of_introduce(ui, vi) @@ -913,18 +925,18 @@ def make_nice_tree_decomposition(T): else: # We must first forget some nodes and then introduce new nodes - wi = DT.add_vertex() + wi = directed_tree.add_vertex() bag[wi] = bag[ui] & bag[vi] - DT.add_path([ui, wi, vi]) - DT.delete_edge(ui, vi) + directed_tree.add_path([ui, wi, vi]) + directed_tree.delete_edge(ui, vi) add_path_of_forget(ui, wi) add_path_of_introduce(wi, vi) # We now return the result - nice = Graph(DT, name=name) - nice.relabel(inplace=True, - perm={u: (i, bag[u]) for i, u in enumerate(nice.breadth_first_search(start=root))}) - return nice + nice_tree_decomp = Graph(directed_tree, name=name) + nice_tree_decomp.relabel(inplace=True, + perm={u: (i, bag[u]) for i, u in enumerate(nice_tree_decomp.breadth_first_search(start=root))}) + return nice_tree_decomp # From eb966c4f738b0a51a04e54c3ceb34d857453ece5 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 26 Oct 2023 19:29:58 +0000 Subject: [PATCH 199/463] tree_decomposition: Format and simplify docstring and code --- .../tree_decomposition.pyx | 145 ++++++++++-------- 1 file changed, 83 insertions(+), 62 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 3b0723ef6f6..0677baf4b4c 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -834,72 +834,88 @@ def make_nice_tree_decomposition(T): directed_tree.add_edge(bags_to_int[u], vi) bag[vi] = Set() - # P3: Ensure that each vertex of directed_tree has at most 2 children. - # If b has k > 2 children (c1, c2, ..., c_k). We disconnect (c1, ... ck-1) - # from b, introduce k - 2 new vertices (b1, b2, .., bk-2), make ci the - # children of bi for 1 <= i <= k-2, make ck-1 the second children of bk-2, - # make bi the second children of b_i-1, and finally make b1 the second - # children of b. Each vertex bi has the same bag has b. - for ui in list(directed_tree): # the list(..) is needed since we modify directed_tree + # Step 3: Ensure that each node of directed_tree has at most 2 children. + # If a node has more than 2 children, introduce new nodes to + # make sure each node has at most 2 children: + # + # If v has k > 2 children (w_1, w_2, ..., w_k), we disconnect (w_1, ..., w_{k-1}) + # from v, and introduce k - 2 new nodes (u_1, u_2, ..., u_{k-2}). + # We then let w_i be the children of u_i for 1 <= i <= k - 2. + # We also let w_{k-1} be the second child of u_{k-2}, and + # u_i the second child of u_{i-1}. + # Finally, we let u_1 the second child of u. + # Each node u_i has the same bag as u. + + # We need to call list(...) since we modify directed_tree + for ui in list(directed_tree): if directed_tree.out_degree(ui) > 2: children = directed_tree.neighbors_out(ui) - children.pop() # one vertex remains a child of ui + children.pop() # one vertex remains a child of ui + directed_tree.delete_edges((ui, vi) for v in children) - new_vertices = [directed_tree.add_vertex() for _ in range(len(children) - 1)] - directed_tree.add_edge(ui, new_vertices[0]) - directed_tree.add_path(new_vertices) - directed_tree.add_edges(zip(new_vertices, children)) - directed_tree.add_edge(new_vertices[-1], children[-1]) - bag.update((vi, bag[ui]) for vi in new_vertices) - - # P4: If b has 2 children c1 and c2, then bag[b] == bag[c1] == bag[c2] - for ui in list(directed_tree): - if directed_tree.out_degree(ui) < 2: + + new_nodes = [directed_tree.add_vertex() for _ in range(len(children) - 1)] + + directed_tree.add_edge(ui, new_nodes[0]) + directed_tree.add_path(new_nodes) + directed_tree.add_edges(zip(new_nodes, children)) + directed_tree.add_edge(new_nodes[-1], children[-1]) + + bag.update((vi, bag[ui]) for vi in new_nodes) + + # Step 4: If current vertex v has two children w1 and w2, + # then bag[v] == bag[w1] == bag[w2] + for current_node in list(directed_tree): + if directed_tree.out_degree(current_node) < 2: continue - for vi in directed_tree.neighbor_out_iterator(ui): - if bag[ui] != bag[vi]: - directed_tree.delete_edge(ui, vi) - wi = directed_tree.add_vertex() - directed_tree.add_path([ui, wi, vi]) - bag[wi] = bag[ui] - - # P5: if b has a single child c, then one of the following conditions holds: - # (i) bag[c] is a subset of bag[b] and |bag[b]| == |bag[c]| + 1 - # (ii) bag[b] is a subset of bag[c] and |bag[c]| == |bag[b]| + 1 - - def add_path_of_introduce(ui, vi): + for neighbor in directed_tree.neighbor_out_iterator(current_node): + if bag[current_node] != bag[neighbor]: + directed_tree.delete_edge(current_node, neighbor) + new_node = directed_tree.add_vertex() + directed_tree.add_path([current_node, new_node, neighbor]) + bag[new_node] = bag[current_node] + + # Step 5: If the node v has only one child, then it is either an introduce + # node or a forget node. + def add_path_of_intro_nodes(u, v): """ - Replace arc (ui, vi) by a path of introduce vertices. + Replace the arc (u, v) by a path of introduce nodes. """ - if len(bag[ui]) + 1 == len(bag[vi]): + if len(bag[u]) + 1 == len(bag[v]): return - diff = list(bag[vi] - bag[ui]) - diff.pop() # when all vertices are added, we are on vi - xi = ui + + diff = list(bag[v] - bag[u]) + diff.pop() + + last_node = u for w in diff: - wi = directed_tree.add_vertex() - bag[wi] = bag[xi].union(Set((w,))) - directed_tree.add_edge(xi, wi) - xi = wi - directed_tree.add_edge(xi, vi) - directed_tree.delete_edge(ui, vi) + new_node = directed_tree.add_vertex() + bag[new_node] = bag[last_node].union({w}) + directed_tree.add_edge(last_node, new_node) + last_node = new_node + + directed_tree.add_edge(last_node, v) + directed_tree.delete_edge(u, v) - def add_path_of_forget(ui, vi): + def add_path_of_forget_nodes(u, v): """ - Replace arc (ui, vi) by a path of forget vertices. + Replace the arc (u, v) by a path of forget nodes. """ - if len(bag[vi]) + 1 == len(bag[ui]): + if len(bag[v]) + 1 == len(bag[u]): return - diff = list(bag[ui] - bag[vi]) - diff.pop() # when all vertices are removed, we are on vi - xi = ui + + diff = list(bag[u] - bag[v]) + diff.pop() + + last_node = u for w in diff: - wi = directed_tree.add_vertex() - bag[wi] = bag[xi] - Set((w,)) - directed_tree.add_edge(xi, wi) - xi = wi - directed_tree.add_edge(xi, vi) - directed_tree.delete_edge(ui, vi) + new_node = directed_tree.add_vertex() + bag[new_node] = bag[last_node] - {w} + directed_tree.add_edge(last_node, new_node) + last_node = new_node + + directed_tree.add_edge(last_node, v) + directed_tree.delete_edge(u, v) for ui in list(directed_tree): if directed_tree.out_degree(ui) != 1: @@ -908,8 +924,8 @@ def make_nice_tree_decomposition(T): vi = next(directed_tree.neighbor_out_iterator(ui)) bag_ui, bag_vi = bag[ui], bag[vi] + # Merge the nodes if the two bags are the same if bag_ui == bag_vi: - # We can merge the vertices if directed_tree.in_degree(ui) == 1: parent = next(directed_tree.neighbor_in_iterator(ui)) directed_tree.add_edge(parent, vi) @@ -917,25 +933,30 @@ def make_nice_tree_decomposition(T): root = vi directed_tree.delete_vertex(ui) + # Add paths of intro / forget nodes accordingly + elif bag_ui.issubset(bag_vi): - add_path_of_introduce(ui, vi) + add_path_of_intro_nodes(ui, vi) elif bag_vi.issubset(bag_ui): - add_path_of_forget(ui, vi) + add_path_of_forget_nodes(ui, vi) + # Handle the case when the two nodes are not related in any way above else: - # We must first forget some nodes and then introduce new nodes wi = directed_tree.add_vertex() bag[wi] = bag[ui] & bag[vi] directed_tree.add_path([ui, wi, vi]) directed_tree.delete_edge(ui, vi) - add_path_of_forget(ui, wi) - add_path_of_introduce(wi, vi) + add_path_of_forget_nodes(ui, wi) + add_path_of_intro_nodes(wi, vi) - # We now return the result + # Return the nice tree decomposition after the processing nice_tree_decomp = Graph(directed_tree, name=name) - nice_tree_decomp.relabel(inplace=True, - perm={u: (i, bag[u]) for i, u in enumerate(nice_tree_decomp.breadth_first_search(start=root))}) + + bfs_ordering = nice_tree_decomp.breadth_first_search(start=root) + relabeling = {u: (i, bag[u]) for i, u in enumerate(bfs_ordering)} + nice_tree_decomp.relabel(inplace=True, perm=relabeling) + return nice_tree_decomp From c5630a15826c427b041ceeea93472344b025a990 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 26 Oct 2023 19:48:32 +0000 Subject: [PATCH 200/463] index.rst: Add "Parameterized Algorithms" --- src/doc/en/reference/references/index.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 697c50a6bcf..ca31f33ecd8 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -1474,6 +1474,11 @@ REFERENCES: .. [CFI1992] Cai, JY., Fürer, M. & Immerman, N. Combinatorica (1992) 12: 389. :doi:`10.1007/BF01305232` +.. [CFKLMPPS15] Marek Cygan, Fedor V. Fomin, Łukasz Kowalik, Daniel Lokshtanov, + Dániel Marx, Marcin Pilipczuk, Michał Pilipczuk, Saket Saurabh. + *Parameterized Algorithms*. Springer International Publishing + Switzerland 2015 + .. [CFKP1997] James W. Cannon, William J. Floyd, Richard Kenyon and Walter R. Parry. *Hyperbolic Geometry*. Flavors of Geometry, MSRI Publications, Volume 31, 1997. From 2e90cf1034d8c932ad23b306434af532def2fd50 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 26 Oct 2023 19:49:13 +0000 Subject: [PATCH 201/463] tree_decomposition.pyx: Make changes par code view on GitHub PR #36504 --- .../tree_decomposition.pyx | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 0677baf4b4c..74f6588240b 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -764,9 +764,11 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): G.name("Tree decomposition") return G -def make_nice_tree_decomposition(T): +def make_nice_tree_decomposition(graph, tree_decomp): r""" - Return a *nice* tree decomposition (TD) of the TD `T`. + Return a *nice* tree decomposition (TD) of the TD `tree_decomp`. + + See page 161 of [CFKLMPPS15]_ for a description of the nice tree decomposition. A *nice* TD `NT` is a rooted tree with four types of nodes: @@ -781,7 +783,8 @@ def make_nice_tree_decomposition(T): INPUT:: - - ``T`` -- a tree decomposition + - ``graph`` -- a Sage graph + - ``tree_decomp`` -- a tree decomposition OUTPUT:: @@ -789,8 +792,8 @@ def make_nice_tree_decomposition(T): .. WARNING:: - This method assumes that the vertices of the input tree `T` are hashable - and have attribute ``issuperset``, e.g., ``frozenset`` or + This method assumes that the vertices of the input tree `tree_decomp` + are hashable and have attribute ``issuperset``, e.g., ``frozenset`` or :class:`~sage.sets.set.Set_object_enumerated_with_category`. TESTS:: @@ -801,23 +804,23 @@ def make_nice_tree_decomposition(T): TODO """ - from sage.graphs.graph import Graph - if not isinstance(T, Graph): - raise ValueError("Input must be a valid tree decomposition") + if not is_valid_tree_decomposition(graph, tree_decomp): + raise ValueError("input must be a valid tree decomposition for this graph") - name = f"Nice tree decomposition of {T.name()}" - if not T: + name = f"Nice tree decomposition of {tree_decomp.name()}" + if not tree_decomp: + from sage.graphs.graph import Graph return Graph(name=name) # Step 1: Ensure the tree is directed and has a root # Choose a root and orient the edges from root-to-leaves direction - leaves = [u for u in T if T.degree(u) == 1] + leaves = [u for u in tree_decomp if tree_decomp.degree(u) == 1] root = leaves.pop() from sage.graphs.digraph import DiGraph - directed_tree = DiGraph(T.breadth_first_search(start=root, edges=True), + directed_tree = DiGraph(tree_decomp.breadth_first_search(start=root, edges=True), format='list_of_edges') - # Relabel the graph in range (0, |T| - 1) + # Relabel the graph in range (0, |tree_decomp| - 1) bags_to_int = directed_tree.relabel(inplace=True, return_map=True) # Get the new name of the root node root = bags_to_int[root] From 1deb54506915b7d5cfee781fcbc44347fcc4805f Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 26 Oct 2023 20:12:41 +0000 Subject: [PATCH 202/463] tree_decomposition.pyx: Add to table of methods; New test --- .../graph_decompositions/tree_decomposition.pyx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 74f6588240b..3bbe03ba1e5 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -75,6 +75,7 @@ The treewidth of a clique is `n-1` and its treelength is 1:: :meth:`treewidth` | Compute the treewidth of `G` (and provide a decomposition). :meth:`treelength` | Compute the treelength of `G` (and provide a decomposition). + :meth:`make_nice_tree_decomposition` | Return a *nice* tree decomposition (TD) of the TD `tree_decomp`. :meth:`is_valid_tree_decomposition` | Check whether `T` is a valid tree-decomposition for `G`. :meth:`reduced_tree_decomposition` | Return a reduced tree-decomposition of `T`. :meth:`width_of_tree_decomposition` | Return the width of the tree decomposition `T` of `G`. @@ -796,20 +797,21 @@ def make_nice_tree_decomposition(graph, tree_decomp): are hashable and have attribute ``issuperset``, e.g., ``frozenset`` or :class:`~sage.sets.set.Set_object_enumerated_with_category`. - TESTS:: - - TODO - EXAMPLES:: - TODO + sage: from sage.graphs.graph_decompositions.tree_decomposition import make_nice_tree_decomposition + sage: petersen = graphs.PetersenGraph() + sage: TD = petersen.treewidth(certificate=True) + sage: nice_TD = make_nice_tree_decomposition(petersen, TD) + sage: len(nice_TD) + 28 """ if not is_valid_tree_decomposition(graph, tree_decomp): raise ValueError("input must be a valid tree decomposition for this graph") name = f"Nice tree decomposition of {tree_decomp.name()}" + from sage.graphs.graph import Graph if not tree_decomp: - from sage.graphs.graph import Graph return Graph(name=name) # Step 1: Ensure the tree is directed and has a root From fd7d2efca3e04c30f7b496203f99672bde62681c Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Fri, 27 Oct 2023 11:49:34 +0000 Subject: [PATCH 203/463] tree_decomposition.pyx: Add two more examples --- .../tree_decomposition.pyx | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 3bbe03ba1e5..481e1c19015 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -801,10 +801,25 @@ def make_nice_tree_decomposition(graph, tree_decomp): sage: from sage.graphs.graph_decompositions.tree_decomposition import make_nice_tree_decomposition sage: petersen = graphs.PetersenGraph() - sage: TD = petersen.treewidth(certificate=True) - sage: nice_TD = make_nice_tree_decomposition(petersen, TD) - sage: len(nice_TD) - 28 + sage: petersen_TD = petersen.treewidth(certificate=True) + sage: make_nice_tree_decomposition(petersen, petersen_TD) + Nice tree decomposition of Tree decomposition: Graph on 28 vertices + + :: + + sage: from sage.graphs.graph_decompositions.tree_decomposition import make_nice_tree_decomposition + sage: cherry = graphs.CompleteBipartiteGraph(1, 2) + sage: cherry_TD = cherry.treewidth(certificate=True) + sage: make_nice_tree_decomposition(cherry, cherry_TD) + Nice tree decomposition of Tree decomposition: Graph on 7 vertices + + :: + + sage: from sage.graphs.graph_decompositions.tree_decomposition import make_nice_tree_decomposition + sage: bip_one_four = graphs.CompleteBipartiteGraph(1, 4) + sage: bip_one_four_TD = bip_one_four.treewidth(certificate=True) + sage: make_nice_tree_decomposition(bip_one_four, bip_one_four_TD) + Nice tree decomposition of Tree decomposition: Graph on 15 vertices """ if not is_valid_tree_decomposition(graph, tree_decomp): raise ValueError("input must be a valid tree decomposition for this graph") @@ -895,7 +910,7 @@ def make_nice_tree_decomposition(graph, tree_decomp): last_node = u for w in diff: new_node = directed_tree.add_vertex() - bag[new_node] = bag[last_node].union({w}) + bag[new_node] = bag[last_node].union(Set((w,))) directed_tree.add_edge(last_node, new_node) last_node = new_node From 1de3a224b576164533274e96522404565341644a Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 29 Oct 2023 18:07:50 +0000 Subject: [PATCH 204/463] tree_decomposition.pyx: For backup purpose. Add `nice` arg to `treewidth` function. Fix docstring. --- .../tree_decomposition.pyx | 67 ++++++++++++------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 481e1c19015..3310f300cc6 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -431,7 +431,7 @@ def _from_tree_decompositions_of_atoms_to_tree_decomposition(T_atoms, cliques): return T -def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): +def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=False): r""" Compute the treewidth of `g` (and provide a decomposition). @@ -442,7 +442,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): - ``k`` -- integer (default: ``None``); indicates the width to be considered. When ``k`` is an integer, the method checks that the graph has treewidth `\leq k`. If ``k`` is ``None`` (default), the method computes - the optimal tree-width. + the optimal treewidth. - ``kmin`` -- integer (default: ``None``); when specified, search for a tree-decomposition of width at least ``kmin``. This parameter is useful @@ -456,12 +456,19 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): installation of the 'tdlib' package). The default behaviour is to use 'tdlib' if it is available, and Sage's own algorithm when it is not. + - ``nice`` -- boolean (default: ``False``); whether or not to return the + nice tree decomposition, provided ``certificate`` is ``True``. + OUTPUT: - ``g.treewidth()`` returns the treewidth of ``g``. When ``k`` is specified, - it returns ``False`` when no tree-decomposition of width `\leq k` exists or - ``True`` otherwise. When ``certificate=True``, the tree-decomposition is - also returned. + ``g.treewidth()`` returns treewidth of the graph ``g``. + + When ``k`` is specified, it returns ``False`` if there is no tree + decomposition of width `\leq k`, and ``True`` otherwise. + + When ``certificate=True``, the tree decomposition is returned. + + When ``nice=True``, the nice tree decomposition is returned. ALGORITHM: @@ -470,7 +477,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): and ``connected_component`` is a connected component of the graph induced by ``G-vertex_cut``. - We deduce that the pair ``(vertex_cut, cc)`` is feasible with tree-width `k` + We deduce that the pair ``(vertex_cut, cc)`` is feasible with treewidth `k` if ``cc`` is empty, or if a vertex ``v`` from ``vertex_cut`` can be replaced with a vertex from ``cc``, such that the pair ``(vertex_cut+v,cc-v)`` is feasible. @@ -497,6 +504,11 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): sage: graphs.PetersenGraph().treewidth(certificate=True) Tree decomposition: Graph on 6 vertices + Nice tree decomposition of the PetersenGraph has 28 nodes: + + sage: graphs.PetersenGraph().treewidth(certificate=True, nice=True) + Nice tree decomposition: Graph on 28 vertices + The treewidth of a 2-dimensional grid is its smallest side:: sage: graphs.Grid2dGraph(2,5).treewidth() @@ -544,7 +556,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): True sage: g.treewidth(k=3, certificate=True) False - sage: T = g.treewidth(k=4,certificate=True) + sage: T = g.treewidth(k=4, certificate=True) sage: T Tree decomposition: Graph on 6 vertices sage: from sage.graphs.graph_decompositions.tree_decomposition import is_valid_tree_decomposition @@ -623,7 +635,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): if (k is not None) and k < 0: raise ValueError(f"k(={k}) must be a nonnegative integer") - # Stupid cases + # Silly cases from sage.graphs.graph import Graph if not g.order(): if certificate: @@ -648,11 +660,13 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): raise FeatureNotPresentError(PythonModule('sage.graphs.graph_decompositions.tdlib', spkg='tdlib')) - T = tdlib.treedecomposition_exact(g, -1 if k is None else k) - width = tdlib.get_width(T) + tree_decomp = tdlib.treedecomposition_exact(g, -1 if k is None else k) + width = tdlib.get_width(tree_decomp) if certificate: - return T if (k is None or width <= k) else False + if k is None or width <= k: + return make_nice_tree_decomposition(g, tree_decomp) if nice else tree_decomp + return False return width if k is None else width <= k # The treewidth of a graph is the maximum over its atoms. So, we decompose @@ -752,22 +766,27 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None): if not certificate: return True - # Building the Tree-Decomposition graph. Its vertices are cuts of the + # Building the tree-decomposition graph. Its vertices are cuts of the # decomposition, and there is an edge from a cut C1 to a cut C2 if C2 is an # immediate subcall of C1 - G = Graph() - G.add_edges(((Set(x), Set(y)) for x, y in TD), loops=False) + tree_decomp = Graph() + tree_decomp.add_edges(((Set(x), Set(y)) for x, y in TD), loops=False) - # The Tree-Decomposition may contain a lot of useless nodes. + # The tree-decomposition may contain a lot of useless nodes. # We merge all edges between two sets S, S' where S is a subset of S' - G = reduced_tree_decomposition(G) + tree_decomp = reduced_tree_decomposition(tree_decomp) + + tree_decomp.name("Tree decomposition") + if nice: + print(nice) + tree_decomp = make_nice_tree_decomposition(g, tree_decomp) - G.name("Tree decomposition") - return G + print(nice) + return tree_decomp def make_nice_tree_decomposition(graph, tree_decomp): r""" - Return a *nice* tree decomposition (TD) of the TD `tree_decomp`. + Return a *nice* tree decomposition (TD) of the TD ``tree_decomp``. See page 161 of [CFKLMPPS15]_ for a description of the nice tree decomposition. @@ -775,10 +794,10 @@ def make_nice_tree_decomposition(graph, tree_decomp): - *Leaf* nodes have no children and bag size 1; - *Introduce* nodes have one child: If `v \in NT` is an introduce node and - `w \in NT` its child, then `Bag(v) = Bag(w) \cup { x }`, where `x` is the + `w \in NT` its child, then `Bag(v) = Bag(w) \cup \{ x \}`, where `x` is the introduced node; - *Forget* nodes have one child: If `v \in NT` is a forget node and - `w \in NT` its child, then `Bag(v) = Bag(w) \setminus { x }`, where `x` is the + `w \in NT` its child, then `Bag(v) = Bag(w) \setminus \{ x \}`, where `x` is the forgotten node; - *Join* nodes have two children, both identical to the parent. @@ -1370,7 +1389,7 @@ cdef class TreelengthConnected: if not self.certificate: return True - # Building the Tree-Decomposition graph. Its vertices are cuts of the + # Building the tree-decomposition graph. Its vertices are cuts of the # decomposition, and there is an edge from a cut C1 to a cut C2 if C2 is an # immediate subcall of C1. If needed, the vertices are relabeled. if self.perm_inv: @@ -1716,7 +1735,7 @@ def treelength(G, k=None, certificate=False): # decompositions of its atoms. T = _from_tree_decompositions_of_atoms_to_tree_decomposition(result, cliques) - # The Tree-Decomposition may contain a lot of useless nodes. + # The tree-decomposition may contain a lot of useless nodes. # We merge all edges between two sets S,S' where S is a subset of S' T = reduced_tree_decomposition(T) T.name(name) From 26ac402373d3e378fb05f468dbef8358ac46987c Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 29 Oct 2023 21:20:35 +0000 Subject: [PATCH 205/463] tree_decomposition.pyx: Handler the case when using atoms and cliques --- src/sage/graphs/graph_decompositions/tree_decomposition.pyx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 3310f300cc6..8ce5c433c9f 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -695,7 +695,9 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=Fals T.append(Ta) # Merge the resulting trees - return _from_tree_decompositions_of_atoms_to_tree_decomposition(T, cliques) + tree_decomp = _from_tree_decompositions_of_atoms_to_tree_decomposition(T, cliques) + + return make_nice_tree_decomposition(g, tree_decomp) if nice else tree_decomp # Forcing k to be defined if k is None: From 2e780feb1f95fcd45f01cd864162f413fc541801 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Tue, 31 Oct 2023 18:50:56 +0000 Subject: [PATCH 206/463] tree_decomposition.pyx: Resolved "nice" argument issue --- src/sage/graphs/graph_decompositions/tree_decomposition.pyx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 8ce5c433c9f..74c5f1a68f4 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -507,7 +507,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=Fals Nice tree decomposition of the PetersenGraph has 28 nodes: sage: graphs.PetersenGraph().treewidth(certificate=True, nice=True) - Nice tree decomposition: Graph on 28 vertices + Nice tree decomposition of Tree decomposition: Graph on 28 vertices The treewidth of a 2-dimensional grid is its smallest side:: @@ -702,7 +702,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=Fals # Forcing k to be defined if k is None: for i in range(max(kmin, g.clique_number() - 1, min(g.degree())), g.order()): - ans = g.treewidth(algorithm=algorithm, k=i, certificate=certificate) + ans = g.treewidth(algorithm=algorithm, k=i, certificate=certificate, nice=nice) if ans: return ans if certificate else i @@ -780,10 +780,8 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=Fals tree_decomp.name("Tree decomposition") if nice: - print(nice) tree_decomp = make_nice_tree_decomposition(g, tree_decomp) - print(nice) return tree_decomp def make_nice_tree_decomposition(graph, tree_decomp): From 85fa8d8270db0797e3edbdfc88db57c321ed9c48 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Tue, 31 Oct 2023 19:45:59 +0000 Subject: [PATCH 207/463] tree_decompositions.pyx: Changes according to linter and codestyle --- .../graphs/graph_decompositions/tree_decomposition.pyx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 74c5f1a68f4..af008bbaef3 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -465,7 +465,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=Fals When ``k`` is specified, it returns ``False`` if there is no tree decomposition of width `\leq k`, and ``True`` otherwise. - + When ``certificate=True``, the tree decomposition is returned. When ``nice=True``, the nice tree decomposition is returned. @@ -801,12 +801,12 @@ def make_nice_tree_decomposition(graph, tree_decomp): forgotten node; - *Join* nodes have two children, both identical to the parent. - INPUT:: + INPUT: - ``graph`` -- a Sage graph - ``tree_decomp`` -- a tree decomposition - OUTPUT:: + OUTPUT: A nice tree decomposition. @@ -874,7 +874,7 @@ def make_nice_tree_decomposition(graph, tree_decomp): bag[vi] = Set() # Step 3: Ensure that each node of directed_tree has at most 2 children. - # If a node has more than 2 children, introduce new nodes to + # If a node has more than 2 children, introduce new nodes to # make sure each node has at most 2 children: # # If v has k > 2 children (w_1, w_2, ..., w_k), we disconnect (w_1, ..., w_{k-1}) @@ -959,7 +959,7 @@ def make_nice_tree_decomposition(graph, tree_decomp): for ui in list(directed_tree): if directed_tree.out_degree(ui) != 1: continue - + vi = next(directed_tree.neighbor_out_iterator(ui)) bag_ui, bag_vi = bag[ui], bag[vi] From 620cd4fcd620a92acd5655b3a747bf63bc4ca321 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 2 Nov 2023 13:52:21 +0000 Subject: [PATCH 208/463] tree_decomposition.pyx: Additional tests for `tdlib`, if installed --- .../tree_decomposition.pyx | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index af008bbaef3..bf4bc72128e 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -499,14 +499,26 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=Fals The PetersenGraph has treewidth 4:: - sage: graphs.PetersenGraph().treewidth() + sage: petersen = graphs.PetersenGraph() + sage: petersen.treewidth(algorithm='sage') + 4 + sage: petersen.treewidth(algorithm='sage', certificate=True) + Tree decomposition: Graph on 6 vertices + + The PetersenGraph has treewidth 4 (with `tdlib`):: + + sage: petersen = graphs.PetersenGraph() + sage: petersen.treewidth(algorithm='tdlib') 4 - sage: graphs.PetersenGraph().treewidth(certificate=True) + sage: petersen.treewidth(algorithm='tdlib', certificate=True) Tree decomposition: Graph on 6 vertices - Nice tree decomposition of the PetersenGraph has 28 nodes: + Nice tree decomposition of the PetersenGraph has 28 nodes:: - sage: graphs.PetersenGraph().treewidth(certificate=True, nice=True) + sage: petersen = graphs.PetersenGraph() + sage: petersen.treewidth(algorithm='sage', certificate=True, nice=True) + Nice tree decomposition of Tree decomposition: Graph on 28 vertices + sage: petersen.treewidth(algorithm='tdlib', certificate=True, nice=True) Nice tree decomposition of Tree decomposition: Graph on 28 vertices The treewidth of a 2-dimensional grid is its smallest side:: From 0d2135adce240a20a6bc8ca6306e1f253ae7348c Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 2 Nov 2023 17:25:56 +0000 Subject: [PATCH 209/463] tree_decomposition.pyx: Make `tdlib` tests optional --- .../graph_decompositions/tree_decomposition.pyx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index bf4bc72128e..75e08b80b6b 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -505,21 +505,21 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=Fals sage: petersen.treewidth(algorithm='sage', certificate=True) Tree decomposition: Graph on 6 vertices - The PetersenGraph has treewidth 4 (with `tdlib`):: + The PetersenGraph has treewidth 4 (with ``tdlib``):: - sage: petersen = graphs.PetersenGraph() - sage: petersen.treewidth(algorithm='tdlib') - 4 - sage: petersen.treewidth(algorithm='tdlib', certificate=True) - Tree decomposition: Graph on 6 vertices + sage: petersen = graphs.PetersenGraph() # optional tdlib + sage: petersen.treewidth(algorithm='tdlib') # optional tdlib + 4 # optional tdlib + sage: petersen.treewidth(algorithm='tdlib', certificate=True) # optional tdlib + Tree decomposition: Graph on 6 vertices # optional tdlib Nice tree decomposition of the PetersenGraph has 28 nodes:: sage: petersen = graphs.PetersenGraph() sage: petersen.treewidth(algorithm='sage', certificate=True, nice=True) Nice tree decomposition of Tree decomposition: Graph on 28 vertices - sage: petersen.treewidth(algorithm='tdlib', certificate=True, nice=True) - Nice tree decomposition of Tree decomposition: Graph on 28 vertices + sage: petersen.treewidth(algorithm='tdlib', certificate=True, nice=True) # optional tdlib + Nice tree decomposition of Tree decomposition: Graph on 28 vertices # optional tdlib The treewidth of a 2-dimensional grid is its smallest side:: From 728763131d25f979d6d9b850fd94485ac175c6a5 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Fri, 3 Nov 2023 22:10:49 +0000 Subject: [PATCH 210/463] tree_decomposition.pyx: New function `label_nice_tree_decomposition` --- .../tree_decomposition.pyx | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 75e08b80b6b..d2ad99a9f54 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -76,6 +76,7 @@ The treewidth of a clique is `n-1` and its treelength is 1:: :meth:`treewidth` | Compute the treewidth of `G` (and provide a decomposition). :meth:`treelength` | Compute the treelength of `G` (and provide a decomposition). :meth:`make_nice_tree_decomposition` | Return a *nice* tree decomposition (TD) of the TD `tree_decomp`. + :meth:`label_nice_tree_decomposition` | Return a nice tree decomposition with nodes labelled accordingly. :meth:`is_valid_tree_decomposition` | Check whether `T` is a valid tree-decomposition for `G`. :meth:`reduced_tree_decomposition` | Return a reduced tree-decomposition of `T`. :meth:`width_of_tree_decomposition` | Return the width of the tree decomposition `T` of `G`. @@ -1010,6 +1011,46 @@ def make_nice_tree_decomposition(graph, tree_decomp): return nice_tree_decomp +def label_nice_tree_decomposition(nice_TD): + r""" + Return a nice tree decomposition with nodes labelled accordingly. + + INPUT: + + - ``nice_TD`` -- a nice tree decomposition + + OUTPUT: + + A nice tree decomposition with nodes labelled. + """ + directed_TD = DiGraph(nice_TD.breadth_first_search(start=root, + edges=True), + format='list_of_edges') + + # The loop starts from the root node + # We assume the tree decomposition is valid and nice, hence saving time + # on checking. + for node in directed_TD: + in_deg = directed_TD.in_degree(node) + out_deg = directed_TD.out_degree(node) + + if in_deg == 0: + directed_TD.set_vertex(node, 'root') + elif out_deg == 2: + directed_TD.set_vertex(node, 'join') + elif out_deg == 1: + current_bag = node[1] + child_bag = directed_TD.neighbors_out(node)[0][1] + + if len(current_bag) == len(child_bag) + 1: + directed_TD.set_vertex(node, 'intro') + else: + directed_TD.set_vertex(node, 'forget') + else: + directed_TD.set_vertex(node, 'leaf') + + return Graph(directed_TD, name=name) + # # Treelength From 2062172e1593c2a58b11494ae031f82b89906687 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 4 Nov 2023 20:35:14 +0000 Subject: [PATCH 211/463] tree_decomposition.pyx: Make `tdlib` tests optional with correct syntax --- .../graph_decompositions/tree_decomposition.pyx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index d2ad99a9f54..c8c8a113c0d 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -508,19 +508,19 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=Fals The PetersenGraph has treewidth 4 (with ``tdlib``):: - sage: petersen = graphs.PetersenGraph() # optional tdlib - sage: petersen.treewidth(algorithm='tdlib') # optional tdlib - 4 # optional tdlib - sage: petersen.treewidth(algorithm='tdlib', certificate=True) # optional tdlib - Tree decomposition: Graph on 6 vertices # optional tdlib + sage: petersen = graphs.PetersenGraph() # optional - tdlib + sage: petersen.treewidth(algorithm='tdlib') # optional - tdlib + 4 # optional - tdlib + sage: petersen.treewidth(algorithm='tdlib', certificate=True) # optional - tdlib + Tree decomposition: Graph on 6 vertices # optional - tdlib Nice tree decomposition of the PetersenGraph has 28 nodes:: sage: petersen = graphs.PetersenGraph() sage: petersen.treewidth(algorithm='sage', certificate=True, nice=True) Nice tree decomposition of Tree decomposition: Graph on 28 vertices - sage: petersen.treewidth(algorithm='tdlib', certificate=True, nice=True) # optional tdlib - Nice tree decomposition of Tree decomposition: Graph on 28 vertices # optional tdlib + sage: petersen.treewidth(algorithm='tdlib', certificate=True, nice=True) # optional - tdlib + Nice tree decomposition of Tree decomposition: Graph on 28 vertices # optional - tdlib The treewidth of a 2-dimensional grid is its smallest side:: From ad0e56a26193f2b9ce353398ed2229646b65782e Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 5 Nov 2023 14:18:48 +0000 Subject: [PATCH 212/463] tree_decomposition.pyx: Remove unnecessary comments --- .../graphs/graph_decompositions/tree_decomposition.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index c8c8a113c0d..28eaaef6d95 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -508,11 +508,11 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=Fals The PetersenGraph has treewidth 4 (with ``tdlib``):: - sage: petersen = graphs.PetersenGraph() # optional - tdlib + sage: petersen = graphs.PetersenGraph() sage: petersen.treewidth(algorithm='tdlib') # optional - tdlib - 4 # optional - tdlib + 4 sage: petersen.treewidth(algorithm='tdlib', certificate=True) # optional - tdlib - Tree decomposition: Graph on 6 vertices # optional - tdlib + Tree decomposition: Graph on 6 vertices Nice tree decomposition of the PetersenGraph has 28 nodes:: @@ -520,7 +520,7 @@ def treewidth(g, k=None, kmin=None, certificate=False, algorithm=None, nice=Fals sage: petersen.treewidth(algorithm='sage', certificate=True, nice=True) Nice tree decomposition of Tree decomposition: Graph on 28 vertices sage: petersen.treewidth(algorithm='tdlib', certificate=True, nice=True) # optional - tdlib - Nice tree decomposition of Tree decomposition: Graph on 28 vertices # optional - tdlib + Nice tree decomposition of Tree decomposition: Graph on 28 vertices The treewidth of a 2-dimensional grid is its smallest side:: From 22f1ff3079eca662106f4daa2a907facea1855f8 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 5 Nov 2023 14:30:01 +0000 Subject: [PATCH 213/463] tree_decomposition.pyx: New example --- .../tree_decomposition.pyx | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 28eaaef6d95..436491e6c07 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -1011,7 +1011,7 @@ def make_nice_tree_decomposition(graph, tree_decomp): return nice_tree_decomp -def label_nice_tree_decomposition(nice_TD): +def label_nice_tree_decomposition(nice_TD, root): r""" Return a nice tree decomposition with nodes labelled accordingly. @@ -1019,17 +1019,42 @@ def label_nice_tree_decomposition(nice_TD): - ``nice_TD`` -- a nice tree decomposition + - ``root`` -- the root of the nice tree decomposition + OUTPUT: A nice tree decomposition with nodes labelled. + + EXAMPLES:: + + sage: bip_one_four = graphs.CompleteBipartiteGraph(1, 4) + sage: bip_one_four_TD = bip_one_four.treewidth(certificate=True) + sage: nice_TD = make_nice_tree_decomposition(bip_one_four_TD) + sage: label_TD = label_nice_tree_decomposition(nice_TD) + sage: for node in label_TD: + ....: print(node, label_TD.get_vertex(node)) + (0, {}) root + (1, {0}) forget + (2, {0, 1}) intro + (3, {0}) forget + (4, {0, 4}) join + (5, {0, 4}) intro + (6, {0, 4}) intro + (7, {0}) forget + (8, {0}) forget + (9, {0, 3}) intro + (10, {0, 2}) intro + (11, {3}) intro + (12, {2}) intro + (13, {}) leaf + (14, {}) leaf """ - directed_TD = DiGraph(nice_TD.breadth_first_search(start=root, - edges=True), - format='list_of_edges') + directed_TD = DiGraph(nice_TD.breadth_first_search(start=root, edges=True), + format='list_of_edges') # The loop starts from the root node - # We assume the tree decomposition is valid and nice, hence saving time - # on checking. + # We assume the tree decomposition is valid and nice, + # hence saving time on checking. for node in directed_TD: in_deg = directed_TD.in_degree(node) out_deg = directed_TD.out_degree(node) @@ -1049,7 +1074,7 @@ def label_nice_tree_decomposition(nice_TD): else: directed_TD.set_vertex(node, 'leaf') - return Graph(directed_TD, name=name) + return Graph(directed_TD, name=nice_TD.name()) # From 93e2baf77ffffd9ef63b665343da71feb011e03f Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 5 Nov 2023 17:47:47 +0000 Subject: [PATCH 214/463] tree_decomposition.pyx: Necessary imports for `label_nice_tree_decomposition`; Make example correct --- .../graphs/graph_decompositions/tree_decomposition.pyx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 436491e6c07..b9a33fde068 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -1027,10 +1027,12 @@ def label_nice_tree_decomposition(nice_TD, root): EXAMPLES:: + sage: from sage.graphs.graph_decompositions.tree_decomposition import make_nice_tree_decomposition, label_nice_tree_decomposition sage: bip_one_four = graphs.CompleteBipartiteGraph(1, 4) sage: bip_one_four_TD = bip_one_four.treewidth(certificate=True) - sage: nice_TD = make_nice_tree_decomposition(bip_one_four_TD) - sage: label_TD = label_nice_tree_decomposition(nice_TD) + sage: nice_TD = make_nice_tree_decomposition(bip_one_four, bip_one_four_TD) + sage: root = sorted(nice_TD.vertices())[0] + sage: label_TD = label_nice_tree_decomposition(nice_TD, root) sage: for node in label_TD: ....: print(node, label_TD.get_vertex(node)) (0, {}) root @@ -1049,6 +1051,9 @@ def label_nice_tree_decomposition(nice_TD, root): (13, {}) leaf (14, {}) leaf """ + from sage.graphs.digraph import DiGraph + from sage.graphs.graph import Graph + directed_TD = DiGraph(nice_TD.breadth_first_search(start=root, edges=True), format='list_of_edges') From a489f3ce2253b917abaccf4ed29c02155d699d1d Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Tue, 7 Nov 2023 21:20:24 +0000 Subject: [PATCH 215/463] tree_decomposition.pyx: Make example in `label_nice_tree_decomposition` sorted --- src/sage/graphs/graph_decompositions/tree_decomposition.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index b9a33fde068..f1ebec67af7 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -1033,7 +1033,7 @@ def label_nice_tree_decomposition(nice_TD, root): sage: nice_TD = make_nice_tree_decomposition(bip_one_four, bip_one_four_TD) sage: root = sorted(nice_TD.vertices())[0] sage: label_TD = label_nice_tree_decomposition(nice_TD, root) - sage: for node in label_TD: + sage: for node in sorted(label_TD): ....: print(node, label_TD.get_vertex(node)) (0, {}) root (1, {0}) forget From bd006df67861d65e0132617f11ed643c08906124 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Nov 2023 14:19:27 -0800 Subject: [PATCH 216/463] src/sage/algebras/commutative_dga.py: Remove obsolete '# needs sage.rings.finite_rings' --- src/sage/algebras/commutative_dga.py | 62 ++++++++++++++-------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index d1ea9b782e4..35facfa7866 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -949,9 +949,9 @@ def __classcall__(cls, base, names=None, degrees=None, R=None, I=None, category= TESTS:: - sage: A1 = GradedCommutativeAlgebra(GF(2), 'x,y', (3, 6)) # needs sage.rings.finite_rings - sage: A2 = GradedCommutativeAlgebra(GF(2), ['x', 'y'], [3, 6]) # needs sage.rings.finite_rings - sage: A1 is A2 # needs sage.rings.finite_rings + sage: A1 = GradedCommutativeAlgebra(GF(2), 'x,y', (3, 6)) + sage: A2 = GradedCommutativeAlgebra(GF(2), ['x', 'y'], [3, 6]) + sage: A1 is A2 True Testing the single generator case (:trac:`25276`):: @@ -962,8 +962,8 @@ def __classcall__(cls, base, names=None, degrees=None, R=None, I=None, category= sage: A4. = GradedCommutativeAlgebra(QQ, degrees=[4]) sage: z**2 == 0 False - sage: A5. = GradedCommutativeAlgebra(GF(2)) # needs sage.rings.finite_rings - sage: z**2 == 0 # needs sage.rings.finite_rings + sage: A5. = GradedCommutativeAlgebra(GF(2)) + sage: z**2 == 0 False """ if names is None: @@ -1207,7 +1207,6 @@ def quotient(self, I, check=True): EXAMPLES:: - sage: # needs sage.rings.finite_rings sage: A. = GradedCommutativeAlgebra(GF(5), degrees=(2, 2, 3, 4)) sage: I = A.ideal([x*t+z^2, x*y - t]) sage: B = A.quotient(I); B @@ -1910,7 +1909,6 @@ def degree(self, total=False): EXAMPLES:: - sage: # needs sage.rings.finite_rings sage: A. = GradedCommutativeAlgebra(GF(2), ....: degrees=((1,0), (0,1), (1,1))) sage: (a**2*b).degree() @@ -2390,23 +2388,23 @@ def cohomology_generators(self, max_degree): In contrast, the corresponding algebra in characteristic `p` has finitely generated cohomology:: - sage: A3. = GradedCommutativeAlgebra(GF(3), degrees=(1,2,2)) # needs sage.rings.finite_rings - sage: B3 = A3.cdg_algebra(differential={y: a*x}) # needs sage.rings.finite_rings - sage: B3.cohomology_generators(16) # needs sage.rings.finite_rings + sage: A3. = GradedCommutativeAlgebra(GF(3), degrees=(1,2,2)) + sage: B3 = A3.cdg_algebra(differential={y: a*x}) + sage: B3.cohomology_generators(16) {1: [a], 2: [x], 3: [a*y], 5: [a*y^2], 6: [y^3]} This method works with both singly graded and multi-graded algebras:: - sage: Cs. = GradedCommutativeAlgebra(GF(2), degrees=(1,2,2,3)) # needs sage.rings.finite_rings - sage: Ds = Cs.cdg_algebra({a:c, b:d}) # needs sage.rings.finite_rings - sage: Ds.cohomology_generators(10) # needs sage.rings.finite_rings + sage: Cs. = GradedCommutativeAlgebra(GF(2), degrees=(1,2,2,3)) + sage: Ds = Cs.cdg_algebra({a:c, b:d}) + sage: Ds.cohomology_generators(10) {2: [a^2], 4: [b^2]} - sage: Cm. = GradedCommutativeAlgebra(GF(2), # needs sage.rings.finite_rings + sage: Cm. = GradedCommutativeAlgebra(GF(2), ....: degrees=((1,0), (1,1), ....: (0,2), (0,3))) - sage: Dm = Cm.cdg_algebra({a:c, b:d}) # needs sage.rings.finite_rings - sage: Dm.cohomology_generators(10) # needs sage.rings.finite_rings + sage: Dm = Cm.cdg_algebra({a:c, b:d}) + sage: Dm.cohomology_generators(10) {2: [a^2], 4: [b^2]} TESTS: @@ -3509,9 +3507,9 @@ def GradedCommutativeAlgebra(ring, names=None, degrees=None, max_degree=None, We can construct multi-graded rings as well. We work in characteristic 2 for a change, so the algebras here are honestly commutative:: - sage: C. = GradedCommutativeAlgebra(GF(2), # needs sage.rings.finite_rings + sage: C. = GradedCommutativeAlgebra(GF(2), ....: degrees=((1,0), (1,1), (0,2), (0,3))) - sage: D = C.cdg_algebra(differential={a: c, b: d}); D # needs sage.rings.finite_rings + sage: D = C.cdg_algebra(differential={a: c, b: d}); D Commutative Differential Graded Algebra with generators ('a', 'b', 'c', 'd') in degrees ((1, 0), (1, 1), (0, 2), (0, 3)) over Finite Field of size 2 with differential: @@ -3524,46 +3522,46 @@ def GradedCommutativeAlgebra(ring, names=None, degrees=None, max_degree=None, Use tuples, lists, vectors, or elements of additive abelian groups to specify degrees:: - sage: D.basis(3) # basis in total degree 3 # needs sage.rings.finite_rings + sage: D.basis(3) # basis in total degree 3 [a^3, a*b, a*c, d] - sage: D.basis((1,2)) # basis in degree (1,2) # needs sage.rings.finite_rings + sage: D.basis((1,2)) # basis in degree (1,2) [a*c] - sage: D.basis([1,2]) # needs sage.rings.finite_rings + sage: D.basis([1,2]) [a*c] - sage: D.basis(vector([1,2])) # needs sage.rings.finite_rings + sage: D.basis(vector([1,2])) [a*c] sage: G = AdditiveAbelianGroup([0,0]); G Additive abelian group isomorphic to Z + Z - sage: D.basis(G(vector([1,2]))) # needs sage.rings.finite_rings + sage: D.basis(G(vector([1,2]))) [a*c] At this point, ``a``, for example, is an element of ``C``. We can redefine it so that it is instead an element of ``D`` in several ways, for instance using :meth:`gens` method:: - sage: a, b, c, d = D.gens() # needs sage.rings.finite_rings - sage: a.differential() # needs sage.rings.finite_rings + sage: a, b, c, d = D.gens() + sage: a.differential() c Or the :meth:`inject_variables` method:: - sage: D.inject_variables() # needs sage.rings.finite_rings + sage: D.inject_variables() Defining a, b, c, d - sage: (a*b).differential() # needs sage.rings.finite_rings + sage: (a*b).differential() b*c + a*d - sage: (a*b*c**2).degree() # needs sage.rings.finite_rings + sage: (a*b*c**2).degree() (2, 5) Degrees are returned as elements of additive abelian groups:: - sage: (a*b*c**2).degree() in G # needs sage.rings.finite_rings + sage: (a*b*c**2).degree() in G True - sage: (a*b*c**2).degree(total=True) # total degree # needs sage.rings.finite_rings + sage: (a*b*c**2).degree(total=True) # total degree 7 - sage: D.cohomology(4) # needs sage.rings.finite_rings + sage: D.cohomology(4) Free module generated by {[a^4], [b^2]} over Finite Field of size 2 - sage: D.cohomology((2,2)) # needs sage.rings.finite_rings + sage: D.cohomology((2,2)) Free module generated by {[b^2]} over Finite Field of size 2 Graded algebra with maximal degree:: From 919ec6ff0cf034bef5870b85e323f40ff6caa3a2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Nov 2023 14:25:29 -0800 Subject: [PATCH 217/463] src/sage/algebras/finite_gca.py: Remove dubious '# needs sage.libs.singular'; doctest cosmetics --- src/sage/algebras/finite_gca.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sage/algebras/finite_gca.py b/src/sage/algebras/finite_gca.py index 08ebb27616e..cb6c29e358d 100644 --- a/src/sage/algebras/finite_gca.py +++ b/src/sage/algebras/finite_gca.py @@ -90,14 +90,15 @@ class FiniteGCAlgebra(CombinatorialFreeModule, Algebra): sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,2,2,3), max_degree=6) sage: A - Graded commutative algebra with generators ('x', 'y', 'z', 't') in degrees (1, 2, 2, 3) with maximal degree 6 + Graded commutative algebra with generators ('x', 'y', 'z', 't') + in degrees (1, 2, 2, 3) with maximal degree 6 sage: t*x + x*t 0 sage: x^2 0 sage: x*t^2 0 - sage: x*y^2+z*t + sage: x*y^2 + z*t x*y^2 + z*t The generators can be returned with :meth:`algebra_generators`:: @@ -115,7 +116,9 @@ class FiniteGCAlgebra(CombinatorialFreeModule, Algebra): Depending on the context, the multiplication can be given a different symbol:: - sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,2,6,6), max_degree=10, mul_symbol='⌣', mul_latex_symbol=r'\smile') + sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,2,6,6), max_degree=10, + ....: mul_symbol='⌣', + ....: mul_latex_symbol=r'\smile') sage: x*y^2 + x*t x⌣y^2 + x⌣t sage: latex(x*y^2 - z*x) @@ -127,7 +130,7 @@ class FiniteGCAlgebra(CombinatorialFreeModule, Algebra): omitted, an instance of the class :class:`sage.algebras.commutative_dga.GCAlgebra` is created instead:: - sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,2,6,6)) # needs sage.libs.singular + sage: A. = GradedCommutativeAlgebra(QQ, degrees=(1,2,6,6)) sage: type(A) From 6ab6d84a5ad9fd5285c2372413dd1ef48ce9be8e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Nov 2023 20:20:16 -0800 Subject: [PATCH 218/463] build/pkgs/_prereq/distros/opensuse.txt: Add gawk --- build/pkgs/_prereq/distros/opensuse.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/build/pkgs/_prereq/distros/opensuse.txt b/build/pkgs/_prereq/distros/opensuse.txt index 070f456aea4..6f7a11fea47 100644 --- a/build/pkgs/_prereq/distros/opensuse.txt +++ b/build/pkgs/_prereq/distros/opensuse.txt @@ -11,6 +11,7 @@ binutils make m4 +gawk perl python3 tar From 82903bcc219f31c4aee7ccc77b9c854fcc4f5499 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 9 Mar 2023 00:42:11 -0800 Subject: [PATCH 219/463] build/pkgs/ipython: Update to 8.11.0 --- build/pkgs/ipython/checksums.ini | 6 +++--- build/pkgs/ipython/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/ipython/checksums.ini b/build/pkgs/ipython/checksums.ini index a539eb830b4..e1498b94189 100644 --- a/build/pkgs/ipython/checksums.ini +++ b/build/pkgs/ipython/checksums.ini @@ -1,5 +1,5 @@ tarball=ipython-VERSION.tar.gz -sha1=e0dd247f29befed1159d9bdca987d90c2ee0d34a -md5=8c98f6def0622ea32975cb779247c3d7 -cksum=2860792697 +sha1=9ae06dd2adbddbd12e1b7989c8c7cad135f0ead2 +md5=d1601937437f4ce74bea4c8b2cde6cd6 +cksum=3177895794 upstream_url=https://pypi.io/packages/source/i/ipython/ipython-VERSION.tar.gz diff --git a/build/pkgs/ipython/package-version.txt b/build/pkgs/ipython/package-version.txt index acd405b1d62..db3905bf80f 100644 --- a/build/pkgs/ipython/package-version.txt +++ b/build/pkgs/ipython/package-version.txt @@ -1 +1 @@ -8.6.0 +8.11.0 From 06a9532b9a9fbfa5b2b58b3c691eb71b799684a2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 9 Mar 2023 00:44:47 -0800 Subject: [PATCH 220/463] build/pkgs/jedi: Update to 0.18.2 --- build/pkgs/jedi/checksums.ini | 6 +++--- build/pkgs/jedi/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jedi/checksums.ini b/build/pkgs/jedi/checksums.ini index 2db629c8d82..b91b9b187f4 100644 --- a/build/pkgs/jedi/checksums.ini +++ b/build/pkgs/jedi/checksums.ini @@ -1,5 +1,5 @@ tarball=jedi-VERSION.tar.gz -sha1=e94444bd83b55247fd1f3d27d47cc0b148560134 -md5=d8dba4a98a35530f7f5b461c20aff180 -cksum=4093067035 +sha1=8ff91cf4b06cd540108a4c69105770756f831020 +md5=47e89a2b8bedcfeb1527fac37b9ba1b3 +cksum=3224505263 upstream_url=https://pypi.io/packages/source/j/jedi/jedi-VERSION.tar.gz diff --git a/build/pkgs/jedi/package-version.txt b/build/pkgs/jedi/package-version.txt index 249afd517d9..503a21deb47 100644 --- a/build/pkgs/jedi/package-version.txt +++ b/build/pkgs/jedi/package-version.txt @@ -1 +1 @@ -0.18.1 +0.18.2 From f49a4e0a237e2256e809ad8d7c420aabadc7c28a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 9 Mar 2023 00:46:50 -0800 Subject: [PATCH 221/463] build/pkgs/wcwidth: Update to 0.2.6 --- build/pkgs/wcwidth/checksums.ini | 6 +++--- build/pkgs/wcwidth/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/wcwidth/checksums.ini b/build/pkgs/wcwidth/checksums.ini index e81b55d8053..bca0da44a2c 100644 --- a/build/pkgs/wcwidth/checksums.ini +++ b/build/pkgs/wcwidth/checksums.ini @@ -1,5 +1,5 @@ tarball=wcwidth-VERSION.tar.gz -sha1=3822ed26dc70a4055827bc66cdc21126e51efd66 -md5=a07a75f99d316e14838ac760c831ea37 -cksum=497830371 +sha1=ec98f6ba8ea7c5d2cec9d24d31539d39e2f90d17 +md5=976b997f2ed155b5c2e9a4d50e528d90 +cksum=2272376797 upstream_url=https://pypi.io/packages/source/w/wcwidth/wcwidth-VERSION.tar.gz diff --git a/build/pkgs/wcwidth/package-version.txt b/build/pkgs/wcwidth/package-version.txt index 3a4036fb450..53a75d67355 100644 --- a/build/pkgs/wcwidth/package-version.txt +++ b/build/pkgs/wcwidth/package-version.txt @@ -1 +1 @@ -0.2.5 +0.2.6 From 8a34b2325b2a496e1577ce45d47b5bd22993d014 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 9 Mar 2023 00:46:58 -0800 Subject: [PATCH 222/463] build/pkgs/pygments: Update to 2.14.0 --- build/pkgs/pygments/checksums.ini | 6 +++--- build/pkgs/pygments/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/pygments/checksums.ini b/build/pkgs/pygments/checksums.ini index 14fc1c04cdb..108d39045a2 100644 --- a/build/pkgs/pygments/checksums.ini +++ b/build/pkgs/pygments/checksums.ini @@ -1,5 +1,5 @@ tarball=Pygments-VERSION.tar.gz -sha1=adaf31bf13a7bcc210568537138e0984ecdea626 -md5=6ccae578d28d18968b30a4711652fd9a -cksum=613387624 +sha1=9a2a836e2acfbc2f83c6c40c379d1335c38fa451 +md5=447be4afb076c8325a7dc659aff5b931 +cksum=2352097018 upstream_url=https://pypi.io/packages/source/p/pygments/Pygments-VERSION.tar.gz diff --git a/build/pkgs/pygments/package-version.txt b/build/pkgs/pygments/package-version.txt index fb2c0766b7c..edcfe40d198 100644 --- a/build/pkgs/pygments/package-version.txt +++ b/build/pkgs/pygments/package-version.txt @@ -1 +1 @@ -2.13.0 +2.14.0 From 1d3d4f869a3e652298fc5f6afa8beaa5379360c6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 9 Mar 2023 00:47:14 -0800 Subject: [PATCH 223/463] build/pkgs/stack_data: Update to 0.6.2 --- build/pkgs/stack_data/checksums.ini | 6 +++--- build/pkgs/stack_data/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/stack_data/checksums.ini b/build/pkgs/stack_data/checksums.ini index 625aaf0578f..b9bc5e8e3e3 100644 --- a/build/pkgs/stack_data/checksums.ini +++ b/build/pkgs/stack_data/checksums.ini @@ -1,5 +1,5 @@ tarball=stack_data-VERSION.tar.gz -sha1=58ed9cb32a42e07dbc18356d06f8db96475bc0f2 -md5=05c8c6c58c02280bc87b6851e40d38e6 -cksum=1485401259 +sha1=71d14defdfc9741bca4aaff049668197f01cd088 +md5=bf86c3c81a0158e1e7f3979da5a0033b +cksum=3302525331 upstream_url=https://pypi.io/packages/source/s/stack_data/stack_data-VERSION.tar.gz diff --git a/build/pkgs/stack_data/package-version.txt b/build/pkgs/stack_data/package-version.txt index ee6cdce3c29..b6160487433 100644 --- a/build/pkgs/stack_data/package-version.txt +++ b/build/pkgs/stack_data/package-version.txt @@ -1 +1 @@ -0.6.1 +0.6.2 From 29847b1982a54c5c6a37f9337a3b8057481bc380 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 9 Mar 2023 00:54:23 -0800 Subject: [PATCH 224/463] build/pkgs/asttokens: Update to 2.2.1 --- build/pkgs/asttokens/checksums.ini | 6 +++--- build/pkgs/asttokens/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/asttokens/checksums.ini b/build/pkgs/asttokens/checksums.ini index e69f1ecdfb3..e3759368f21 100644 --- a/build/pkgs/asttokens/checksums.ini +++ b/build/pkgs/asttokens/checksums.ini @@ -1,5 +1,5 @@ tarball=asttokens-VERSION.tar.gz -sha1=cca6058c6c23195148be93bfa32c0a0ca9b2f873 -md5=67b269e359fcb404cd8626985f3676ae -cksum=3749309047 +sha1=eda0bf8bf38ecd475e8358d6ce15968c8679ae86 +md5=a9ae6ae0f85398e511bcb9ec87695eed +cksum=1688343887 upstream_url=https://pypi.io/packages/source/a/asttokens/asttokens-VERSION.tar.gz diff --git a/build/pkgs/asttokens/package-version.txt b/build/pkgs/asttokens/package-version.txt index 7ec1d6db408..c043eea7767 100644 --- a/build/pkgs/asttokens/package-version.txt +++ b/build/pkgs/asttokens/package-version.txt @@ -1 +1 @@ -2.1.0 +2.2.1 From c3160e751507ab72b8111c0172790419e2dbe4a1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 9 Mar 2023 10:01:00 -0800 Subject: [PATCH 225/463] build/pkgs/prompt_toolkit: Update to 3.0.38 --- build/pkgs/prompt_toolkit/checksums.ini | 6 +++--- build/pkgs/prompt_toolkit/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/prompt_toolkit/checksums.ini b/build/pkgs/prompt_toolkit/checksums.ini index ec0df09c5b9..372a5d3b41c 100644 --- a/build/pkgs/prompt_toolkit/checksums.ini +++ b/build/pkgs/prompt_toolkit/checksums.ini @@ -1,5 +1,5 @@ tarball=prompt_toolkit-VERSION.tar.gz -sha1=77365bfc17ab577d80708a3395186ec68a7dbb2c -md5=214d36301eb139adba280793040d7755 -cksum=3187933391 +sha1=a45022d4b1b3bd827cb2e094de7ce40cc7b05337 +md5=c5e321dd56e1ed8ed95c5fccffb8f3da +cksum=2595783299 upstream_url=https://pypi.io/packages/source/p/prompt_toolkit/prompt_toolkit-VERSION.tar.gz diff --git a/build/pkgs/prompt_toolkit/package-version.txt b/build/pkgs/prompt_toolkit/package-version.txt index 03a04fce56f..766ca985e2b 100644 --- a/build/pkgs/prompt_toolkit/package-version.txt +++ b/build/pkgs/prompt_toolkit/package-version.txt @@ -1 +1 @@ -3.0.24 +3.0.38 From 59b8bf4f4f5ac302bced50619efa504afeade91b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 9 Mar 2023 10:05:09 -0800 Subject: [PATCH 226/463] build/pkgs/prompt_toolkit/install-requires.txt: Tentative update --- build/pkgs/prompt_toolkit/install-requires.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/prompt_toolkit/install-requires.txt b/build/pkgs/prompt_toolkit/install-requires.txt index 30d49fc8454..2513c28c95d 100644 --- a/build/pkgs/prompt_toolkit/install-requires.txt +++ b/build/pkgs/prompt_toolkit/install-requires.txt @@ -1,2 +1,2 @@ # https://github.com/sagemath/sage/issues/33428 - prompt_toolkit 3.0.25+ breaks Ctrl-C -prompt_toolkit >=3.0.5, <3.0.25 +prompt_toolkit >=3.0.38 From 8a200a4022b9d7f953d72d47ae504f5cd6b7fd66 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 9 Mar 2023 10:05:29 -0800 Subject: [PATCH 227/463] build/pkgs/ipywidgets: Update to 8.0.4 --- build/pkgs/ipywidgets/checksums.ini | 6 +++--- build/pkgs/ipywidgets/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/ipywidgets/checksums.ini b/build/pkgs/ipywidgets/checksums.ini index 63a890dcf81..d3b3fc45531 100644 --- a/build/pkgs/ipywidgets/checksums.ini +++ b/build/pkgs/ipywidgets/checksums.ini @@ -1,5 +1,5 @@ tarball=ipywidgets-VERSION.tar.gz -sha1=b2c8adf4fefc012adfb61e03a2e957bddbbb7597 -md5=c976de164b782eac9e5dfc933e8da295 -cksum=305610881 +sha1=d54c146be6e9deb545414ceeeb1a5155af81c360 +md5=32c8bedf390539a8e40d1c727586ecb7 +cksum=3287845159 upstream_url=https://pypi.io/packages/source/i/ipywidgets/ipywidgets-VERSION.tar.gz diff --git a/build/pkgs/ipywidgets/package-version.txt b/build/pkgs/ipywidgets/package-version.txt index 8b22a322d0f..50c496d20c6 100644 --- a/build/pkgs/ipywidgets/package-version.txt +++ b/build/pkgs/ipywidgets/package-version.txt @@ -1 +1 @@ -8.0.2 +8.0.4 From b7bbd0094bde35d1d732a0f6a9cbc6d598322bb7 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Wed, 8 Nov 2023 23:53:23 +0000 Subject: [PATCH 228/463] ipython 8.17.2, rebase --- build/pkgs/ipython/checksums.ini | 6 +++--- build/pkgs/ipython/install-requires.txt | 2 +- build/pkgs/ipython/package-version.txt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/pkgs/ipython/checksums.ini b/build/pkgs/ipython/checksums.ini index e1498b94189..3b0a8df72dd 100644 --- a/build/pkgs/ipython/checksums.ini +++ b/build/pkgs/ipython/checksums.ini @@ -1,5 +1,5 @@ tarball=ipython-VERSION.tar.gz -sha1=9ae06dd2adbddbd12e1b7989c8c7cad135f0ead2 -md5=d1601937437f4ce74bea4c8b2cde6cd6 -cksum=3177895794 +sha1=62afbe2e62e713ee89bfe5303809bdcd2affb2a3 +md5=ac2ff5bad97aa09befdf7f0f27323699 +cksum=413345511 upstream_url=https://pypi.io/packages/source/i/ipython/ipython-VERSION.tar.gz diff --git a/build/pkgs/ipython/install-requires.txt b/build/pkgs/ipython/install-requires.txt index 03d4a4f3413..4de933c2b25 100644 --- a/build/pkgs/ipython/install-requires.txt +++ b/build/pkgs/ipython/install-requires.txt @@ -1,2 +1,2 @@ -ipython >=7.13.0, <8.9.0 +ipython >=7.13.0 # ipython >= 8.9.0 requires prompt_toolkit too new for Sage diff --git a/build/pkgs/ipython/package-version.txt b/build/pkgs/ipython/package-version.txt index db3905bf80f..86487fdd0f7 100644 --- a/build/pkgs/ipython/package-version.txt +++ b/build/pkgs/ipython/package-version.txt @@ -1 +1 @@ -8.11.0 +8.17.2 From f65d718735703ee4c76f216f342589d3c89fa853 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Wed, 8 Nov 2023 23:59:35 +0000 Subject: [PATCH 229/463] fix for prompt-toolkit --- src/sage/repl/interpreter.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/sage/repl/interpreter.py b/src/sage/repl/interpreter.py index b9a222c12ef..4ddb8aa94a3 100644 --- a/src/sage/repl/interpreter.py +++ b/src/sage/repl/interpreter.py @@ -153,6 +153,18 @@ from IPython.terminal.ipapp import TerminalIPythonApp, IPAppCrashHandler from IPython.core.crashhandler import CrashHandler +from ctypes import pythonapi, c_int, c_void_p +# The following functions are part of the stable ABI since python 3.2 +# See: https://docs.python.org/3/c-api/sys.html#c.PyOS_getsig + +# PyOS_sighandler_t PyOS_getsig(int i) +pythonapi.PyOS_getsig.restype = c_void_p +pythonapi.PyOS_getsig.argtypes = c_int, + +# PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h) +pythonapi.PyOS_setsig.restype = c_void_p +pythonapi.PyOS_setsig.argtypes = c_int, c_void_p, + # TODO: This global variable _do_preparse should be associated with an # IPython InteractiveShell as opposed to a global variable in this @@ -287,6 +299,18 @@ def init_display_formatter(self): backend = BackendIPythonCommandline() backend.get_display_manager().switch_backend(backend, shell=self) + def prompt_for_code(self): + # save sigint handlers (python and os level) + # https://github.com/prompt-toolkit/python-prompt-toolkit/issues/1576 + # https://github.com/sagemath/sage/issues/33428 + # https://github.com/sagemath/sage/pull/35251 + import signal + sigint = signal.getsignal(signal.SIGINT) + sigint_os = pythonapi.PyOS_getsig(signal.SIGINT) + text = TerminalInteractiveShell.prompt_for_code(self) + signal.signal(signal.SIGINT, sigint) + pythonapi.PyOS_setsig(signal.SIGINT, sigint_os) + return text class SageTestShell(SageShellOverride, TerminalInteractiveShell): """ From f9c3515edab25d8602a93a5ccac48bde7872ec7f Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 13 Nov 2023 13:06:59 +0000 Subject: [PATCH 230/463] bump ipywidgets to 8.1.1 --- build/pkgs/ipywidgets/checksums.ini | 6 +++--- build/pkgs/ipywidgets/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/ipywidgets/checksums.ini b/build/pkgs/ipywidgets/checksums.ini index d3b3fc45531..a04080bb509 100644 --- a/build/pkgs/ipywidgets/checksums.ini +++ b/build/pkgs/ipywidgets/checksums.ini @@ -1,5 +1,5 @@ tarball=ipywidgets-VERSION.tar.gz -sha1=d54c146be6e9deb545414ceeeb1a5155af81c360 -md5=32c8bedf390539a8e40d1c727586ecb7 -cksum=3287845159 +sha1=95f7ec13e8ce75e2da40c1789b4af291946a6d99 +md5=2809d1668037606caac588cab329bece +cksum=1839869422 upstream_url=https://pypi.io/packages/source/i/ipywidgets/ipywidgets-VERSION.tar.gz diff --git a/build/pkgs/ipywidgets/package-version.txt b/build/pkgs/ipywidgets/package-version.txt index 50c496d20c6..0e79152459e 100644 --- a/build/pkgs/ipywidgets/package-version.txt +++ b/build/pkgs/ipywidgets/package-version.txt @@ -1 +1 @@ -8.0.4 +8.1.1 From 9971d1e77374ae21e866614ef44e90adb9030d1f Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 13 Nov 2023 13:08:33 +0000 Subject: [PATCH 231/463] Revert "build/pkgs/prompt_toolkit/distros/conda.txt: Use version range as in install-requires.txt" This reverts commit 7dabb0a656dcbf6d670be0bd0faebbc36240b9ad. --- build/pkgs/prompt_toolkit/distros/conda.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/prompt_toolkit/distros/conda.txt b/build/pkgs/prompt_toolkit/distros/conda.txt index bfb1ed6a874..29392dfc5b3 100644 --- a/build/pkgs/prompt_toolkit/distros/conda.txt +++ b/build/pkgs/prompt_toolkit/distros/conda.txt @@ -1 +1 @@ -prompt_toolkit>=3.0.5,<3.0.25 +prompt_toolkit From 5d48b9e50e721885c083871a05675ae192819f56 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 13 Nov 2023 13:12:31 +0000 Subject: [PATCH 232/463] remove obsolete comments, sync the version of prompt_toolkit for conda --- build/pkgs/ipython/install-requires.txt | 1 - build/pkgs/prompt_toolkit/distros/conda.txt | 2 +- build/pkgs/prompt_toolkit/install-requires.txt | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/build/pkgs/ipython/install-requires.txt b/build/pkgs/ipython/install-requires.txt index 4de933c2b25..a52df49c421 100644 --- a/build/pkgs/ipython/install-requires.txt +++ b/build/pkgs/ipython/install-requires.txt @@ -1,2 +1 @@ ipython >=7.13.0 -# ipython >= 8.9.0 requires prompt_toolkit too new for Sage diff --git a/build/pkgs/prompt_toolkit/distros/conda.txt b/build/pkgs/prompt_toolkit/distros/conda.txt index 29392dfc5b3..e3e1de9a3ea 100644 --- a/build/pkgs/prompt_toolkit/distros/conda.txt +++ b/build/pkgs/prompt_toolkit/distros/conda.txt @@ -1 +1 @@ -prompt_toolkit +prompt_toolkit >=3.0.38 diff --git a/build/pkgs/prompt_toolkit/install-requires.txt b/build/pkgs/prompt_toolkit/install-requires.txt index 2513c28c95d..e3e1de9a3ea 100644 --- a/build/pkgs/prompt_toolkit/install-requires.txt +++ b/build/pkgs/prompt_toolkit/install-requires.txt @@ -1,2 +1 @@ -# https://github.com/sagemath/sage/issues/33428 - prompt_toolkit 3.0.25+ breaks Ctrl-C prompt_toolkit >=3.0.38 From fd59d5347bb3239fa5478ca1215155b8363a09ae Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Mon, 13 Nov 2023 23:09:15 +0530 Subject: [PATCH 233/463] simplified the code --- src/sage/graphs/generic_graph.py | 35 ++++++++++++++++++++ src/sage/graphs/graph.py | 56 -------------------------------- 2 files changed, 35 insertions(+), 56 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index eedbc36bef3..73d7556344e 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15726,6 +15726,41 @@ def distance_all_pairs(self, by_weight=False, algorithm=None, algorithm=algorithm, weight_function=weight_function, check_weight=check_weight)[0] + + def power(self, k): + r""" + Compute the kth power graph of an undirected, unweighted graph based on + shortest distances between nodes using BFS. + + INPUT: + - graph: An undirected, unweighted graph. + - k: The maximum path length for considering edges in the power graph. + + OUTPUT: + - The kth power graph based on shortest distances between nodes. + + EXAMPLE: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: k = 2 + sage: PG = G.power(k) + sage: PG.edges() + [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (5, 4), (4, 5)] + + sage: G = DiGraph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: k = 3 + sage: PG = g.power(k) + sage: PG.edges() + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (1, 0, None), (1, 2, None), (1, 3, None), (1, 4, None), (1, 5, None), (2, 0, None), (2, 1, None), (2, 3, None), (2, 4, None), (2, 5, None), (3, 0, None), (3, 1, None), (3, 2, None), (4, 5, None)] + + """ + power_of_graph = self.copy() + for u in self: + for v in self.breadth_first_search(u, distance=k): + if u != v: + power_of_graph.add_edge(u, v) + + return power_of_graph def girth(self, certificate=False): """ diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index b1e6573356d..2435bd815b7 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4890,62 +4890,6 @@ def independent_set_of_representatives(self, family, solver=None, verbose=0, return repr - @doc_index("Basic methods") - def power_of_graph(self, k): - r""" - Compute the kth power graph of an undirected, unweighted graph based on - shortest distances between nodes using BFS. - - INPUT: - - graph: An undirected, unweighted graph. - - k: The maximum path length for considering edges in the power graph. - - OUTPUT: - - The kth power graph based on shortest distances between nodes. - - EXAMPLE: - - sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) - sage: k = 2 - sage: PG = power_graph_with_shortest_distances(G, k) - sage: PG.edges() - [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (5, 4), (4, 5)] - - """ - n = self.order() - all_distances = {} # Dictionary to store shortest distances between all pairs of nodes - - from collections import deque - - # Step 1: Compute shortest distances using BFS - for u in self.vertices(): - distances = {} # Dictionary to store distances from u to all other nodes - visited = {v: False for v in self.vertices()} - queue = deque() - - visited[u] = True - distances[u] = 0 - queue.append(u) - - while queue: - v = queue.popleft() - for neighbor in self.neighbors(v): - if not visited[neighbor]: - visited[neighbor] = True - distances[neighbor] = distances[v] + 1 - queue.append(neighbor) - - all_distances[u] = distances - - # Step 2: Create the kth power graph based on distances - PG = Graph() - for u in self.vertices(): - for v in self.vertices(): - if u != v and all_distances[u].get(v, float('inf')) <= k: - PG.add_edge(u, v) - - return PG - @doc_index("Algorithmically hard stuff") def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_tolerance=1e-3): r""" From 8c68abfe62927b826e0a2b3db4b964a03cdd45ec Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Tue, 27 Jun 2023 19:30:57 +0200 Subject: [PATCH 234/463] upgrade to flint 3.0.0 - remove arb and antic - patch msolve (patch is already upstream but not yet in a release) --- build/pkgs/antic/SPKG.rst | 18 ------- build/pkgs/antic/checksums.ini | 5 -- build/pkgs/antic/dependencies | 4 -- build/pkgs/antic/distros/arch.txt | 1 - build/pkgs/antic/distros/conda.txt | 1 - build/pkgs/antic/distros/debian.txt | 1 - build/pkgs/antic/distros/fedora.txt | 1 - build/pkgs/antic/distros/freebsd.txt | 1 - build/pkgs/antic/distros/opensuse.txt | 1 - build/pkgs/antic/distros/repology.txt | 1 - build/pkgs/antic/package-version.txt | 1 - build/pkgs/antic/spkg-install.in | 19 ------- build/pkgs/antic/type | 1 - build/pkgs/arb/SPKG.rst | 27 ---------- build/pkgs/arb/checksums.ini | 5 -- build/pkgs/arb/dependencies | 4 -- build/pkgs/arb/distros/arch.txt | 1 - build/pkgs/arb/distros/conda.txt | 1 - build/pkgs/arb/distros/debian.txt | 1 - build/pkgs/arb/distros/fedora.txt | 1 - build/pkgs/arb/distros/freebsd.txt | 1 - build/pkgs/arb/distros/gentoo.txt | 1 - build/pkgs/arb/distros/homebrew.txt | 1 - build/pkgs/arb/distros/nix.txt | 1 - build/pkgs/arb/distros/opensuse.txt | 1 - build/pkgs/arb/distros/repology.txt | 1 - build/pkgs/arb/distros/void.txt | 1 - build/pkgs/arb/package-version.txt | 1 - build/pkgs/arb/spkg-check.in | 2 - build/pkgs/arb/spkg-configure.m4 | 23 -------- build/pkgs/arb/spkg-install.in | 17 ------ build/pkgs/arb/type | 1 - build/pkgs/e_antic/dependencies | 2 +- build/pkgs/flint/SPKG.rst | 6 +-- build/pkgs/flint/checksums.ini | 8 +-- build/pkgs/flint/dependencies | 2 +- build/pkgs/flint/package-version.txt | 2 +- build/pkgs/flint/spkg-build.in | 3 ++ build/pkgs/flint/spkg-configure.m4 | 4 +- build/pkgs/flint/spkg-install.in | 34 ------------ .../0001-Make-msolve-build-with-flint3.patch | 53 +++++++++++++++++++ build/pkgs/sagelib/dependencies | 2 +- build/pkgs/symengine/dependencies | 2 +- src/sage/features/sagemath.py | 2 +- 44 files changed, 71 insertions(+), 195 deletions(-) delete mode 100644 build/pkgs/antic/SPKG.rst delete mode 100644 build/pkgs/antic/checksums.ini delete mode 100644 build/pkgs/antic/dependencies delete mode 100644 build/pkgs/antic/distros/arch.txt delete mode 100644 build/pkgs/antic/distros/conda.txt delete mode 100644 build/pkgs/antic/distros/debian.txt delete mode 100644 build/pkgs/antic/distros/fedora.txt delete mode 100644 build/pkgs/antic/distros/freebsd.txt delete mode 100644 build/pkgs/antic/distros/opensuse.txt delete mode 100644 build/pkgs/antic/distros/repology.txt delete mode 100644 build/pkgs/antic/package-version.txt delete mode 100644 build/pkgs/antic/spkg-install.in delete mode 100644 build/pkgs/antic/type delete mode 100644 build/pkgs/arb/SPKG.rst delete mode 100644 build/pkgs/arb/checksums.ini delete mode 100644 build/pkgs/arb/dependencies delete mode 100644 build/pkgs/arb/distros/arch.txt delete mode 100644 build/pkgs/arb/distros/conda.txt delete mode 100644 build/pkgs/arb/distros/debian.txt delete mode 100644 build/pkgs/arb/distros/fedora.txt delete mode 100644 build/pkgs/arb/distros/freebsd.txt delete mode 100644 build/pkgs/arb/distros/gentoo.txt delete mode 100644 build/pkgs/arb/distros/homebrew.txt delete mode 100644 build/pkgs/arb/distros/nix.txt delete mode 100644 build/pkgs/arb/distros/opensuse.txt delete mode 100644 build/pkgs/arb/distros/repology.txt delete mode 100644 build/pkgs/arb/distros/void.txt delete mode 100644 build/pkgs/arb/package-version.txt delete mode 100644 build/pkgs/arb/spkg-check.in delete mode 100644 build/pkgs/arb/spkg-configure.m4 delete mode 100644 build/pkgs/arb/spkg-install.in delete mode 100644 build/pkgs/arb/type create mode 100644 build/pkgs/flint/spkg-build.in create mode 100644 build/pkgs/msolve/patches/0001-Make-msolve-build-with-flint3.patch diff --git a/build/pkgs/antic/SPKG.rst b/build/pkgs/antic/SPKG.rst deleted file mode 100644 index d6c32377957..00000000000 --- a/build/pkgs/antic/SPKG.rst +++ /dev/null @@ -1,18 +0,0 @@ -antic: Algebraic Number Theory In C -=================================== - -Description ------------ - -Algebraic Number Theory In C - -License -------- - -LGPL 2.1 - -Upstream Contact ----------------- - -https://github.com/wbhart/antic - diff --git a/build/pkgs/antic/checksums.ini b/build/pkgs/antic/checksums.ini deleted file mode 100644 index fc8711ecd13..00000000000 --- a/build/pkgs/antic/checksums.ini +++ /dev/null @@ -1,5 +0,0 @@ -tarball=antic-VERSION.tar.gz -sha1=940d8ea2c3512b9d49ee3101cf043f777764bd8f -md5=4e896420dd6344b53b307871efb2cbb4 -cksum=1938565125 -upstream_url=https://github.com/wbhart/antic/archive/refs/tags/vVERSION.tar.gz diff --git a/build/pkgs/antic/dependencies b/build/pkgs/antic/dependencies deleted file mode 100644 index c95d2836ce5..00000000000 --- a/build/pkgs/antic/dependencies +++ /dev/null @@ -1,4 +0,0 @@ -$(MP_LIBRARY) mpfr flint - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/antic/distros/arch.txt b/build/pkgs/antic/distros/arch.txt deleted file mode 100644 index 83c7cab14e4..00000000000 --- a/build/pkgs/antic/distros/arch.txt +++ /dev/null @@ -1 +0,0 @@ -antic diff --git a/build/pkgs/antic/distros/conda.txt b/build/pkgs/antic/distros/conda.txt deleted file mode 100644 index 83c7cab14e4..00000000000 --- a/build/pkgs/antic/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -antic diff --git a/build/pkgs/antic/distros/debian.txt b/build/pkgs/antic/distros/debian.txt deleted file mode 100644 index 8fdcd3e5721..00000000000 --- a/build/pkgs/antic/distros/debian.txt +++ /dev/null @@ -1 +0,0 @@ -libantic-dev diff --git a/build/pkgs/antic/distros/fedora.txt b/build/pkgs/antic/distros/fedora.txt deleted file mode 100644 index 1b16da9f64b..00000000000 --- a/build/pkgs/antic/distros/fedora.txt +++ /dev/null @@ -1 +0,0 @@ -antic-devel diff --git a/build/pkgs/antic/distros/freebsd.txt b/build/pkgs/antic/distros/freebsd.txt deleted file mode 100644 index 116ff3a26f3..00000000000 --- a/build/pkgs/antic/distros/freebsd.txt +++ /dev/null @@ -1 +0,0 @@ -math/antic diff --git a/build/pkgs/antic/distros/opensuse.txt b/build/pkgs/antic/distros/opensuse.txt deleted file mode 100644 index 1b16da9f64b..00000000000 --- a/build/pkgs/antic/distros/opensuse.txt +++ /dev/null @@ -1 +0,0 @@ -antic-devel diff --git a/build/pkgs/antic/distros/repology.txt b/build/pkgs/antic/distros/repology.txt deleted file mode 100644 index 83c7cab14e4..00000000000 --- a/build/pkgs/antic/distros/repology.txt +++ /dev/null @@ -1 +0,0 @@ -antic diff --git a/build/pkgs/antic/package-version.txt b/build/pkgs/antic/package-version.txt deleted file mode 100644 index 3a4036fb450..00000000000 --- a/build/pkgs/antic/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -0.2.5 diff --git a/build/pkgs/antic/spkg-install.in b/build/pkgs/antic/spkg-install.in deleted file mode 100644 index c57fa884a20..00000000000 --- a/build/pkgs/antic/spkg-install.in +++ /dev/null @@ -1,19 +0,0 @@ -cd src - -# Copied from build/pkgs/flint/spkg-install.in: -# Trac #29607: We must always supply --with-gmp, --with-mpfr, -# --with-ntl because otherwise FLINT's configure script uses -# /usr/local, which is always wrong. -# This is why we do not use $SAGE_CONFIGURE_GMP etc. here. -# The value $SAGE_LOCAL is always a safe choice even if the library -# is coming from the system and is found using what is in -# LIBRARY_PATH or LDFLAGS etc. -./configure \ - --disable-static \ - --prefix="$SAGE_LOCAL" \ - --with-gmp="$SAGE_LOCAL" \ - --with-mpfr="$SAGE_LOCAL" \ - --with-flint="$SAGE_LOCAL" || sdh_die "Error: Failed to configure antic." - -sdh_make verbose -sdh_make_install diff --git a/build/pkgs/antic/type b/build/pkgs/antic/type deleted file mode 100644 index 134d9bc32d5..00000000000 --- a/build/pkgs/antic/type +++ /dev/null @@ -1 +0,0 @@ -optional diff --git a/build/pkgs/arb/SPKG.rst b/build/pkgs/arb/SPKG.rst deleted file mode 100644 index cff49ddb95b..00000000000 --- a/build/pkgs/arb/SPKG.rst +++ /dev/null @@ -1,27 +0,0 @@ -arb: Arbitrary-precision floating-point ball arithmetic -======================================================= - -Description ------------ - -Arb is a C library for arbitrary-precision floating-point ball -arithmetic, developed by Fredrik Johansson -(fredrik.johansson@gmail.com). It supports efficient high-precision -computation with polynomials, power series, matrices and special -functions over the real and complex numbers, with automatic, rigorous -error control. - -License -------- - -GNU General Public License v2+ - - -Upstream Contact ----------------- - - - Fredrik Johansson: fredrik.johansson@gmail.com - - - https://arblib.org/ - - - http://github.com/fredrik-johansson/arb/ diff --git a/build/pkgs/arb/checksums.ini b/build/pkgs/arb/checksums.ini deleted file mode 100644 index 80ef43dad5d..00000000000 --- a/build/pkgs/arb/checksums.ini +++ /dev/null @@ -1,5 +0,0 @@ -tarball=arb-VERSION.tar.gz -sha1=a1efe035dd3af3613dd685971a156f652b86ff63 -md5=9b369e29f93cdf2d4f90b57a92526cce -cksum=64252121 -upstream_url=https://github.com/fredrik-johansson/arb/archive/VERSION.tar.gz diff --git a/build/pkgs/arb/dependencies b/build/pkgs/arb/dependencies deleted file mode 100644 index c95d2836ce5..00000000000 --- a/build/pkgs/arb/dependencies +++ /dev/null @@ -1,4 +0,0 @@ -$(MP_LIBRARY) mpfr flint - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/arb/distros/arch.txt b/build/pkgs/arb/distros/arch.txt deleted file mode 100644 index 86c41dbaa5f..00000000000 --- a/build/pkgs/arb/distros/arch.txt +++ /dev/null @@ -1 +0,0 @@ -arb diff --git a/build/pkgs/arb/distros/conda.txt b/build/pkgs/arb/distros/conda.txt deleted file mode 100644 index 86c41dbaa5f..00000000000 --- a/build/pkgs/arb/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -arb diff --git a/build/pkgs/arb/distros/debian.txt b/build/pkgs/arb/distros/debian.txt deleted file mode 100644 index 9fe71110712..00000000000 --- a/build/pkgs/arb/distros/debian.txt +++ /dev/null @@ -1 +0,0 @@ -libflint-arb-dev diff --git a/build/pkgs/arb/distros/fedora.txt b/build/pkgs/arb/distros/fedora.txt deleted file mode 100644 index 76794404627..00000000000 --- a/build/pkgs/arb/distros/fedora.txt +++ /dev/null @@ -1 +0,0 @@ -arb arb-devel diff --git a/build/pkgs/arb/distros/freebsd.txt b/build/pkgs/arb/distros/freebsd.txt deleted file mode 100644 index 2ef8c7cec0f..00000000000 --- a/build/pkgs/arb/distros/freebsd.txt +++ /dev/null @@ -1 +0,0 @@ -math/arb diff --git a/build/pkgs/arb/distros/gentoo.txt b/build/pkgs/arb/distros/gentoo.txt deleted file mode 100644 index 58e3d4f8008..00000000000 --- a/build/pkgs/arb/distros/gentoo.txt +++ /dev/null @@ -1 +0,0 @@ -sci-mathematics/arb diff --git a/build/pkgs/arb/distros/homebrew.txt b/build/pkgs/arb/distros/homebrew.txt deleted file mode 100644 index 86c41dbaa5f..00000000000 --- a/build/pkgs/arb/distros/homebrew.txt +++ /dev/null @@ -1 +0,0 @@ -arb diff --git a/build/pkgs/arb/distros/nix.txt b/build/pkgs/arb/distros/nix.txt deleted file mode 100644 index 86c41dbaa5f..00000000000 --- a/build/pkgs/arb/distros/nix.txt +++ /dev/null @@ -1 +0,0 @@ -arb diff --git a/build/pkgs/arb/distros/opensuse.txt b/build/pkgs/arb/distros/opensuse.txt deleted file mode 100644 index 3319855150c..00000000000 --- a/build/pkgs/arb/distros/opensuse.txt +++ /dev/null @@ -1 +0,0 @@ -arb-devel diff --git a/build/pkgs/arb/distros/repology.txt b/build/pkgs/arb/distros/repology.txt deleted file mode 100644 index 179c9d507e1..00000000000 --- a/build/pkgs/arb/distros/repology.txt +++ /dev/null @@ -1 +0,0 @@ -arb-fp diff --git a/build/pkgs/arb/distros/void.txt b/build/pkgs/arb/distros/void.txt deleted file mode 100644 index 3319855150c..00000000000 --- a/build/pkgs/arb/distros/void.txt +++ /dev/null @@ -1 +0,0 @@ -arb-devel diff --git a/build/pkgs/arb/package-version.txt b/build/pkgs/arb/package-version.txt deleted file mode 100644 index e9763f6bfed..00000000000 --- a/build/pkgs/arb/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -2.23.0 diff --git a/build/pkgs/arb/spkg-check.in b/build/pkgs/arb/spkg-check.in deleted file mode 100644 index 27cd9419538..00000000000 --- a/build/pkgs/arb/spkg-check.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -$MAKE check diff --git a/build/pkgs/arb/spkg-configure.m4 b/build/pkgs/arb/spkg-configure.m4 deleted file mode 100644 index ef2dd0aac4a..00000000000 --- a/build/pkgs/arb/spkg-configure.m4 +++ /dev/null @@ -1,23 +0,0 @@ -SAGE_SPKG_CONFIGURE([arb], [ - AC_REQUIRE([SAGE_SPKG_CONFIGURE_FLINT]) - SAGE_ARB_LIBRARY="arb" - AC_MSG_CHECKING([installing flint? ]) - if test x$sage_spkg_install_flint = xyes; then - AC_MSG_RESULT([yes; install arb as well]) - sage_spkg_install_arb=yes - else - AC_CHECK_HEADER(arb.h, [ - dnl below function added in version 2.16 of arb - AC_CHECK_LIB([arb], [acb_mat_eig_simple], [], - [dnl in Debian the name of dylib is different. - AC_CHECK_LIB([flint-arb], [acb_mat_eig_simple], - [SAGE_ARB_LIBRARY="flint-arb"], [sage_spkg_install_arb=yes])]) - ], [sage_spkg_install_arb=yes]) - fi -], [], [], [ - if test x$sage_spkg_install_arb = xyes; then - AC_SUBST(SAGE_ARB_LIBRARY,["arb"]) - else - AC_SUBST(SAGE_ARB_LIBRARY,[$SAGE_ARB_LIBRARY]) - fi -]) diff --git a/build/pkgs/arb/spkg-install.in b/build/pkgs/arb/spkg-install.in deleted file mode 100644 index 9322f04c912..00000000000 --- a/build/pkgs/arb/spkg-install.in +++ /dev/null @@ -1,17 +0,0 @@ -cd src - -# Trac #29607: We must always supply --with-gmp, --with-mpfr, -# --with-flint because otherwise ARB's configure script uses -# /usr/local, which is always wrong. -# This is why we do not use $SAGE_CONFIGURE_GMP etc. here. -# The value $SAGE_LOCAL is always a safe choice even if the library -# is coming from the system and is found using what is in -# LIBRARY_PATH or LDFLAGS etc. -./configure --disable-static --prefix="$SAGE_LOCAL" \ - --with-gmp="$SAGE_LOCAL" \ - --with-mpfr="$SAGE_LOCAL" \ - --with-flint="$SAGE_LOCAL" || \ - sdh_die "Error configuring arb." - -sdh_make verbose -sdh_make_install diff --git a/build/pkgs/arb/type b/build/pkgs/arb/type deleted file mode 100644 index a6a7b9cd726..00000000000 --- a/build/pkgs/arb/type +++ /dev/null @@ -1 +0,0 @@ -standard diff --git a/build/pkgs/e_antic/dependencies b/build/pkgs/e_antic/dependencies index fea1ffbda45..8e977a55c13 100644 --- a/build/pkgs/e_antic/dependencies +++ b/build/pkgs/e_antic/dependencies @@ -1,4 +1,4 @@ -$(MP_LIBRARY) flint arb antic boost_cropped +$(MP_LIBRARY) flint boost_cropped ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/flint/SPKG.rst b/build/pkgs/flint/SPKG.rst index f91de70d1ff..d9dcea0903b 100644 --- a/build/pkgs/flint/SPKG.rst +++ b/build/pkgs/flint/SPKG.rst @@ -4,8 +4,8 @@ flint: Fast Library for Number Theory Description ----------- -FLINT is a C library for doing number theory, maintained by William -Hart. +FLINT is a C library for doing number theory, maintained by +Fredrik Johansson. Website: http://www.flintlib.org @@ -20,4 +20,4 @@ Upstream Contact - flint-devel Gougle Group (http://groups.google.co.uk/group/flint-devel) -- William Hart +- Fredrik Johansson diff --git a/build/pkgs/flint/checksums.ini b/build/pkgs/flint/checksums.ini index 3d449d98064..ab836606657 100644 --- a/build/pkgs/flint/checksums.ini +++ b/build/pkgs/flint/checksums.ini @@ -1,5 +1,5 @@ tarball=flint-VERSION.tar.gz -sha1=63d90f8242c8f8ab4011fbcfb44b86c154f43abd -md5=c2d3cec326438f159a530c66eb07fafe -cksum=4244948341 -upstream_url=http://flintlib.org/flint-VERSION.tar.gz +sha1=65be9297c06edd7e24f20874b7bd6130cee56723 +md5=5189f67b0ec12e4a54d6782851642b81 +cksum=172350473 +upstream_url=https://github.com/flintlib/flint/releases/download/vVERSION/flint-VERSION.tar.gz diff --git a/build/pkgs/flint/dependencies b/build/pkgs/flint/dependencies index 385df4faa7d..1108dc4fb21 100644 --- a/build/pkgs/flint/dependencies +++ b/build/pkgs/flint/dependencies @@ -1,4 +1,4 @@ -$(MP_LIBRARY) mpfr ntl +$(MP_LIBRARY) mpfr ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/flint/package-version.txt b/build/pkgs/flint/package-version.txt index c8e38b61405..cb2b00e4f7a 100644 --- a/build/pkgs/flint/package-version.txt +++ b/build/pkgs/flint/package-version.txt @@ -1 +1 @@ -2.9.0 +3.0.1 diff --git a/build/pkgs/flint/spkg-build.in b/build/pkgs/flint/spkg-build.in new file mode 100644 index 00000000000..ffb822c8a97 --- /dev/null +++ b/build/pkgs/flint/spkg-build.in @@ -0,0 +1,3 @@ +cd src +sdh_configure +sdh_make diff --git a/build/pkgs/flint/spkg-configure.m4 b/build/pkgs/flint/spkg-configure.m4 index a58108c9d6e..32da02e52c9 100644 --- a/build/pkgs/flint/spkg-configure.m4 +++ b/build/pkgs/flint/spkg-configure.m4 @@ -1,8 +1,8 @@ SAGE_SPKG_CONFIGURE([flint], [ SAGE_SPKG_DEPCHECK([mpfr ntl], [ AC_CHECK_HEADER(flint/flint.h, [ - dnl flint_parallel_binary_splitting appears in Flint 2.9.0, needed by arb 2.23 - AC_SEARCH_LIBS([flint_parallel_binary_splitting], [flint], [ + dnl gr_get_fexpr appears in Flint 3.0 + AC_SEARCH_LIBS([gr_get_fexpr], [flint], [ dnl check that NTL is linked in AC_SEARCH_LIBS([fmpz_poly_get_ZZX], [flint], [ diff --git a/build/pkgs/flint/spkg-install.in b/build/pkgs/flint/spkg-install.in index eacd7b6e491..3ea8c053669 100644 --- a/build/pkgs/flint/spkg-install.in +++ b/build/pkgs/flint/spkg-install.in @@ -1,36 +1,2 @@ -############################################################################### -# -# FLINT Sage install script -# -############################################################################### -if [ "$SAGE_DEBUG" = "yes" ]; then - echo "Building a debug version of FLINT." - FLINT_TUNE=" $FLINT_TUNE"; export FLINT_TUNE - FLINT_CONFIGURE="--enable-assert $FLINT_CONFIGURE" -fi - cd src - -echo "Configuring FLINT." -# Trac #29607: We must always supply --with-gmp, --with-mpfr, -# --with-ntl because otherwise FLINT's configure script uses -# /usr/local, which is always wrong. -# This is why we do not use $SAGE_CONFIGURE_GMP etc. here. -# The value $SAGE_LOCAL is always a safe choice even if the library -# is coming from the system and is found using what is in -# LIBRARY_PATH or LDFLAGS etc. -./configure \ - --disable-static \ - --prefix="$SAGE_LOCAL" \ - --with-gmp="$SAGE_LOCAL" \ - --with-mpfr="$SAGE_LOCAL" \ - --with-ntl="$SAGE_LOCAL" \ - $FLINT_CONFIGURE || sdh_die "Error: Failed to configure FLINT." - -sdh_make verbose - -echo "Deleting old FLINT files." -rm -f $SAGE_LOCAL/lib/libflint* -rm -rf $SAGE_LOCAL/include/flint - sdh_make_install diff --git a/build/pkgs/msolve/patches/0001-Make-msolve-build-with-flint3.patch b/build/pkgs/msolve/patches/0001-Make-msolve-build-with-flint3.patch new file mode 100644 index 00000000000..27a642a13b0 --- /dev/null +++ b/build/pkgs/msolve/patches/0001-Make-msolve-build-with-flint3.patch @@ -0,0 +1,53 @@ +From fe730579476de0b2d4181a38efa7f63dff9c81d7 Mon Sep 17 00:00:00 2001 +From: Marc Mezzarobba +Date: Tue, 12 Sep 2023 08:23:08 +0200 +Subject: [PATCH] Make msolve build with flint3 + +--- + src/fglm/berlekamp_massey.c | 3 +++ + src/fglm/data_fglm.c | 7 +++++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/fglm/berlekamp_massey.c b/src/fglm/berlekamp_massey.c +index b0f2052..998af1c 100644 +--- a/src/fglm/berlekamp_massey.c ++++ b/src/fglm/berlekamp_massey.c +@@ -30,6 +30,9 @@ + */ + + #include ++#if __FLINT_VERSION >= 3 ++# include ++#endif + //#include "nmod_poly.h" + //#include "mpn_extras.h" + +diff --git a/src/fglm/data_fglm.c b/src/fglm/data_fglm.c +index 0726760..0e1da6f 100644 +--- a/src/fglm/data_fglm.c ++++ b/src/fglm/data_fglm.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + + typedef uint32_t szmat_t; +@@ -299,9 +300,11 @@ static inline void nmod_poly_set_prime(nmod_poly_t poly, + mp_limb_t ninv = n_preinvert_limb(prime); + poly->mod.n = prime; + poly->mod.ninv = ninv; ++#if __FLINT_VERSION < 3 + count_leading_zeros(poly->mod.norm, prime); +- /* poly->mod.norm = flint_clz(prime); */ +- ++#else ++ poly->mod.norm = flint_clz(prime); ++#endif + } + + static inline void fglm_param_set_prime(param_t *param, mp_limb_t prime){ +-- +2.40.1 + diff --git a/build/pkgs/sagelib/dependencies b/build/pkgs/sagelib/dependencies index 5dc2efe1d31..fa6e98df7db 100644 --- a/build/pkgs/sagelib/dependencies +++ b/build/pkgs/sagelib/dependencies @@ -1,4 +1,4 @@ -FORCE $(SCRIPTS) arb boost_cropped $(BLAS) brial cliquer cypari cysignals cython ecl eclib ecm flint libgd gap giac givaro glpk gmpy2 gsl iml importlib_metadata importlib_resources jupyter_core lcalc lrcalc_python libbraiding libhomfly libpng linbox m4ri m4rie memory_allocator mpc mpfi mpfr $(MP_LIBRARY) ntl numpy pari pip pkgconfig planarity ppl pplpy primesieve primecount primecountpy pycygwin $(PYTHON) requests rw sage_conf singular symmetrica typing_extensions $(PCFILES) | $(PYTHON_TOOLCHAIN) sage_setup $(PYTHON) pythran +FORCE $(SCRIPTS) boost_cropped $(BLAS) brial cliquer cypari cysignals cython ecl eclib ecm flint libgd gap giac givaro glpk gmpy2 gsl iml importlib_metadata importlib_resources jupyter_core lcalc lrcalc_python libbraiding libhomfly libpng linbox m4ri m4rie memory_allocator mpc mpfi mpfr $(MP_LIBRARY) ntl numpy pari pip pkgconfig planarity ppl pplpy primesieve primecount primecountpy pycygwin $(PYTHON) requests rw sage_conf singular symmetrica typing_extensions $(PCFILES) | $(PYTHON_TOOLCHAIN) sage_setup $(PYTHON) pythran ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/symengine/dependencies b/build/pkgs/symengine/dependencies index 1fc34963eda..7795d486018 100644 --- a/build/pkgs/symengine/dependencies +++ b/build/pkgs/symengine/dependencies @@ -1,4 +1,4 @@ -$(MP_LIBRARY) arb ecm flint mpc mpfr | cmake +$(MP_LIBRARY) ecm flint mpc mpfr | cmake ---------- All lines of this file are ignored except the first. diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index bc34d35dd1c..4097d3512b9 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -777,7 +777,7 @@ class sage__rings__number_field(JoinFeature): A :class:`~sage.features.Feature` describing the presence of :mod:`sage.rings.number_field`. Number fields are implemented in Sage using a complicated mixture of various libraries, - including :ref:`arb `, :ref:`FLINT `, :ref:`GAP `, + including :ref:`FLINT `, :ref:`GAP `, :ref:`MPFI `, :ref:`NTL `, and :ref:`PARI `. EXAMPLES: From d0348c1f06724efd006db3d677bf310a14c4c2b5 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Mon, 9 Oct 2023 15:32:43 +0200 Subject: [PATCH 235/463] make sagelib build with flint3 --- pkgs/sage-conf/_sage_conf/_conf.py.in | 2 - src/sage/env.py | 6 +-- src/sage/libs/arb/acb.pxd | 2 +- src/sage/libs/arb/acb_calc.pxd | 2 +- src/sage/libs/arb/acb_elliptic.pxd | 2 +- src/sage/libs/arb/acb_hypgeom.pxd | 2 +- src/sage/libs/arb/acb_modular.pxd | 2 +- src/sage/libs/arb/acb_poly.pxd | 20 +------ src/sage/libs/arb/arb.pxd | 2 +- src/sage/libs/arb/arb_fmpz_poly.pxd | 3 +- src/sage/libs/arb/arb_hypgeom.pxd | 2 +- src/sage/libs/arb/arb_wrap.h | 26 ++++----- src/sage/libs/arb/arf.pxd | 4 +- src/sage/libs/arb/bernoulli.pxd | 2 +- src/sage/libs/arb/mag.pxd | 4 +- src/sage/libs/flint/flint_wrap.h | 1 + src/sage/libs/flint/fmpq.pxd | 2 + src/sage/libs/flint/fmpq_poly.pxd | 23 ++++---- src/sage/libs/flint/fmpq_poly.pyx | 45 ++++++++++++++++ src/sage/libs/flint/fmpz.pxd | 3 ++ src/sage/libs/flint/fmpz_mod_poly.pxd | 54 ------------------- src/sage/libs/flint/fmpz_poly.pxd | 16 +++--- src/sage/libs/flint/fmpz_poly.pyx | 43 ++++++++++++++- src/sage/libs/flint/fmpz_poly_q.pxd | 7 --- .../libs/linbox/linbox_flint_interface.pyx | 5 +- src/sage/matrix/matrix_complex_ball_dense.pyx | 2 +- src/sage/matrix/matrix_integer_sparse.pyx | 8 ++- .../polynomial/polynomial_rational_flint.pyx | 40 +++++++++----- src/sage/symbolic/ginac/inifcns_orthopoly.cpp | 5 +- src/sage/symbolic/ginac/useries.cpp | 50 ++++++++++++----- src/sage_setup/library_order.py | 7 +-- 31 files changed, 216 insertions(+), 176 deletions(-) create mode 100644 src/sage/libs/flint/fmpq_poly.pyx diff --git a/pkgs/sage-conf/_sage_conf/_conf.py.in b/pkgs/sage-conf/_sage_conf/_conf.py.in index 87b27ca05cb..895d6572d1e 100644 --- a/pkgs/sage-conf/_sage_conf/_conf.py.in +++ b/pkgs/sage-conf/_sage_conf/_conf.py.in @@ -19,8 +19,6 @@ MAXIMA_FAS = "@SAGE_MAXIMA_FAS@".replace('${prefix}', SAGE_LOCAL) # Delete this line if your ECL can load Kenzo without further prodding. KENZO_FAS = "@SAGE_KENZO_FAS@".replace('${prefix}', SAGE_LOCAL) -ARB_LIBRARY = "@SAGE_ARB_LIBRARY@" - NTL_INCDIR = "@NTL_INCDIR@" NTL_LIBDIR = "@NTL_LIBDIR@" diff --git a/src/sage/env.py b/src/sage/env.py index 4515e90e912..9ab6b1e1864 100644 --- a/src/sage/env.py +++ b/src/sage/env.py @@ -223,7 +223,6 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st FOURTITWO_PPI = var("FOURTITWO_PPI") FOURTITWO_CIRCUITS = var("FOURTITWO_CIRCUITS") FOURTITWO_GROEBNER = var("FOURTITWO_GROEBNER") -ARB_LIBRARY = var("ARB_LIBRARY", "arb") CBLAS_PC_MODULES = var("CBLAS_PC_MODULES", "cblas:openblas:blas") ECL_CONFIG = var("ECL_CONFIG", "ecl-config") NTL_INCDIR = var("NTL_INCDIR") @@ -356,8 +355,7 @@ def cython_aliases(required_modules=None, sage: cython_aliases() {...} sage: sorted(cython_aliases().keys()) - ['ARB_LIBRARY', - 'CBLAS_CFLAGS', + ['CBLAS_CFLAGS', ..., 'ZLIB_LIBRARIES'] sage: cython_aliases(required_modules=('module-that-is-assumed-to-not-exist')) @@ -475,8 +473,6 @@ def uname_specific(name, value, alternative): if "LINBOX_CFLAGS" in aliases: aliases["LINBOX_CFLAGS"].append("-std=gnu++11") - aliases["ARB_LIBRARY"] = ARB_LIBRARY - # TODO: Remove Cygwin hack by installing a suitable cblas.pc if os.path.exists('/usr/lib/libblas.dll.a'): aliases["CBLAS_LIBS"] = ['gslcblas'] diff --git a/src/sage/libs/arb/acb.pxd b/src/sage/libs/arb/acb.pxd index 5148dc43991..3f53b96d331 100644 --- a/src/sage/libs/arb/acb.pxd +++ b/src/sage/libs/arb/acb.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = acb.h from sage.libs.arb.types cimport * diff --git a/src/sage/libs/arb/acb_calc.pxd b/src/sage/libs/arb/acb_calc.pxd index a5dbf360b5e..67bd2ed57dc 100644 --- a/src/sage/libs/arb/acb_calc.pxd +++ b/src/sage/libs/arb/acb_calc.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = acb_calc.h from sage.libs.arb.types cimport * diff --git a/src/sage/libs/arb/acb_elliptic.pxd b/src/sage/libs/arb/acb_elliptic.pxd index 176f68df00e..e3480e9f73b 100644 --- a/src/sage/libs/arb/acb_elliptic.pxd +++ b/src/sage/libs/arb/acb_elliptic.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = acb_elliptic.h from sage.libs.arb.types cimport * diff --git a/src/sage/libs/arb/acb_hypgeom.pxd b/src/sage/libs/arb/acb_hypgeom.pxd index 418e766f10d..c43e5c0623b 100644 --- a/src/sage/libs/arb/acb_hypgeom.pxd +++ b/src/sage/libs/arb/acb_hypgeom.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = acb_hypgeom.h from sage.libs.arb.types cimport * diff --git a/src/sage/libs/arb/acb_modular.pxd b/src/sage/libs/arb/acb_modular.pxd index c708e9bf97d..cdc413c92da 100644 --- a/src/sage/libs/arb/acb_modular.pxd +++ b/src/sage/libs/arb/acb_modular.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = acb_modular.h from sage.libs.arb.types cimport * diff --git a/src/sage/libs/arb/acb_poly.pxd b/src/sage/libs/arb/acb_poly.pxd index 69f4320055b..ae02757ffd9 100644 --- a/src/sage/libs/arb/acb_poly.pxd +++ b/src/sage/libs/arb/acb_poly.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = acb_poly.h from sage.libs.arb.types cimport * @@ -79,24 +79,10 @@ cdef extern from "arb_wrap.h": void _acb_poly_divrem(acb_ptr Q, acb_ptr R, acb_srcptr A, long lenA, acb_srcptr B, long lenB, long prec) bint acb_poly_divrem(acb_poly_t Q, acb_poly_t R, const acb_poly_t A, const acb_poly_t B, long prec) void _acb_poly_div_root(acb_ptr Q, acb_t R, acb_srcptr A, long len, const acb_t c, long prec) - void _acb_poly_taylor_shift_horner(acb_ptr g, const acb_t c, long n, long prec) - void acb_poly_taylor_shift_horner(acb_poly_t g, const acb_poly_t f, const acb_t c, long prec) - void _acb_poly_taylor_shift_divconquer(acb_ptr g, const acb_t c, long n, long prec) - void acb_poly_taylor_shift_divconquer(acb_poly_t g, const acb_poly_t f, const acb_t c, long prec) - void _acb_poly_taylor_shift_convolution(acb_ptr g, const acb_t c, long n, long prec) - void acb_poly_taylor_shift_convolution(acb_poly_t g, const acb_poly_t f, const acb_t c, long prec) void _acb_poly_taylor_shift(acb_ptr g, const acb_t c, long n, long prec) void acb_poly_taylor_shift(acb_poly_t g, const acb_poly_t f, const acb_t c, long prec) - void _acb_poly_compose_horner(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long prec) - void acb_poly_compose_horner(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long prec) - void _acb_poly_compose_divconquer(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long prec) - void acb_poly_compose_divconquer(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long prec) void _acb_poly_compose(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long prec) void acb_poly_compose(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long prec) - void _acb_poly_compose_series_horner(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long n, long prec) - void acb_poly_compose_series_horner(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long n, long prec) - void _acb_poly_compose_series_brent_kung(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long n, long prec) - void acb_poly_compose_series_brent_kung(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long n, long prec) void _acb_poly_compose_series(acb_ptr res, acb_srcptr poly1, long len1, acb_srcptr poly2, long len2, long n, long prec) void acb_poly_compose_series(acb_poly_t res, const acb_poly_t poly1, const acb_poly_t poly2, long n, long prec) void _acb_poly_revert_series_lagrange(acb_ptr h, acb_srcptr f, long flen, long n, long prec) @@ -161,10 +147,6 @@ cdef extern from "arb_wrap.h": void acb_poly_exp_series_basecase(acb_poly_t f, const acb_poly_t h, long n, long prec) void _acb_poly_exp_series(acb_ptr f, acb_srcptr h, long hlen, long n, long prec) void acb_poly_exp_series(acb_poly_t f, const acb_poly_t h, long n, long prec) - void _acb_poly_sin_cos_series_basecase(acb_ptr s, acb_ptr c, acb_srcptr h, long hlen, long n, long prec, int times_pi) - void acb_poly_sin_cos_series_basecase(acb_poly_t s, acb_poly_t c, const acb_poly_t h, long n, long prec, int times_pi) - void _acb_poly_sin_cos_series_tangent(acb_ptr s, acb_ptr c, acb_srcptr h, long hlen, long n, long prec, int times_pi) - void acb_poly_sin_cos_series_tangent(acb_poly_t s, acb_poly_t c, const acb_poly_t h, long n, long prec, int times_pi) void _acb_poly_sin_cos_series(acb_ptr s, acb_ptr c, acb_srcptr h, long hlen, long n, long prec) void acb_poly_sin_cos_series(acb_poly_t s, acb_poly_t c, const acb_poly_t h, long n, long prec) void _acb_poly_sin_series(acb_ptr s, acb_srcptr h, long hlen, long n, long prec) diff --git a/src/sage/libs/arb/arb.pxd b/src/sage/libs/arb/arb.pxd index c82b94de30f..33083fc125f 100644 --- a/src/sage/libs/arb/arb.pxd +++ b/src/sage/libs/arb/arb.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = arb.h from sage.libs.arb.types cimport * diff --git a/src/sage/libs/arb/arb_fmpz_poly.pxd b/src/sage/libs/arb/arb_fmpz_poly.pxd index 079f76e9d9e..55daa705238 100644 --- a/src/sage/libs/arb/arb_fmpz_poly.pxd +++ b/src/sage/libs/arb/arb_fmpz_poly.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = arb_fmpz_poly.h from sage.libs.arb.types cimport * @@ -22,5 +22,4 @@ cdef extern from "arb_wrap.h": unsigned long arb_fmpz_poly_deflation(const fmpz_poly_t poly) void arb_fmpz_poly_deflate(fmpz_poly_t res, const fmpz_poly_t poly, unsigned long deflation) void arb_fmpz_poly_complex_roots(acb_ptr roots, const fmpz_poly_t poly, int flags, long prec) - void arb_fmpz_poly_cos_minpoly(fmpz_poly_t res, unsigned long n) void arb_fmpz_poly_gauss_period_minpoly(fmpz_poly_t res, unsigned long q, unsigned long n) diff --git a/src/sage/libs/arb/arb_hypgeom.pxd b/src/sage/libs/arb/arb_hypgeom.pxd index fb1c40ddaa8..139b987d669 100644 --- a/src/sage/libs/arb/arb_hypgeom.pxd +++ b/src/sage/libs/arb/arb_hypgeom.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = arb_hypgeom.h from sage.libs.flint.types cimport fmpz_t diff --git a/src/sage/libs/arb/arb_wrap.h b/src/sage/libs/arb/arb_wrap.h index 49997075ee5..f51c89ffe38 100644 --- a/src/sage/libs/arb/arb_wrap.h +++ b/src/sage/libs/arb/arb_wrap.h @@ -11,19 +11,19 @@ #define ulong mp_limb_t #define slong mp_limb_signed_t -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #undef ulong #undef slong diff --git a/src/sage/libs/arb/arf.pxd b/src/sage/libs/arb/arf.pxd index b8b83fefcdc..84778fe9f09 100644 --- a/src/sage/libs/arb/arf.pxd +++ b/src/sage/libs/arb/arf.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = arf.h from sage.libs.arb.types cimport * @@ -30,7 +30,6 @@ cdef extern from "arb_wrap.h": void arf_set_ui(arf_t y, unsigned long x) void arf_set_si(arf_t y, long x) void arf_set_mpfr(arf_t y, const mpfr_t x) - # void arf_set_fmpr(arf_t y, const fmpr_t x) void arf_set_d(arf_t y, double x) void arf_swap(arf_t y, arf_t x) void arf_init_set_ui(arf_t y, unsigned long x) @@ -46,7 +45,6 @@ cdef extern from "arb_wrap.h": int arf_set_round_fmpz_2exp(arf_t y, const fmpz_t x, const fmpz_t e, long prec, arf_rnd_t rnd) void arf_get_fmpz_2exp(fmpz_t m, fmpz_t e, const arf_t x) double arf_get_d(const arf_t x, arf_rnd_t rnd) - # void arf_get_fmpr(fmpr_t y, const arf_t x) int arf_get_mpfr(mpfr_t y, const arf_t x, mpfr_rnd_t rnd) void arf_get_fmpz(fmpz_t z, const arf_t x, arf_rnd_t rnd) long arf_get_si(const arf_t x, arf_rnd_t rnd) diff --git a/src/sage/libs/arb/bernoulli.pxd b/src/sage/libs/arb/bernoulli.pxd index f859ebfb8d7..95a84dd5179 100644 --- a/src/sage/libs/arb/bernoulli.pxd +++ b/src/sage/libs/arb/bernoulli.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = bernoulli.h from sage.libs.flint.types cimport fmpq_t, ulong diff --git a/src/sage/libs/arb/mag.pxd b/src/sage/libs/arb/mag.pxd index d5d8693ea8f..69dfb990ae0 100644 --- a/src/sage/libs/arb/mag.pxd +++ b/src/sage/libs/arb/mag.pxd @@ -1,4 +1,4 @@ -# distutils: libraries = gmp flint ARB_LIBRARY +# distutils: libraries = gmp flint # distutils: depends = mag.h from sage.libs.arb.types cimport * @@ -27,13 +27,11 @@ cdef extern from "arb_wrap.h": # void mag_randtest(mag_t x, flint_rand_t state, long expbits) # void mag_randtest_special(mag_t x, flint_rand_t state, long expbits) void mag_set_d(mag_t y, double x) - # void mag_set_fmpr(mag_t y, const fmpr_t x) void mag_set_ui(mag_t y, unsigned long x) void mag_set_fmpz(mag_t y, const fmpz_t x) void mag_set_d_2exp_fmpz(mag_t z, double x, const fmpz_t y) void mag_set_fmpz_2exp_fmpz(mag_t z, const fmpz_t x, const fmpz_t y) void mag_set_ui_2exp_si(mag_t z, unsigned long x, long y) - # void mag_get_fmpr(fmpr_t y, const mag_t x) void mag_get_fmpq(fmpq_t y, const mag_t x) void mag_set_ui_lower(mag_t z, unsigned long x) void mag_set_fmpz_lower(mag_t z, const fmpz_t x) diff --git a/src/sage/libs/flint/flint_wrap.h b/src/sage/libs/flint/flint_wrap.h index 266535c3835..a416d5b53db 100644 --- a/src/sage/libs/flint/flint_wrap.h +++ b/src/sage/libs/flint/flint_wrap.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include diff --git a/src/sage/libs/flint/fmpq.pxd b/src/sage/libs/flint/fmpq.pxd index 5e64c82102f..0616c0a7408 100644 --- a/src/sage/libs/flint/fmpq.pxd +++ b/src/sage/libs/flint/fmpq.pxd @@ -12,6 +12,8 @@ cdef extern from "flint_wrap.h": fmpz * fmpq_denref(fmpq_t) void fmpq_init(fmpq_t) void fmpq_clear(fmpq_t) + void fmpq_init_set_readonly(fmpq_t, const mpq_t) + void fmpq_clear_readonly(fmpq_t) void fmpq_one(fmpq_t) void fmpq_zero(fmpq_t) bint fmpq_is_zero(fmpq_t) diff --git a/src/sage/libs/flint/fmpq_poly.pxd b/src/sage/libs/flint/fmpq_poly.pxd index 6050c487835..afa16e5bbdd 100644 --- a/src/sage/libs/flint/fmpq_poly.pxd +++ b/src/sage/libs/flint/fmpq_poly.pxd @@ -30,6 +30,9 @@ cdef extern from "flint_wrap.h": void fmpq_poly_canonicalise(fmpq_poly_t) int fmpq_poly_is_canonical(const fmpq_poly_t) + void _fmpq_poly_set_length(fmpq_poly_t, slong) + void _fmpq_poly_normalise(fmpq_poly_t) + # Polynomial parameters slong fmpq_poly_degree(const fmpq_poly_t) ulong fmpq_poly_length(const fmpq_poly_t) @@ -46,10 +49,7 @@ cdef extern from "flint_wrap.h": void fmpq_poly_set_ui(fmpq_poly_t, ulong) void fmpq_poly_set_fmpz(fmpq_poly_t, const fmpz_t) void fmpq_poly_set_fmpq(fmpq_poly_t, const fmpq_t) - void fmpq_poly_set_mpz(fmpq_poly_t, const mpz_t) - void fmpq_poly_set_mpq(fmpq_poly_t, const mpq_t) void fmpq_poly_set_fmpz_poly(fmpq_poly_t, const fmpz_poly_t) - void fmpq_poly_set_array_mpq(fmpq_poly_t, const mpq_t *, slong) void fmpq_poly_set_str(fmpq_poly_t, const char *) char *fmpq_poly_get_str(const fmpq_poly_t) @@ -67,7 +67,6 @@ cdef extern from "flint_wrap.h": void fmpq_poly_reverse(fmpq_poly_t, const fmpq_poly_t, slong) void fmpq_poly_get_coeff_fmpq(fmpq_t, const fmpq_poly_t, slong) - void fmpq_poly_get_coeff_mpq(mpq_t, const fmpq_poly_t, slong) void fmpq_poly_get_coeff_si(slong, const fmpq_poly_t, slong) void fmpq_poly_get_coeff_ui(ulong, const fmpq_poly_t, slong) @@ -75,8 +74,6 @@ cdef extern from "flint_wrap.h": void fmpq_poly_set_coeff_ui(fmpq_poly_t, slong, ulong) void fmpq_poly_set_coeff_fmpz(fmpq_poly_t, slong, const fmpz_t) void fmpq_poly_set_coeff_fmpq(fmpq_poly_t, slong, const fmpq_t) - void fmpq_poly_set_coeff_mpz(fmpq_poly_t, slong, const mpz_t) - void fmpq_poly_set_coeff_mpq(fmpq_poly_t, slong, const mpq_t) # Comparison int fmpq_poly_equal(const fmpq_poly_t, const fmpq_poly_t) @@ -100,8 +97,6 @@ cdef extern from "flint_wrap.h": fmpq_poly_t, const fmpq_poly_t, const fmpz_t) void fmpq_poly_scalar_mul_fmpq( fmpq_poly_t, const fmpq_poly_t, const fmpq_t) - void fmpq_poly_scalar_mul_mpz(fmpq_poly_t, const fmpq_poly_t, const mpz_t) - void fmpq_poly_scalar_mul_mpq(fmpq_poly_t, const fmpq_poly_t, const mpq_t) void fmpq_poly_scalar_div_si(fmpq_poly_t, const fmpq_poly_t, slong) void fmpq_poly_scalar_div_ui(fmpq_poly_t, const fmpq_poly_t, ulong) @@ -109,8 +104,6 @@ cdef extern from "flint_wrap.h": fmpq_poly_t, const fmpq_poly_t, const fmpz_t) void fmpq_poly_scalar_div_fmpq( fmpq_poly_t, const fmpq_poly_t, const fmpq_t) - void fmpq_poly_scalar_div_mpz(fmpq_poly_t, const fmpq_poly_t, const mpz_t) - void fmpq_poly_scalar_div_mpq(fmpq_poly_t, const fmpq_poly_t, const mpq_t) # Multiplication void fmpq_poly_mul(fmpq_poly_t, const fmpq_poly_t, const fmpq_poly_t) @@ -155,8 +148,6 @@ cdef extern from "flint_wrap.h": # Evaluation void fmpq_poly_evaluate_fmpz(fmpq_t, const fmpq_poly_t, const fmpz_t) void fmpq_poly_evaluate_fmpq(fmpq_t, const fmpq_poly_t, const fmpq_t) - void fmpq_poly_evaluate_mpz(mpq_t, const fmpq_poly_t, const mpz_t) - void fmpq_poly_evaluate_mpq(mpq_t, const fmpq_poly_t, const mpq_t) # Composition void fmpq_poly_compose(fmpq_poly_t, const fmpq_poly_t, const fmpq_poly_t) @@ -189,3 +180,11 @@ cdef extern from "flint_wrap.h": # since the fmpq_poly header seems to be lacking this inline function cdef inline sage_fmpq_poly_max_limbs(const fmpq_poly_t poly) noexcept: return _fmpz_vec_max_limbs(fmpq_poly_numref(poly), fmpq_poly_length(poly)) + +# functions removed from flint but still needed in sage +cdef void fmpq_poly_scalar_mul_mpz(fmpq_poly_t, const fmpq_poly_t, const mpz_t) +cdef void fmpq_poly_scalar_mul_mpq(fmpq_poly_t, const fmpq_poly_t, const mpq_t) +cdef void fmpq_poly_set_coeff_mpq(fmpq_poly_t, slong, const mpq_t) +cdef void fmpq_poly_get_coeff_mpq(mpq_t, const fmpq_poly_t, slong) +cdef void fmpq_poly_set_mpz(fmpq_poly_t, const mpz_t) +cdef void fmpq_poly_set_mpq(fmpq_poly_t, const mpq_t) diff --git a/src/sage/libs/flint/fmpq_poly.pyx b/src/sage/libs/flint/fmpq_poly.pyx new file mode 100644 index 00000000000..3b8a0cf0c51 --- /dev/null +++ b/src/sage/libs/flint/fmpq_poly.pyx @@ -0,0 +1,45 @@ +# Functions removed from flint but still needed in Sage. Code adapted from +# earlier versions of flint. + +from sage.libs.gmp.mpq cimport * +from sage.libs.flint.fmpz cimport * +from sage.libs.flint.fmpq cimport * + +cdef void fmpq_poly_scalar_mul_mpz(fmpq_poly_t rop, const fmpq_poly_t op, const mpz_t c): + cdef fmpz_t f + fmpz_init_set_readonly(f, c) + fmpq_poly_scalar_mul_fmpz(rop, op, f) + fmpz_clear_readonly(f) + +cdef void fmpq_poly_scalar_mul_mpq(fmpq_poly_t rop, const fmpq_poly_t op, const mpq_t c): + cdef fmpq_t f + fmpq_init_set_readonly(f, c) + fmpq_poly_scalar_mul_fmpq(rop, op, f) + fmpq_clear_readonly(f) + +cdef void fmpq_poly_set_coeff_mpq(fmpq_poly_t poly, slong n, const mpq_t x): + cdef fmpq_t t + fmpq_init_set_readonly(t, x) + fmpq_poly_set_coeff_fmpq(poly, n, t) + fmpq_clear_readonly(t) + +cdef void fmpq_poly_get_coeff_mpq(mpq_t x, const fmpq_poly_t poly, slong n): + cdef fmpq_t t + fmpq_init(t) + fmpq_poly_get_coeff_fmpq(t, poly, n) + fmpq_get_mpq(x, t) + fmpq_clear(t) + +cdef void fmpq_poly_set_mpq(fmpq_poly_t poly, const mpq_t x): + fmpq_poly_fit_length(poly, 1) + fmpz_set_mpz(fmpq_poly_numref(poly), mpq_numref(x)) + fmpz_set_mpz(fmpq_poly_denref(poly), mpq_denref(x)) + _fmpq_poly_set_length(poly, 1) + _fmpq_poly_normalise(poly) + +cdef void fmpq_poly_set_mpz(fmpq_poly_t poly, const mpz_t x): + fmpq_poly_fit_length(poly, 1) + fmpz_set_mpz(fmpq_poly_numref(poly), x) + fmpz_one(fmpq_poly_denref(poly)) + _fmpq_poly_set_length(poly, 1) + _fmpq_poly_normalise(poly) diff --git a/src/sage/libs/flint/fmpz.pxd b/src/sage/libs/flint/fmpz.pxd index 01058d0f130..b97fbe1eae0 100644 --- a/src/sage/libs/flint/fmpz.pxd +++ b/src/sage/libs/flint/fmpz.pxd @@ -16,6 +16,9 @@ cdef extern from "flint_wrap.h": void fmpz_init_set(fmpz_t, fmpz_t) void fmpz_init_set_ui(fmpz_t, ulong) + void fmpz_init_set_readonly(fmpz_t, const mpz_t) + void fmpz_clear_readonly(fmpz_t) + # Conversion void fmpz_set(fmpz_t f, fmpz_t g) void fmpz_set_ui(fmpz_t, ulong) diff --git a/src/sage/libs/flint/fmpz_mod_poly.pxd b/src/sage/libs/flint/fmpz_mod_poly.pxd index 24b653eb3b7..2727246da98 100644 --- a/src/sage/libs/flint/fmpz_mod_poly.pxd +++ b/src/sage/libs/flint/fmpz_mod_poly.pxd @@ -67,13 +67,6 @@ cdef extern from "flint_wrap.h": void fmpz_mod_poly_get_coeff_fmpz(fmpz_t x, const fmpz_mod_poly_t poly, slong n, const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_set_coeff_mpz(fmpz_mod_poly_t poly, - slong n, const mpz_t x, const fmpz_mod_ctx_t ctx) - - void fmpz_mod_poly_get_coeff_mpz(mpz_t x, - const fmpz_mod_poly_t poly, slong n, const fmpz_mod_ctx_t ctx) - - void _fmpz_mod_poly_shift_left(fmpz * res, const fmpz * poly, slong len, slong n) @@ -194,14 +187,6 @@ cdef extern from "flint_wrap.h": const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_div_basecase(fmpz_mod_poly_t Q, - const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_ctx_t ctx) - - void fmpz_mod_poly_div_newton_n_preinv(fmpz_mod_poly_t Q, - const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_poly_t Binv, const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_divrem_newton_n_preinv(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_poly_t Binv, const fmpz_mod_ctx_t ctx) @@ -213,10 +198,6 @@ cdef extern from "flint_wrap.h": const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_divrem_divconquer(fmpz_mod_poly_t Q, - fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_divrem(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_ctx_t ctx) @@ -254,40 +235,13 @@ cdef extern from "flint_wrap.h": void fmpz_mod_poly_make_monic_f(fmpz_t f, fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_gcd_euclidean(fmpz_mod_poly_t G, - const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_ctx_t ctx) - - void fmpz_mod_poly_gcd_euclidean_f(fmpz_t f, fmpz_mod_poly_t G, - const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_gcd_f(fmpz_t f, fmpz_mod_poly_t G, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_gcd_hgcd(fmpz_mod_poly_t G, - const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_ctx_t ctx) - - void fmpz_mod_poly_gcd(fmpz_mod_poly_t G, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_xgcd_euclidean(fmpz_mod_poly_t G, - fmpz_mod_poly_t S, fmpz_mod_poly_t T, - const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_ctx_t ctx) - - void fmpz_mod_poly_xgcd_euclidean_f(fmpz_t f, fmpz_mod_poly_t G, - fmpz_mod_poly_t S, fmpz_mod_poly_t T, - const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_ctx_t ctx) - - void fmpz_mod_poly_xgcd_hgcd(fmpz_mod_poly_t G, fmpz_mod_poly_t S, - fmpz_mod_poly_t T, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, - const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_xgcd(fmpz_mod_poly_t G, fmpz_mod_poly_t S, fmpz_mod_poly_t T, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_ctx_t ctx) @@ -361,14 +315,6 @@ cdef extern from "flint_wrap.h": const fmpz_mod_poly_t poly, const fmpz * xs, slong n, const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_compose_horner(fmpz_mod_poly_t res, - const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, - const fmpz_mod_ctx_t ctx) - - void fmpz_mod_poly_compose_divconquer(fmpz_mod_poly_t res, - const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, - const fmpz_mod_ctx_t ctx) - void fmpz_mod_poly_compose(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, const fmpz_mod_ctx_t ctx) diff --git a/src/sage/libs/flint/fmpz_poly.pxd b/src/sage/libs/flint/fmpz_poly.pxd index 18b36672d30..c8bc6d3ca0a 100644 --- a/src/sage/libs/flint/fmpz_poly.pxd +++ b/src/sage/libs/flint/fmpz_poly.pxd @@ -28,7 +28,6 @@ cdef extern from "flint_wrap.h": void fmpz_poly_set_ui(fmpz_poly_t, ulong) void fmpz_poly_set_si(fmpz_poly_t, slong) void fmpz_poly_set_fmpz(fmpz_poly_t, const fmpz_t) - void fmpz_poly_set_mpz(fmpz_poly_t, const mpz_t) int fmpz_poly_set_str(fmpz_poly_t, const char *) char *fmpz_poly_get_str(const fmpz_poly_t) @@ -70,7 +69,6 @@ cdef extern from "flint_wrap.h": # Scalar multiplication and division void fmpz_poly_scalar_mul_fmpz( fmpz_poly_t, const fmpz_poly_t, const fmpz_t) - void fmpz_poly_scalar_mul_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) void fmpz_poly_scalar_mul_si(fmpz_poly_t, const fmpz_poly_t, slong) void fmpz_poly_scalar_mul_ui(fmpz_poly_t, const fmpz_poly_t, ulong) void fmpz_poly_scalar_mul_2exp(fmpz_poly_t, const fmpz_poly_t, ulong) @@ -310,12 +308,14 @@ cdef extern from "flint_wrap.h": fmpz_poly_t, const fmpz_poly_t, const fmpz_t, const nmod_poly_t, int) - # Some functions for backwards compatibility - void fmpz_poly_scalar_mul_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) - void fmpz_poly_scalar_divexact_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) - void fmpz_poly_scalar_fdiv_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) - void fmpz_poly_set_coeff_mpz(fmpz_poly_t, slong, const mpz_t) - void fmpz_poly_get_coeff_mpz(mpz_t, const fmpz_poly_t, slong) + +# functions removed from flint but still needed in sage +cdef void fmpz_poly_scalar_mul_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) +cdef void fmpz_poly_scalar_divexact_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) +cdef void fmpz_poly_scalar_fdiv_mpz(fmpz_poly_t, const fmpz_poly_t, const mpz_t) +cdef void fmpz_poly_set_coeff_mpz(fmpz_poly_t, slong, const mpz_t) +cdef void fmpz_poly_get_coeff_mpz(mpz_t, const fmpz_poly_t, slong) +cdef void fmpz_poly_set_mpz(fmpz_poly_t, const mpz_t) # Wrapper Cython class diff --git a/src/sage/libs/flint/fmpz_poly.pyx b/src/sage/libs/flint/fmpz_poly.pyx index 74915b37612..cfcbea9090c 100644 --- a/src/sage/libs/flint/fmpz_poly.pyx +++ b/src/sage/libs/flint/fmpz_poly.pyx @@ -25,10 +25,10 @@ from cysignals.memory cimport sig_free from sage.arith.long cimport pyobject_to_long from sage.cpython.string cimport char_to_str, str_to_bytes +from sage.libs.flint.fmpz cimport * from sage.structure.sage_object cimport SageObject from sage.rings.integer cimport Integer - cdef class Fmpz_poly(SageObject): def __cinit__(self): @@ -455,3 +455,44 @@ cdef class Fmpz_poly(SageObject): """ from sage.rings.integer_ring import ZZ return ZZ[var](self.list()) + + +# Functions removed from flint but still needed in Sage. Code adapted from +# earlier versions of flint. + +cdef void fmpz_poly_scalar_mul_mpz(fmpz_poly_t rop, const fmpz_poly_t op, const mpz_t c): + cdef fmpz_t f + fmpz_init_set_readonly(f, c) + fmpz_poly_scalar_mul_fmpz(rop, op, f) + fmpz_clear_readonly(f) + +cdef void fmpz_poly_scalar_divexact_mpz(fmpz_poly_t rop, const fmpz_poly_t op, const mpz_t c): + cdef fmpz_t f + fmpz_init_set_readonly(f, c) + fmpz_poly_scalar_divexact_fmpz(rop, op, f) + fmpz_clear_readonly(f) + +cdef void fmpz_poly_scalar_fdiv_mpz(fmpz_poly_t rop, const fmpz_poly_t op, const mpz_t c): + cdef fmpz_t f + fmpz_init_set_readonly(f, c) + fmpz_poly_scalar_fdiv_fmpz(rop, op, f) + fmpz_clear_readonly(f) + +cdef void fmpz_poly_set_coeff_mpz(fmpz_poly_t poly, slong n, const mpz_t x): + cdef fmpz_t t + fmpz_init_set_readonly(t, x) + fmpz_poly_set_coeff_fmpz(poly, n, t) + fmpz_clear_readonly(t) + +cdef void fmpz_poly_get_coeff_mpz(mpz_t x, const fmpz_poly_t poly, slong n): + cdef fmpz_t t + fmpz_init(t) + fmpz_poly_get_coeff_fmpz(t, poly, n) + fmpz_get_mpz(x, t) + fmpz_clear(t) + +cdef void fmpz_poly_set_mpz(fmpz_poly_t poly, const mpz_t x): + fmpz_poly_fit_length(poly, 1) + fmpz_set_mpz(poly.coeffs, x) + _fmpz_poly_set_length(poly, 1) + _fmpz_poly_normalise(poly) diff --git a/src/sage/libs/flint/fmpz_poly_q.pxd b/src/sage/libs/flint/fmpz_poly_q.pxd index 846542dc0d8..63c13355bf6 100644 --- a/src/sage/libs/flint/fmpz_poly_q.pxd +++ b/src/sage/libs/flint/fmpz_poly_q.pxd @@ -49,11 +49,7 @@ cdef extern from "flint_wrap.h": #* Scalar multiplication and division ****************************************/ void fmpz_poly_q_scalar_mul_si(fmpz_poly_q_t rop, const fmpz_poly_q_t op, long x) - void fmpz_poly_q_scalar_mul_mpz(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpz_t x) - void fmpz_poly_q_scalar_mul_mpq(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpq_t x) void fmpz_poly_q_scalar_div_si(fmpz_poly_q_t rop, const fmpz_poly_q_t op, long x) - void fmpz_poly_q_scalar_div_mpz(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpz_t x) - void fmpz_poly_q_scalar_div_mpq(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpq_t x) #* Multiplication and division ***********************************************/ void fmpz_poly_q_mul(fmpz_poly_q_t rop, @@ -67,9 +63,6 @@ cdef extern from "flint_wrap.h": #* Derivative ****************************************************************/ void fmpz_poly_q_derivative(fmpz_poly_q_t rop, const fmpz_poly_q_t op) - #* Evaluation ****************************************************************/ - int fmpz_poly_q_evaluate(mpq_t rop, const fmpz_poly_q_t f, const mpq_t a) - #* Input and output **********************************************************/ int fmpz_poly_q_set_str(fmpz_poly_q_t rop, const char *s) char * fmpz_poly_q_get_str(const fmpz_poly_q_t op) diff --git a/src/sage/libs/linbox/linbox_flint_interface.pyx b/src/sage/libs/linbox/linbox_flint_interface.pyx index 1979ac0f0a4..37a340c457f 100644 --- a/src/sage/libs/linbox/linbox_flint_interface.pyx +++ b/src/sage/libs/linbox/linbox_flint_interface.pyx @@ -33,6 +33,7 @@ and C. Pernet. The functions available are: # https://www.gnu.org/licenses/ # **************************************************************************** +from sage.libs.gmp.types cimport mpz_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 @@ -80,11 +81,13 @@ cdef void fmpz_poly_set_linbox(fmpz_poly_t p, PolynomialRing_integer.Element& q) (the .pxd file) in order to keep the header C-compatible """ cdef size_t i + cdef mpz_t tmp fmpz_poly_fit_length(p, q.size()) for i in range(q.size()): - fmpz_poly_set_coeff_mpz(p, i, q[i].get_mpz_const()) + tmp = q[i].get_mpz_const() + fmpz_poly_set_coeff_mpz(p, i, tmp) _fmpz_poly_set_length(p, q.size()) diff --git a/src/sage/matrix/matrix_complex_ball_dense.pyx b/src/sage/matrix/matrix_complex_ball_dense.pyx index e5414abdd9e..2f0131f4064 100644 --- a/src/sage/matrix/matrix_complex_ball_dense.pyx +++ b/src/sage/matrix/matrix_complex_ball_dense.pyx @@ -1,4 +1,4 @@ -# distutils: libraries = ARB_LIBRARY +# distutils: libraries = flint r""" Arbitrary precision complex ball matrices using Arb diff --git a/src/sage/matrix/matrix_integer_sparse.pyx b/src/sage/matrix/matrix_integer_sparse.pyx index 27f5cdfac0f..6c5c20dbc6b 100644 --- a/src/sage/matrix/matrix_integer_sparse.pyx +++ b/src/sage/matrix/matrix_integer_sparse.pyx @@ -847,6 +847,7 @@ cdef class Matrix_integer_sparse(Matrix_sparse): sage: matrix(ZZ, 1, 1, sparse=True)._charpoly_linbox() x """ + cdef mpz_t tmp if self._nrows != self._ncols: raise ArithmeticError('only valid for square matrix') @@ -869,7 +870,8 @@ cdef class Matrix_integer_sparse(Matrix_sparse): cdef size_t i fmpz_poly_fit_length(g._poly, p.size()) for i in range(p.size()): - fmpz_poly_set_coeff_mpz(g._poly, i, p[0][i].get_mpz_const()) + tmp = p[0][i].get_mpz_const() + fmpz_poly_set_coeff_mpz(g._poly, i, tmp) _fmpz_poly_set_length(g._poly, p.size()) del M @@ -966,9 +968,11 @@ cdef class Matrix_integer_sparse(Matrix_sparse): sig_off() cdef size_t i + cdef mpz_t tmp fmpz_poly_fit_length(g._poly, p.size()) for i in range(p.size()): - fmpz_poly_set_coeff_mpz(g._poly, i, p[0][i].get_mpz_const()) + tmp = p[0][i].get_mpz_const() + fmpz_poly_set_coeff_mpz(g._poly, i, tmp) _fmpz_poly_set_length(g._poly, p.size()) del M diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx index 04eaefc9fed..d99f0d3b98c 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx @@ -222,7 +222,7 @@ cdef class Polynomial_rational_flint(Polynomial): cdef unsigned long n cdef Rational c cdef list L1 - cdef mpq_t * L2 + cdef fmpq_t q Polynomial.__init__(self, parent, is_gen=is_gen) @@ -253,14 +253,11 @@ cdef class Polynomial_rational_flint(Polynomial): L1 = [e if isinstance(e, Rational) else Rational(e) for e in x] n = len(x) sig_on() - L2 = check_allocarray(n, sizeof(mpq_t)) + fmpq_poly_fit_length(self._poly, n) for deg from 0 <= deg < n: - mpq_init(L2[deg]) - mpq_set(L2[deg], ( L1[deg]).value) - fmpq_poly_set_array_mpq(self._poly, L2, n) - for deg from 0 <= deg < n: - mpq_clear(L2[deg]) - sig_free(L2) + fmpq_init_set_readonly(q, ( L1[deg]).value) + fmpq_poly_set_coeff_fmpq(self._poly, deg, q) + fmpq_clear_readonly(q) sig_off() # deg = 0 @@ -435,6 +432,7 @@ cdef class Polynomial_rational_flint(Polynomial): utmost care. """ cdef bint do_sig = _do_sig(self._poly) + cdef fmpz_t tmpfz if isinstance(value, int): if do_sig: sig_str("FLINT exception") @@ -442,7 +440,9 @@ cdef class Polynomial_rational_flint(Polynomial): if do_sig: sig_off() elif isinstance(value, Integer): if do_sig: sig_str("FLINT exception") - fmpq_poly_set_coeff_mpz(self._poly, n, ( value).value) + fmpz_init_set_readonly(tmpfz, ( value).value) + fmpq_poly_set_coeff_fmpz(self._poly, n, tmpfz) + fmpz_clear_readonly(tmpfz) if do_sig: sig_off() elif isinstance(value, Rational): if do_sig: sig_str("FLINT exception") @@ -492,7 +492,7 @@ cdef class Polynomial_rational_flint(Polynomial): cdef Polynomial_rational_flint f cdef Rational r cdef fmpz_t tmpfz - cdef fmpq_t tmpfq + cdef fmpq_t tmpfq, tmpfq1 cdef RealBall arb_a, arb_z cdef ComplexBall acb_a, acb_z @@ -508,13 +508,23 @@ cdef class Polynomial_rational_flint(Polynomial): elif isinstance(a, Rational): r = Rational.__new__(Rational) sig_str("FLINT exception") - fmpq_poly_evaluate_mpq(r.value, self._poly, ( a).value) + fmpq_init_set_readonly(tmpfq, ( a).value) + fmpq_init(tmpfq1) + fmpq_poly_evaluate_fmpq(tmpfq1, self._poly, tmpfq) + fmpq_get_mpq(r.value, tmpfq1) + fmpq_clear(tmpfq1) + fmpq_clear_readonly(tmpfq) sig_off() return r elif isinstance(a, Integer): r = Rational.__new__(Rational) sig_str("FLINT exception") - fmpq_poly_evaluate_mpz(r.value, self._poly, ( a).value) + fmpz_init_set_readonly(tmpfz, ( a).value) + fmpq_init(tmpfq) + fmpq_poly_evaluate_fmpz(tmpfq, self._poly, tmpfz) + fmpq_get_mpq(r.value, tmpfq) + fmpq_clear(tmpfq) + fmpz_clear_readonly(tmpfz) sig_off() return r elif isinstance(a, int): @@ -1321,6 +1331,7 @@ cdef class Polynomial_rational_flint(Polynomial): """ cdef Polynomial_rational_flint res cdef bint do_sig + cdef fmpq_t tmpfq if right == 0: raise ZeroDivisionError("division by zero polynomial") @@ -1331,8 +1342,9 @@ cdef class Polynomial_rational_flint(Polynomial): do_sig = _do_sig(self._poly) if do_sig: sig_str("FLINT exception") - fmpq_poly_scalar_div_mpq(res._poly, self._poly, - ( QQ(right)).value) + fmpq_init_set_readonly(tmpfq, ( QQ(right)).value) + fmpq_poly_scalar_div_fmpq(res._poly, self._poly, tmpfq) + fmpq_clear_readonly(tmpfq) if do_sig: sig_off() return res diff --git a/src/sage/symbolic/ginac/inifcns_orthopoly.cpp b/src/sage/symbolic/ginac/inifcns_orthopoly.cpp index a591cb4cd7c..a90f2050c59 100644 --- a/src/sage/symbolic/ginac/inifcns_orthopoly.cpp +++ b/src/sage/symbolic/ginac/inifcns_orthopoly.cpp @@ -20,6 +20,7 @@ #include "utils.h" #include "gmp.h" +#include "flint/fmpz_poly.h" #include "flint/fmpq_poly.h" #include "flint/fmpq.h" @@ -63,7 +64,7 @@ static ex chebyt_eval(const ex& n_, const ex& x) for (int i = 0; i Date: Tue, 4 Jul 2023 11:23:26 +0200 Subject: [PATCH 236/463] test that #20003 is fixed --- .../polynomial/polynomial_zmod_flint.pyx | 5 +++ .../con_rational_function_field.py | 42 +++++-------------- 2 files changed, 15 insertions(+), 32 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx index 6e7f7498329..3a66198d568 100644 --- a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx @@ -658,6 +658,11 @@ cdef class Polynomial_zmod_flint(Polynomial_template): ... NotImplementedError: square free factorization of polynomials over rings with composite characteristic is not implemented + :trac:`20003`:: + + sage: P. = GF(7)[] + sage: (6*x+3).squarefree_decomposition() + (6) * (x + 4) """ if not self.base_ring().is_field(): raise NotImplementedError("square free factorization of polynomials over rings with composite characteristic is not implemented") diff --git a/src/sage/schemes/plane_conics/con_rational_function_field.py b/src/sage/schemes/plane_conics/con_rational_function_field.py index 05d24e78a85..581102b5c5b 100644 --- a/src/sage/schemes/plane_conics/con_rational_function_field.py +++ b/src/sage/schemes/plane_conics/con_rational_function_field.py @@ -198,38 +198,6 @@ def has_rational_point(self, point=False, algorithm='default', Fraction Field of Univariate Polynomial Ring in u over Rational Field with modulus v^2 - u^3 - 1 - ``has_rational_point`` fails for some conics over function fields - over finite fields, due to :trac:`20003`:: - - sage: K. = PolynomialRing(GF(7)) - sage: C = Conic([5*t^2 + 4, t^2 + 3*t + 3, 6*t^2 + 3*t + 2, - ....: 5*t^2 + 5, 4*t + 3, 4*t^2 + t + 5]) - sage: C.has_rational_point() # needs sage.libs.singular - Traceback (most recent call last): - ... - TypeError: self (=Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate - Polynomial Ring in t over Finite Field of size 7 defined by - (-2*t^2 - 3)*x^2 + (-t^3 + 3*t^2 - 2*t - 2)/(t + 3)*y^2 + (-t^6 + 3*t^5 + t^3 - t^2 - t + 2)/(t^4 + t^3 - 3*t^2 + 3*t + 1)*z^2 - To: Projective Conic Curve over Fraction Field of Univariate - Polynomial Ring in t over Finite Field of size 7 defined by - (-2*t^2 - 3)*x^2 + (t^2 + 3*t + 3)*x*y + (-2*t^2 - 2)*y^2 + (-t^2 + 3*t + 2)*x*z + (-3*t + 3)*y*z + (-3*t^2 + t - 2)*z^2 - Defn: Defined on coordinates by sending (x : y : z) to - (x + (2*t - 2)/(t + 3)*y + (3*t^4 + 2*t^3 - 2*t^2 - 2*t + 3)/(t^4 + t^3 - 3*t^2 + 3*t + 1)*z - : y + (-t^3 - t^2 + 3*t - 1)/(t^3 - 3*t^2 + 2*t + 2)*z : z)) - domain must equal right (=Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate - Polynomial Ring in t over Finite Field of size 7 defined by - (-2*t^3 - t^2 + 3*t + 3)*x^2 + (t - 3)*y^2 + (-t^7 + 2*t^5 + t^4 + 2*t^3 + 3*t^2 - t - 1)*z^2 - To: Projective Conic Curve over Fraction Field of Univariate - Polynomial Ring in t over Finite Field of size 7 defined by - -2/(t^3 - 3*t^2 + 2*t + 2)*x^2 + 1/(t^3 + 3*t^2 - 2*t + 1)*y^2 + (-t^6 + 3*t^5 + t^3 - t^2 - t + 2)/(t^9 - 2*t^8 + t^7 - t^6 + 3*t^5 - 3*t^3 + t^2 - 2*t + 3)*z^2 - Defn: Defined on coordinates by sending (x : y : z) to - ((t^3 - 3*t^2 + 2*t + 2)*x : (t^2 - 2)*y : (t^5 - 3*t^4 + t^2 + 3*t + 3)*z)) - codomain - - - TESTS:: sage: K. = FractionField(PolynomialRing(QQ, 't')) @@ -250,6 +218,16 @@ def has_rational_point(self, point=False, algorithm='default', sage: C.has_rational_point(point=True) # long time (4 seconds) # needs sage.libs.singular (True, ((-2/117*t^8 + 304/1053*t^7 + 40/117*t^6 - 1/27*t^5 - 110/351*t^4 - 2/195*t^3 + 11/351*t^2 + 1/117)/(t^4 + 2/39*t^3 + 4/117*t^2 + 2/39*t + 14/39) : -5/3*t^4 + 19*t^3 : 1)) + + ``has_rational_point`` used to fail for some conics over function fields + over finite fields, due to :trac:`20003`:: + + sage: K. = PolynomialRing(GF(7)) + sage: C = Conic([5*t^2 + 4, t^2 + 3*t + 3, 6*t^2 + 3*t + 2, + ....: 5*t^2 + 5, 4*t + 3, 4*t^2 + t + 5]) + sage: C.has_rational_point() + True + """ from .constructor import Conic From 3ea9f98b12848aa813464ea75c5d891f21d0f230 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Fri, 13 Oct 2023 17:34:06 +0200 Subject: [PATCH 237/463] simplify flint spkg-configure for flint3 - flint no longer depends on ntl - HAVE_GC no longer exists --- build/pkgs/flint/spkg-configure.m4 | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/build/pkgs/flint/spkg-configure.m4 b/build/pkgs/flint/spkg-configure.m4 index 32da02e52c9..9576e4cc1e9 100644 --- a/build/pkgs/flint/spkg-configure.m4 +++ b/build/pkgs/flint/spkg-configure.m4 @@ -1,25 +1,8 @@ SAGE_SPKG_CONFIGURE([flint], [ - SAGE_SPKG_DEPCHECK([mpfr ntl], [ + SAGE_SPKG_DEPCHECK([mpfr], [ AC_CHECK_HEADER(flint/flint.h, [ dnl gr_get_fexpr appears in Flint 3.0 - AC_SEARCH_LIBS([gr_get_fexpr], [flint], [ - dnl check that NTL is linked in - AC_SEARCH_LIBS([fmpz_poly_get_ZZX], [flint], [ - - AC_MSG_CHECKING([that GC is not enabled in Flint... ]) - AC_RUN_IFELSE([ - AC_LANG_PROGRAM([[#include ]], [ - [#ifdef HAVE_GC] - [return HAVE_GC;] - [#else] - [return 0;] - [#endif]])], - [AC_MSG_RESULT([GC not enabled. Good.])], - [AC_MSG_RESULT([GC enabled. Incompatible with Sage.]) - sage_spkg_install_flint=yes], - [AC_MSG_RESULT(["cross compiling. assuming GC is not enabled"])]) - ], [sage_spkg_install_flint=yes]) - ], [sage_spkg_install_flint=yes]) + AC_SEARCH_LIBS([gr_get_fexpr], [flint], [], [sage_spkg_install_flint=yes]) ], [sage_spkg_install_flint=yes]) ]) ], [], [], [ From 21f18dd36d7b6edb8e67da9dbc352b31d17af6fd Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Fri, 13 Oct 2023 18:04:41 +0200 Subject: [PATCH 238/463] some undocumented removals noticed by Vincent --- src/sage/libs/arb/acb.pxd | 4 ---- src/sage/libs/arb/arb.pxd | 7 ------- 2 files changed, 11 deletions(-) diff --git a/src/sage/libs/arb/acb.pxd b/src/sage/libs/arb/acb.pxd index 3f53b96d331..851488d803a 100644 --- a/src/sage/libs/arb/acb.pxd +++ b/src/sage/libs/arb/acb.pxd @@ -152,10 +152,6 @@ cdef extern from "arb_wrap.h": void acb_sech(acb_t s, const acb_t z, long prec) void acb_csch(acb_t c, const acb_t z, long prec) - void acb_rising_ui_bs(acb_t z, const acb_t x, unsigned long n, long prec) - void acb_rising_ui_rs(acb_t z, const acb_t x, unsigned long n, unsigned long step, long prec) - void acb_rising_ui_rec(acb_t z, const acb_t x, unsigned long n, long prec) - void acb_rising_ui(acb_t z, const acb_t x, unsigned long n, long prec) void acb_rising(acb_t z, const acb_t x, const acb_t n, long prec) void acb_gamma(acb_t y, const acb_t x, long prec) diff --git a/src/sage/libs/arb/arb.pxd b/src/sage/libs/arb/arb.pxd index 33083fc125f..acd232ab816 100644 --- a/src/sage/libs/arb/arb.pxd +++ b/src/sage/libs/arb/arb.pxd @@ -224,15 +224,8 @@ cdef extern from "arb_wrap.h": void arb_lambertw(arb_t res, const arb_t x, int flags, long prec) - void arb_rising_ui_bs(arb_t z, const arb_t x, unsigned long n, long prec) - void arb_rising_ui_rs(arb_t z, const arb_t x, unsigned long n, unsigned long step, long prec) - void arb_rising_ui_rec(arb_t z, const arb_t x, unsigned long n, long prec) - void arb_rising_ui(arb_t z, const arb_t x, unsigned long n, long prec) void arb_rising(arb_t z, const arb_t x, const arb_t n, long prec) void arb_rising_fmpq_ui(arb_t z, const fmpq_t x, unsigned long n, long prec) - void arb_rising2_ui_bs(arb_t u, arb_t v, const arb_t x, unsigned long n, long prec) - void arb_rising2_ui_rs(arb_t u, arb_t v, const arb_t x, unsigned long n, unsigned long step, long prec) - void arb_rising2_ui(arb_t u, arb_t v, const arb_t x, unsigned long n, long prec) void arb_fac_ui(arb_t z, unsigned long n, long prec) void arb_bin_ui(arb_t z, const arb_t n, unsigned long k, long prec) void arb_bin_uiui(arb_t z, unsigned long n, unsigned long k, long prec) From 5e02c5ead25c4d147d8671775a0d33c1ac3c6c3f Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Sun, 15 Oct 2023 12:55:50 +0200 Subject: [PATCH 239/463] update tests for flint3 --- src/sage/rings/complex_arb.pyx | 7 ++++--- src/sage/rings/real_arb.pyx | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/complex_arb.pyx b/src/sage/rings/complex_arb.pyx index 1e3085c9215..0786de7fc81 100644 --- a/src/sage/rings/complex_arb.pyx +++ b/src/sage/rings/complex_arb.pyx @@ -1360,12 +1360,13 @@ cdef class ComplexBall(RingElement): sage: CBF100(-3r) -3.000000000000000000000000000000 - sage: ComplexBall(CBF100, 10^100) - 1.000000000000000000000000000000e+100 sage: ComplexBall(CBF100, CIF(1, 2)) 1.000000000000000000000000000000 + 2.000000000000000000000000000000*I sage: ComplexBall(CBF100, RBF(1/3), RBF(1)) [0.3333333333333333 +/- ...e-17] + 1.000000000000000000000000000000*I + sage: ComplexBall(CBF100, 10^100) + [1.000000000000000000000000000000e+100 +/- ...] + sage: NF. = QuadraticField(-1, embedding=CC(0, -1)) sage: CBF(a) -1.000000000000000*I @@ -3009,7 +3010,7 @@ cdef class ComplexBall(RingElement): sage: CBF(1).rising_factorial(2**64) [+/- ...e+347382171326740403407] sage: ComplexBallField(128)(1).rising_factorial(2**64) - [2.343691126796861348e+347382171305201285713 +/- ...e+347382171305201285694] + [2.34369112679686134...e+347382171305201285713 +/- ...] sage: CBF(1/2).rising_factorial(CBF(2,3)) # abs tol 1e-15 [-0.123060451458124 +/- 3.06e-16] + [0.0406412631676552 +/- 7.57e-17]*I diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index 17961ac36b2..8509b19cc66 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -898,7 +898,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): sage: RBF.gamma(5) 24.00000000000000 sage: RBF.gamma(10**20) - [+/- ...e+1956570552410610660600] + [1.932849514310098...+1956570551809674817225 +/- ...] sage: RBF.gamma(1/3) [2.678938534707747 +/- ...e-16] sage: RBF.gamma(-5) @@ -1102,7 +1102,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): 15.00000000000000, 48.00000000000000] sage: RBF.double_factorial(2**20) - [1.4483729903e+2928836 +/- ...e+2928825] + [1.448372990...e+2928836 +/- ...] sage: RBF.double_factorial(2**1000) Traceback (most recent call last): ... From 516b65a034fbba326a61d9c5b09cd3a1dc7870a5 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Sun, 22 Oct 2023 09:53:06 +0200 Subject: [PATCH 240/463] missing includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (thanks to Gonzalo Tornaría) --- src/sage/libs/arb/arb_wrap.h | 2 ++ src/sage/libs/flint/flint_wrap.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/sage/libs/arb/arb_wrap.h b/src/sage/libs/arb/arb_wrap.h index f51c89ffe38..488bb376d5e 100644 --- a/src/sage/libs/arb/arb_wrap.h +++ b/src/sage/libs/arb/arb_wrap.h @@ -5,6 +5,8 @@ * by arb, most of which rely on flint's ulong and slong defines. */ +#include + #undef ulong #undef slong diff --git a/src/sage/libs/flint/flint_wrap.h b/src/sage/libs/flint/flint_wrap.h index a416d5b53db..4db72b97660 100644 --- a/src/sage/libs/flint/flint_wrap.h +++ b/src/sage/libs/flint/flint_wrap.h @@ -15,6 +15,7 @@ */ #include +#include /* Save previous definition of ulong if any, as pari also uses it */ /* Should work on GCC, clang, MSVC */ @@ -33,6 +34,7 @@ #include #include +#include #include #include #include From e03f6c41ecbf7f1f259045c5d9862e918e385b8a Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Mon, 13 Nov 2023 09:53:55 +0100 Subject: [PATCH 241/463] stricter gmp version check, for flint3's benefit --- build/pkgs/gmp/spkg-configure.m4 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build/pkgs/gmp/spkg-configure.m4 b/build/pkgs/gmp/spkg-configure.m4 index 61d7c5f3b2f..4000200db2c 100644 --- a/build/pkgs/gmp/spkg-configure.m4 +++ b/build/pkgs/gmp/spkg-configure.m4 @@ -2,8 +2,10 @@ SAGE_SPKG_CONFIGURE([gmp], [ sage_spkg_install_gmp=no AC_CHECK_HEADER(gmp.h, [], [sage_spkg_install_gmp=yes]) AC_CHECK_HEADER(gmpxx.h, [], [sage_spkg_install_gmp=yes]) - dnl mpq_cmp_z appeared in GMP 6.1.0 and is used by pynac - AC_SEARCH_LIBS([__gmpq_cmp_z], [gmp], [], + dnl mpn_gcd_11 appeared in GMP 6.2.1 + dnl It is undocumented but is used by Flint when built with default + dnl flags. + AC_SEARCH_LIBS([__gmpn_gcd_11], [gmp], [], [sage_spkg_install_gmp=yes]) ], [], [], [ if test x$sage_spkg_install_gmp = xyes; then From 27351b5e0bda34a5bb687c4b5fb81981bffc072b Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Mon, 13 Nov 2023 10:26:39 +0100 Subject: [PATCH 242/463] patch flint to fix handling of DESTDIR --- ...-Makefile.in-fix-handling-of-DESTDIR.patch | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 build/pkgs/flint/patches/0001-Makefile.in-fix-handling-of-DESTDIR.patch diff --git a/build/pkgs/flint/patches/0001-Makefile.in-fix-handling-of-DESTDIR.patch b/build/pkgs/flint/patches/0001-Makefile.in-fix-handling-of-DESTDIR.patch new file mode 100644 index 00000000000..48a32f5d894 --- /dev/null +++ b/build/pkgs/flint/patches/0001-Makefile.in-fix-handling-of-DESTDIR.patch @@ -0,0 +1,106 @@ +From 54277f054f13254898c9a57c2c7eb869877e1252 Mon Sep 17 00:00:00 2001 +From: Marc Mezzarobba +Date: Mon, 13 Nov 2023 10:23:54 +0100 +Subject: [PATCH] Makefile.in: fix handling of $DESTDIR + +--- + Makefile.in | 54 ++++++++++++++++++++++++++--------------------------- + 1 file changed, 27 insertions(+), 27 deletions(-) + +diff --git a/Makefile.in b/Makefile.in +index 08db6837c..2827b9da1 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -34,9 +34,9 @@ FLINT_SOLIB:=@FLINT_SOLIB@ + prefix:=@prefix@ + exec_prefix:=@exec_prefix@ + +-INCLUDEDIR:=$(DESTDIR)@includedir@ +-LIBDIR:=$(DESTDIR)@libdir@ +-BINDIR:=$(DESTDIR)@bindir@ ++INCLUDEDIR:=@includedir@ ++LIBDIR:=@libdir@ ++BINDIR:=@bindir@ + PKGCONFIGDIR:=$(LIBDIR)/pkgconfig + + HOST_OS:=@host_os@ +@@ -202,10 +202,10 @@ BUILD_DIRS += \ + endif + + INSTALL_DIRS := \ +- $(LIBDIR) $(INCLUDEDIR)/flint \ +- $(PKGCONFIGDIR) ++ $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCLUDEDIR)/flint \ ++ $(DESTDIR)$(PKGCONFIGDIR) + ifneq ($(FLINT_DLLLIB),0) +-INSTALL_DIRS += $(BINDIR) ++INSTALL_DIRS += $(DESTDIR)$(BINDIR) + endif + + ################################################################################ +@@ -722,41 +722,41 @@ distclean: clean + ################################################################################ + + install: library | $(INSTALL_DIRS) +- $(CP) flint.pc $(PKGCONFIGDIR)/flint.pc ++ $(CP) flint.pc $(DESTDIR)$(PKGCONFIGDIR)/flint.pc + ifneq ($(SHARED), 0) + ifneq ($(FLINT_DLLLIB),0) +- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB) $(BINDIR) +- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_MAJOR) $(BINDIR) +- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_FULL) $(BINDIR) +- $(CP) $(FLINT_DIR)/$(FLINT_IMPLIB) $(LIBDIR) ++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB) $(DESTDIR)$(BINDIR) ++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_MAJOR) $(DESTDIR)$(BINDIR) ++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_FULL) $(DESTDIR)$(BINDIR) ++ $(CP) $(FLINT_DIR)/$(FLINT_IMPLIB) $(DESTDIR)$(LIBDIR) + else +- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB) $(LIBDIR) +- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_MAJOR) $(LIBDIR) +- $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_FULL) $(LIBDIR) ++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB) $(DESTDIR)$(LIBDIR) ++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_MAJOR) $(DESTDIR)$(LIBDIR) ++ $(CP_A) $(FLINT_DIR)/$(FLINT_LIB_FULL) $(DESTDIR)$(LIBDIR) + endif + ifneq ($(FLINT_DYLIB),0) +- install_name_tool -id $(LIBDIR)/$(FLINT_LIB_FULL) $(LIBDIR)/$(FLINT_LIB) ++ install_name_tool -id $(LIBDIR)/$(FLINT_LIB_FULL) $(DESTDIR)$(LIBDIR)/$(FLINT_LIB) + endif + endif + ifneq ($(STATIC), 0) +- $(CP) $(FLINT_DIR)/$(FLINT_LIB_STATIC) $(LIBDIR) ++ $(CP) $(FLINT_DIR)/$(FLINT_LIB_STATIC) $(DESTDIR)$(LIBDIR) + endif +- $(CP) $(HEADERS) $(INCLUDEDIR)/flint ++ $(CP) $(HEADERS) $(DESTDIR)$(INCLUDEDIR)/flint + + uninstall: +- $(RM_F) $(PKGCONFIGDIR)/flint.pc ++ $(RM_F) $(DESTDIR)$(PKGCONFIGDIR)/flint.pc + ifneq ($(FLINT_DLLLIB),0) +- $(RM_F) $(BINDIR)/$(FLINT_LIB) +- $(RM_F) $(BINDIR)/$(FLINT_LIB_MAJOR) +- $(RM_F) $(BINDIR)/$(FLINT_LIB_FULL) +- $(RM_F) $(LIBDIR)/$(FLINT_IMPLIB) ++ $(RM_F) $(DESTDIR)$(BINDIR)/$(FLINT_LIB) ++ $(RM_F) $(DESTDIR)$(BINDIR)/$(FLINT_LIB_MAJOR) ++ $(RM_F) $(DESTDIR)$(BINDIR)/$(FLINT_LIB_FULL) ++ $(RM_F) $(DESTDIR)$(LIBDIR)/$(FLINT_IMPLIB) + else +- $(RM_F) $(LIBDIR)/$(FLINT_LIB) +- $(RM_F) $(LIBDIR)/$(FLINT_LIB_MAJOR) +- $(RM_F) $(LIBDIR)/$(FLINT_LIB_FULL) ++ $(RM_F) $(DESTDIR)$(LIBDIR)/$(FLINT_LIB) ++ $(RM_F) $(DESTDIR)$(LIBDIR)/$(FLINT_LIB_MAJOR) ++ $(RM_F) $(DESTDIR)$(LIBDIR)/$(FLINT_LIB_FULL) + endif +- $(RM_F) $(LIBDIR)/$(FLINT_LIB_STATIC) +- $(RM_RF) $(INCLUDEDIR)/flint ++ $(RM_F) $(DESTDIR)$(LIBDIR)/$(FLINT_LIB_STATIC) ++ $(RM_RF) $(DESTDIR)$(INCLUDEDIR)/flint + + ################################################################################ + # maintainer stuff +-- +2.42.0 + From 3223aa1aa21fccec128c298fa7f1990806148e52 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Mon, 13 Nov 2023 20:34:43 +0000 Subject: [PATCH 243/463] checksum.ini: Update to the latest info --- build/pkgs/configure/checksums.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index ed5acb9cc09..b5731ea41cd 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=6564d23ce7b0af645ecf5ec5461f82942ca9561e -md5=425ddadf2e8f5808916be6567802033d -cksum=2694227517 +sha1=6c2020ef6639a24eb777eb1fa1adfca6dbd4520c +md5=c8641bab76511afffa14c46c8a6f4c73 +cksum=1432162721 From 103d99b8aee497569cb1f418c8943681fc77bf76 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 22 Oct 2023 12:34:50 -0700 Subject: [PATCH 244/463] src/tox.ini (coverage.py): New --- src/tox.ini | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tox.ini b/src/tox.ini index fea30bea362..c8d22d9eb62 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -51,6 +51,21 @@ allowlist_externals = {[sagedirect]allowlist_externals} commands = {env:SAGE} -t -p 0 {posargs:--all} +[testenv:coverage.py] +# https://coverage.readthedocs.io/en/latest/index.html +description = + run the Sage doctester with Coverage.py + (https://coverage.readthedocs.io/en/latest/index.html) +## This toxenv bypasses the virtual environment set up by tox. +passenv = {[sagedirect]passenv} +setenv = {[sagedirect]setenv} +envdir = {[sagedirect]envdir} +allowlist_externals = {[sagedirect]allowlist_externals} +commands_pre = + {env:SAGE} -pip install -U coverage +commands = + {env:SAGE} --python -m coverage run {toxinidir}/../venv/bin/sage-runtests -p 0 {posargs:--all} + [testenv:coverage] description = give information about doctest coverage of files From ef22843a5a0569028951235b3ae004373f203224 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 22 Oct 2023 12:38:26 -0700 Subject: [PATCH 245/463] tox.ini (coverage.py): Delegate to src/tox.ini --- tox.ini | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tox.ini b/tox.ini index c039103f422..afc5b071191 100644 --- a/tox.ini +++ b/tox.ini @@ -794,6 +794,15 @@ envdir = {[sage_src]envdir} commands = {[sage_src]commands} allowlist_externals = {[sage_src]allowlist_externals} +[testenv:coverage.py] +description = + run the Sage doctester with Coverage.py + (https://coverage.readthedocs.io/en/latest/index.html) +passenv = {[sage_src]passenv} +envdir = {[sage_src]envdir} +commands = {[sage_src]commands} +allowlist_externals = {[sage_src]allowlist_externals} + [testenv:coverage] description = give information about doctest coverage of files (same as "sage --coverage[all]") From b27878f8fd5012aaf32efcbcbc6f611d20ee8306 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 22 Oct 2023 12:39:29 -0700 Subject: [PATCH 246/463] sage --advanced: Fix what is displayed as default for 'sage --tox' --- src/bin/sage | 4 ++-- src/tox.ini | 2 +- tox.ini | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bin/sage b/src/bin/sage index 64d7986482b..edc6303f533 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -453,8 +453,8 @@ usage_advanced() { if [ -n "$SAGE_SRC" -a -f "$SAGE_SRC/tox.ini" ]; then echo " --tox [options] -- general entry point for testing" echo " and linting of the Sage library" - echo " -e -- run specific test environments" - echo " (default: run all except full pycodestyle)" + echo " -e -- run specific test environments; default:" + echo " $(echo $(tox -c "$SAGE_SRC" --listenvs 2>/dev/null) | sed 's/ /,/g;')" tox -c "$SAGE_SRC" --listenvs-all -v 2>/dev/null | sed -n '/->/s/^/ /;s/(/\ (/;s/->/ --/p;' echo " -p auto -- run test environments in parallel" diff --git a/src/tox.ini b/src/tox.ini index c8d22d9eb62..4f4f41383a9 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -216,7 +216,7 @@ commands = flake8 --select=RST {posargs:{toxinidir}/sage/} [testenv:cython-lint] description = - Check Cython files for code style + check Cython files for code style deps = cython-lint commands = cython-lint --no-pycodestyle {posargs:{toxinidir}/sage/} diff --git a/tox.ini b/tox.ini index afc5b071191..10aaff29066 100644 --- a/tox.ini +++ b/tox.ini @@ -870,7 +870,7 @@ allowlist_externals = {[sage_src]allowlist_externals} [testenv:cython-lint] description = - Check Cython files for code style + check Cython files for code style passenv = {[sage_src]passenv} envdir = {[sage_src]envdir} commands = {[sage_src]commands} From 514d716a2056ee40c1044a1773192cc60dc06f85 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 22 Oct 2023 13:46:51 -0700 Subject: [PATCH 247/463] tox.ini (coverage.py[-html]): Generate reports --- src/tox.ini | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tox.ini b/src/tox.ini index 4f4f41383a9..629fd077c2f 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -55,7 +55,7 @@ commands = # https://coverage.readthedocs.io/en/latest/index.html description = run the Sage doctester with Coverage.py - (https://coverage.readthedocs.io/en/latest/index.html) + (use "sage --tox -e coverage.py-html" to generate HTML report) ## This toxenv bypasses the virtual environment set up by tox. passenv = {[sagedirect]passenv} setenv = {[sagedirect]setenv} @@ -64,7 +64,11 @@ allowlist_externals = {[sagedirect]allowlist_externals} commands_pre = {env:SAGE} -pip install -U coverage commands = - {env:SAGE} --python -m coverage run {toxinidir}/../venv/bin/sage-runtests -p 0 {posargs:--all} + {env:SAGE} --python -m coverage run "{toxinidir}/../venv/bin/sage-runtests" -p 0 {posargs:--all} +commands_post = + {env:SAGE} --python -m coverage combine + {env:SAGE} --python -m coverage report +html: {env:SAGE} --python -m coverage html -d "{envdir}" [testenv:coverage] description = From b432dacd891e881ed085bce6158d72806db5871b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 22 Oct 2023 13:49:15 -0700 Subject: [PATCH 248/463] src/doc/en/developer/tools.rst: Update output from sage --advanced regarding tox --- src/doc/en/developer/tools.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/doc/en/developer/tools.rst b/src/doc/en/developer/tools.rst index fca5d5ef4c1..1e48f8f627e 100644 --- a/src/doc/en/developer/tools.rst +++ b/src/doc/en/developer/tools.rst @@ -48,8 +48,8 @@ available:: ... --tox [options] -- general entry point for testing and linting of the Sage library - -e -- run specific test environments - (default: run all except full pycodestyle) + -e -- run specific test environments; default: + doctest,coverage,startuptime,pycodestyle-minimal,relint,codespell,rst doctest -- run the Sage doctester (same as "sage -t") coverage -- give information about doctest coverage of files @@ -59,11 +59,13 @@ available:: pycodestyle-minimal -- check against Sage's minimal style conventions relint -- check whether some forbidden patterns appear (includes all patchbot pattern-exclusion plugins) - rst -- validate Python docstrings markup as reStructuredText codespell -- check for misspelled words in source code - cython-lint -- Check Cython files for code style + rst -- validate Python docstrings markup as reStructuredText + coverage.py -- run the Sage doctester with Coverage.py + (use "sage --tox -e coverage.py-html" to generate HTML report) pyright -- run the static typing checker pyright pycodestyle -- check against the Python style conventions of PEP8 + cython-lint -- check Cython files for code style -p auto -- run test environments in parallel --help -- show tox help From fb3e5fff75f2c8101c5b27003a242cb837eb08ee Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 22 Oct 2023 13:59:53 -0700 Subject: [PATCH 249/463] src/doc/en/developer/tools.rst: Add section on Coverage.py --- src/doc/en/developer/tools.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/doc/en/developer/tools.rst b/src/doc/en/developer/tools.rst index 1e48f8f627e..7773a2899c8 100644 --- a/src/doc/en/developer/tools.rst +++ b/src/doc/en/developer/tools.rst @@ -79,6 +79,26 @@ Sage doctester in the normal Sage environment. This is equivalent to using the command ``./sage -t``; see :ref:`chapter-doctesting`. +.. _section-tools-coverage-py: + +Doctest with Coverage.py +======================== + +The command ``./sage -tox -e coverage.py`` requires that Sage has been +built already. ``coverage.py`` is a special tox environment that runs the +Sage doctester (:ref:`chapter-doctesting`) in the normal Sage environment, +but under the control of +`Coverage.py `_ +for code coverage analysis. + +If invoked as ``./sage -tox -e coverage.py-html``, additionally a +detailed HTML report is generated. + +*Configuration:* ``[coverage:run]`` block in ``SAGE_ROOT/src/tox.ini`` + +*Documentation:* https://coverage.readthedocs.io + + .. _section-tools-coverage: Coverage From d1f5bd8090c207c1b2e4446c6aae8c59c9684da1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 24 Oct 2023 11:24:59 -0700 Subject: [PATCH 250/463] src/doc/en/developer/tools.rst: Expand sections on doctest, coverage, startuptime --- src/doc/en/developer/tools.rst | 66 ++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/src/doc/en/developer/tools.rst b/src/doc/en/developer/tools.rst index 7773a2899c8..aee17931a78 100644 --- a/src/doc/en/developer/tools.rst +++ b/src/doc/en/developer/tools.rst @@ -73,10 +73,14 @@ available:: Doctest ======= -The command ``./sage -tox -e doctest`` requires that Sage has been -built already. ``doctest`` is a special tox environment that runs the -Sage doctester in the normal Sage environment. This is equivalent to -using the command ``./sage -t``; see :ref:`chapter-doctesting`. +The command ``./sage -tox -e doctest`` runs the Sage doctester. This is +equivalent to using the command ``./sage -t``; see :ref:`chapter-doctesting`. + +.. NOTE:: + + ``doctest`` is a special tox environment that requires that Sage has + been built already. A virtual environment is created by tox, but + Sage is invoked in the normal Sage environment. .. _section-tools-coverage-py: @@ -84,10 +88,9 @@ using the command ``./sage -t``; see :ref:`chapter-doctesting`. Doctest with Coverage.py ======================== -The command ``./sage -tox -e coverage.py`` requires that Sage has been -built already. ``coverage.py`` is a special tox environment that runs the -Sage doctester (:ref:`chapter-doctesting`) in the normal Sage environment, -but under the control of +The command ``./sage -tox -e coverage.py`` runs the Sage doctester +(:ref:`chapter-doctesting`) in the normal Sage environment, but +under the control of `Coverage.py `_ for code coverage analysis. @@ -98,17 +101,36 @@ detailed HTML report is generated. *Documentation:* https://coverage.readthedocs.io +.. NOTE:: + + ``coverage.py`` is a special tox environment that requires that Sage has + been built already. A virtual environment is created by tox, but the + **coverage** package is installed into the normal Sage environment, and + Sage is invoked from there. .. _section-tools-coverage: Coverage ======== -The command ``./sage -tox -e coverage`` requires that Sage has been -built already. ``coverage`` is a special tox environment that is -equivalent to using the command ``./sage --coverageall`` (if no -arguments are provided) or ``./sage --coverage`` (if arguments are -provided). +The command ``./sage -tox -e coverage`` checks that each function has +at least one doctest (typically in an **EXAMPLES** or **TESTS** block, +see :ref:`section-docstring-function`). + +Without additional arguments, this command is equivalent to using the +command ``./sage --coverageall`` and gives a short report with a one-line +summary for each module of the Sage library. + +If invoked with arguments, for example ``./sage -tox -e coverage +-- src/sage/geometry src/sage/combinat/tableau.py``, it is equivalent to +using the command ``./sage --coverageall``, which includes details on +the modules in the given files or directories. + +.. NOTE:: + + ``coverage`` is a special tox environment that requires that Sage has been + built already. A virtual environment is created by tox, but + Sage is invoked in the normal Sage environment. .. _section-tools-startuptime: @@ -116,10 +138,24 @@ provided). Startuptime =========== -The command ``./sage -tox -e startuptime`` requires that Sage has been -built already. ``startuptime`` is a special tox environment that is +The command ``./sage -tox -e startuptime`` measures the time for loading +each module that is imported during the start up phase of Sage. It is equivalent to using the command ``./sage --startuptime``. +Without additional arguments, the command gives a short report that lists +the modules with the longest contributions to the overall startup time, +sorted by time. + +If invoked with arguments, for example ``sage -tox -e startuptime -- sage.rings +src/sage/geometry/polyhedron``, it provides details on the given modules, packages, +source files, or directories. + +.. NOTE:: + + ``startuptime`` is a special tox environment that requires that Sage has been + built already. A virtual environment is created by tox, but + Sage is invoked in the normal Sage environment. + .. _section-tools-pycodestyle: From 73735ac453e1a25cd0a9b71279b818f280f31e02 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 24 Oct 2023 12:41:49 -0700 Subject: [PATCH 251/463] src/tox.ini (coverage.py-html): Fix for tox >= 4.9 --- src/tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tox.ini b/src/tox.ini index 629fd077c2f..ad43b80702b 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -51,7 +51,7 @@ allowlist_externals = {[sagedirect]allowlist_externals} commands = {env:SAGE} -t -p 0 {posargs:--all} -[testenv:coverage.py] +[testenv:coverage.py{,-html}] # https://coverage.readthedocs.io/en/latest/index.html description = run the Sage doctester with Coverage.py From 75177b0855c78312bf95c998f8edaad15cded248 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 25 Oct 2023 00:05:22 -0700 Subject: [PATCH 252/463] src/doc/en/developer/tools.rst: Fix typo --- src/doc/en/developer/tools.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/developer/tools.rst b/src/doc/en/developer/tools.rst index aee17931a78..2cbd9b6415f 100644 --- a/src/doc/en/developer/tools.rst +++ b/src/doc/en/developer/tools.rst @@ -123,7 +123,7 @@ summary for each module of the Sage library. If invoked with arguments, for example ``./sage -tox -e coverage -- src/sage/geometry src/sage/combinat/tableau.py``, it is equivalent to -using the command ``./sage --coverageall``, which includes details on +using the command ``./sage --coverage``, which includes details on the modules in the given files or directories. .. NOTE:: From 77bbbec81ea7af2f38d2d27f0855c6f871bee9f6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 13 Nov 2023 20:32:23 -0800 Subject: [PATCH 253/463] src/tox.ini (coverage.py-html): Fix --- src/tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tox.ini b/src/tox.ini index ad43b80702b..1e6aa280044 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -68,7 +68,7 @@ commands = commands_post = {env:SAGE} --python -m coverage combine {env:SAGE} --python -m coverage report -html: {env:SAGE} --python -m coverage html -d "{envdir}" + html: {env:SAGE} --python -m coverage html -d "{envdir}" [testenv:coverage] description = From 194771035405881bab5e4a414af96ee3974daa50 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Tue, 14 Nov 2023 09:06:05 +0000 Subject: [PATCH 254/463] remove space in conda.txt --- build/pkgs/prompt_toolkit/distros/conda.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/prompt_toolkit/distros/conda.txt b/build/pkgs/prompt_toolkit/distros/conda.txt index e3e1de9a3ea..b99577146cd 100644 --- a/build/pkgs/prompt_toolkit/distros/conda.txt +++ b/build/pkgs/prompt_toolkit/distros/conda.txt @@ -1 +1 @@ -prompt_toolkit >=3.0.38 +prompt_toolkit>=3.0.38 From aa53aad93eecf0b0798ce5505ea004085fc9f8df Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 14 Nov 2023 09:14:41 -0800 Subject: [PATCH 255/463] src/tox.ini (coverage.py-html): Split out from coverage.py for better help display --- src/doc/en/developer/tools.rst | 2 +- src/tox.ini | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/doc/en/developer/tools.rst b/src/doc/en/developer/tools.rst index 2cbd9b6415f..02be3f91b4b 100644 --- a/src/doc/en/developer/tools.rst +++ b/src/doc/en/developer/tools.rst @@ -62,7 +62,7 @@ available:: codespell -- check for misspelled words in source code rst -- validate Python docstrings markup as reStructuredText coverage.py -- run the Sage doctester with Coverage.py - (use "sage --tox -e coverage.py-html" to generate HTML report) + coverage.py-html -- run the Sage doctester with Coverage.py, generate HTML report pyright -- run the static typing checker pyright pycodestyle -- check against the Python style conventions of PEP8 cython-lint -- check Cython files for code style diff --git a/src/tox.ini b/src/tox.ini index 1e6aa280044..00f7a153f35 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -51,11 +51,10 @@ allowlist_externals = {[sagedirect]allowlist_externals} commands = {env:SAGE} -t -p 0 {posargs:--all} -[testenv:coverage.py{,-html}] +[testenv:coverage.py] # https://coverage.readthedocs.io/en/latest/index.html description = run the Sage doctester with Coverage.py - (use "sage --tox -e coverage.py-html" to generate HTML report) ## This toxenv bypasses the virtual environment set up by tox. passenv = {[sagedirect]passenv} setenv = {[sagedirect]setenv} @@ -68,7 +67,24 @@ commands = commands_post = {env:SAGE} --python -m coverage combine {env:SAGE} --python -m coverage report - html: {env:SAGE} --python -m coverage html -d "{envdir}" + +[testenv:coverage.py-html] +# https://coverage.readthedocs.io/en/latest/index.html +description = + run the Sage doctester with Coverage.py, generate HTML report +## This toxenv bypasses the virtual environment set up by tox. +passenv = {[sagedirect]passenv} +setenv = {[sagedirect]setenv} +envdir = {[sagedirect]envdir} +allowlist_externals = {[sagedirect]allowlist_externals} +commands_pre = + {env:SAGE} -pip install -U coverage +commands = + {env:SAGE} --python -m coverage run "{toxinidir}/../venv/bin/sage-runtests" -p 0 {posargs:--all} +commands_post = + {env:SAGE} --python -m coverage combine + {env:SAGE} --python -m coverage report + {env:SAGE} --python -m coverage html -d "{envdir}" [testenv:coverage] description = From 6ad11d5d16775f61af09b06cf3c4830fd63cda24 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 14 Nov 2023 18:40:27 -0800 Subject: [PATCH 256/463] build/pkgs/openblas: Update to 0.3.25 --- build/pkgs/openblas/checksums.ini | 6 +++--- build/pkgs/openblas/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/openblas/checksums.ini b/build/pkgs/openblas/checksums.ini index c2a1fe997c5..2de5fe8909d 100644 --- a/build/pkgs/openblas/checksums.ini +++ b/build/pkgs/openblas/checksums.ini @@ -1,5 +1,5 @@ tarball=openblas-VERSION.tar.gz -sha1=6b781727c7b95850ae4a3eb0a391492eb4f3e780 -md5=115634b39007de71eb7e75cf7591dfb2 -cksum=2485407229 +sha1=79f2828dff06e24ecec7277f3d3da5e7b196ff53 +md5=48384e324cd1cdcfbdb0d2e16ca55327 +cksum=1614515639 upstream_url=https://github.com/xianyi/OpenBLAS/archive/vVERSION.tar.gz diff --git a/build/pkgs/openblas/package-version.txt b/build/pkgs/openblas/package-version.txt index a1dad2aa79c..88dbf46f411 100644 --- a/build/pkgs/openblas/package-version.txt +++ b/build/pkgs/openblas/package-version.txt @@ -1 +1 @@ -0.3.23 +0.3.25 From 45091b45502aeb520e83830e0e3b32589c920c96 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 15 Nov 2023 13:56:36 +0800 Subject: [PATCH 257/463] Remove outdated future import --- src/sage_setup/autogen/interpreters/__main__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage_setup/autogen/interpreters/__main__.py b/src/sage_setup/autogen/interpreters/__main__.py index de07210db06..96b25d61551 100644 --- a/src/sage_setup/autogen/interpreters/__main__.py +++ b/src/sage_setup/autogen/interpreters/__main__.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function - import argparse import os From 1f572f8769c1a8dd13aaede24ace2edb5860492a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 14 Nov 2023 22:09:37 -0800 Subject: [PATCH 258/463] .github/workflows/macos.yml: Fix syntax --- .github/workflows/macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 34483ed3d22..6d71bcefa16 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -23,7 +23,7 @@ on: default: >- [["latest", "", "homebrew-macos-usrlocal-minimal"], ["latest", "", "homebrew-macos-usrlocal-standard"], - ["11", "xcode_13.2.1", "homebrew-macos-usrlocal-minimal], + ["11", "xcode_13.2.1", "homebrew-macos-usrlocal-minimal"], ["12", "", "homebrew-macos-usrlocal-standard"], ["13", "xcode_15.0", "homebrew-macos-usrlocal-standard"], ["latest", "", "homebrew-macos-usrlocal-maximal"], From 9a4a464ce889e636c005c9dfc231655979c794e9 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 12 Oct 2023 12:03:38 +0200 Subject: [PATCH 259/463] check coprimality of moduli in CRT_basis() --- src/sage/arith/misc.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index aa0174580a1..5d3ef49f7c5 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -3584,10 +3584,6 @@ def CRT_basis(moduli): `a_i` is congruent to 1 modulo `m_i` and to 0 modulo `m_j` for `j\not=i`. - .. note:: - - The pairwise coprimality of the input is not checked. - EXAMPLES:: sage: a1 = ZZ(mod(42,5)) @@ -3610,7 +3606,14 @@ def CRT_basis(moduli): if n == 0: return [] M = prod(moduli) - return [((xgcd(m,M//m)[2])*(M//m)) % M for m in moduli] + cs = [] + for m in moduli: + Mm = M // m + d, _, v = xgcd(m, Mm) + if not d.is_one(): + raise ValueError('moduli must be coprime') + cs.append((v * Mm) % M) + return cs def CRT_vectors(X, moduli): From 19dd5dafe9959355f0c0e0654bc8edfe1b0480f4 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Wed, 12 Apr 2023 17:55:50 +0800 Subject: [PATCH 260/463] fix documentation and doctest for qfbcornacchia() -- see #35292 --- src/sage/quadratic_forms/binary_qf.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index 0f32bba92ba..b7ce0ed5ddb 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -1581,9 +1581,10 @@ def solve_integer(self, n, *, algorithm="general"): sage: Q.solve_integer(773187972) # needs sage.libs.pari (4919, 1337) - If `Q` is of the form `[1,0,c]` as above and `n` is a prime or - four times a prime, Cornacchia's algorithm can be used, which is - typically much faster than the general method:: + If `Q` is of the form `[1,0,c]` as above and `n` is a prime + (or four times a prime whenever `c \equiv 3 \pmod 4`), then + Cornacchia's algorithm can be used, which is typically much + faster than the general method:: sage: Q = BinaryQF([1, 0, 12345]) sage: n = 2^99 + 5273 @@ -1625,7 +1626,7 @@ def solve_integer(self, n, *, algorithm="general"): sage: abc = [1, 0, randrange(1,10^3)] sage: Q = BinaryQF(abc) sage: n = random_prime(10^9) - sage: if randrange(2): + sage: if Q[2] % 4 == 3 and randrange(2): ....: n *= 4 sage: xy1 = Q.solve_integer(n, algorithm='cornacchia') sage: xy1 is None or Q(*xy1) == n From e53ce0dd5263cbf9d1907b5463af2e56919223db Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 13 Apr 2023 01:33:36 +0800 Subject: [PATCH 261/463] streamline test per reviewer feedback --- src/sage/quadratic_forms/binary_qf.py | 30 ++++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index b7ce0ed5ddb..d16438bf45b 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -1623,16 +1623,30 @@ def solve_integer(self, n, *, algorithm="general"): Also when using the ``"cornacchia"`` algorithm:: sage: # needs sage.libs.pari - sage: abc = [1, 0, randrange(1,10^3)] - sage: Q = BinaryQF(abc) sage: n = random_prime(10^9) - sage: if Q[2] % 4 == 3 and randrange(2): - ....: n *= 4 - sage: xy1 = Q.solve_integer(n, algorithm='cornacchia') - sage: xy1 is None or Q(*xy1) == n + sage: c = randrange(1, 10^3) + + sage: # needs sage.libs.pari + sage: Q1 = BinaryQF(1, 0, c) + sage: xy = Q1.solve_integer(n, algorithm='cornacchia') + sage: xy is None or Q1(*xy) == n + True + sage: (xy is None) == (Q1.solve_integer(n) is None) + True + + sage: # needs sage.libs.pari + sage: Q3 = BinaryQF(1, 0, 4*c+3) + sage: xy = Q3.solve_integer(n, algorithm='cornacchia') + sage: xy is None or Q3(*xy) == n + True + sage: (xy is None) == (Q3.solve_integer(n) is None) + True + + sage: # needs sage.libs.pari + sage: xy = Q3.solve_integer(4*n, algorithm='cornacchia') + sage: xy is None or Q3(*xy) == 4*n True - sage: xy2 = Q.solve_integer(n) - sage: (xy1 is None) == (xy2 is None) + sage: (xy is None) == (Q3.solve_integer(4*n) is None) True Test for square discriminants specifically (:trac:`33026`):: From 5c1712628b310b6736929a03a6e339ab74d62e97 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 21 Aug 2023 20:22:56 -0700 Subject: [PATCH 262/463] src/sage/misc/package_dir.py (update_distribution): New --- src/sage/misc/package_dir.py | 101 ++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 9f075b16c31..fe636fa7a37 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -14,6 +14,7 @@ import os import glob +import re import sys from contextlib import contextmanager @@ -90,8 +91,11 @@ def __contains__(self, filename): return distribution not in self._exclude_distributions +distribution_directive = re.compile(r"(\s*#?\s*)(sage_setup:\s*distribution\s*=\s*([-_A-Za-z0-9]*))") + + def read_distribution(src_file): - """ + r""" Parse ``src_file`` for a ``# sage_setup: distribution = PKG`` directive. INPUT: @@ -130,6 +134,101 @@ def read_distribution(src_file): return '' +def update_distribution(src_file, distribution, *, verbose=False): + r""" + Add or update a ``# sage_setup: distribution = PKG`` directive in ``src_file``. + + For a Python or Cython file, if a ``sage_setup: distribution`` directive + is not already present, it is added. + + For any other file, if a ``sage_setup: distribution`` directive is not already + present, no action is taken. + + INPUT: + + - ``src_file`` -- file name of a source file + + EXAMPLES:: + + sage: from sage.misc.package_dir import read_distribution, update_distribution + sage: import tempfile + sage: def test(filename, file_contents): + ....: with tempfile.TemporaryDirectory() as d: + ....: fname = os.path.join(d, filename) + ....: with open(fname, 'w') as f: + ....: f.write(file_contents) + ....: with open(fname, 'r') as f: + ....: print(f.read() + "====") + ....: update_distribution(fname, 'sagemath-categories') + ....: with open(fname, 'r') as f: + ....: print(f.read() + "====") + ....: update_distribution(fname, '') + ....: with open(fname, 'r') as f: + ....: print(f.read(), end="") + sage: test('module.py', '# Python file\n') + # Python file + ==== + # sage_setup: distribution = sagemath-categories + # Python file + ==== + # sage_setup: distribution = + # Python file + sage: test('file.cpp', '// sage_setup: distribution=sagemath-modules\n' + ....: '// C++ file with existing directive\n') + // sage_setup: distribution=sagemath-modules + // C++ file with existing directive + ==== + // sage_setup: distribution = sagemath-categories + // C++ file with existing directive + ==== + // sage_setup: distribution = + // C++ file with existing directive + sage: test('file.cpp', '// C++ file without existing directive\n') + // C++ file without existing directive + ==== + // C++ file without existing directive + ==== + // C++ file without existing directive + """ + if not distribution: + distribution = '' + directive = f'sage_setup: distribution = {distribution}'.rstrip() + with open(src_file, 'r') as f: + src_lines = f.read().splitlines(keepends=True) + any_found = False + any_change = False + for i, line in enumerate(src_lines): + if m := distribution_directive.search(line): + old_distribution = m.group(3) + if any_found: + # Found a second distribution directive; remove it. + if not (line := distribution_directive.sub(r'', line)): + line = None + else: + line = distribution_directive.sub(fr'\1{directive}', line) + if line != src_lines[i]: + src_lines[i] = line + any_change = True + if verbose: + print(f"Changed 'sage_setup: distribution' in {src_file!r} " + f"from {old_distribution!r} to {distribution!r}") + any_found = True + if not any_found: + if any(src_file.endswith(ext) + for ext in [".pxd", ".pxi", ".py", ".pyx", ".sage"]): + src_lines.insert(0, f'# {directive}\n') + any_change = True + if verbose: + print(f"Added 'sage_setup: distribution = {distribution}' " + f"directive in {src_file!r}") + if not any_change: + return + with open(src_file, 'w') as f: + for line in src_lines: + if line is not None: + f.write(line) + + def is_package_or_sage_namespace_package_dir(path, *, distribution_filter=None): r""" Return whether ``path`` is a directory that contains a Python package. From 534bcc74c4244bd6f9dbec21e5788d900d004e48 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 21 Aug 2023 20:23:43 -0700 Subject: [PATCH 263/463] sage --fixdistributions: New command --- src/bin/sage | 10 ++++++- src/sage/misc/package_dir.py | 57 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/bin/sage b/src/bin/sage index 64d7986482b..e5bb07e4882 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -482,10 +482,13 @@ usage_advanced() { echo " --fixdoctests file.py" echo " -- Run doctests and replace output of failing doctests" echo " with actual output." - echo " --fiximports " + echo " --fiximports " echo " -- Replace imports from sage.PAC.KAGE.all by specific" echo " imports when sage.PAC.KAGE is an implicit namespace" echo " package" + echo " --fixdistributions " + echo " -- Check or update 'sage_setup: distribution' directives" + echo " in source files" fi echo " --sh [...] -- run a shell with Sage environment variables" echo " as they are set in the runtime of Sage" @@ -986,6 +989,11 @@ if [ "$1" = '-fiximports' -o "$1" = '--fiximports' ]; then exec sage-python -m sage.misc.replace_dot_all "$@" fi +if [ "$1" = '-fixdistributions' -o "$1" = '--fixdistributions' ]; then + shift + exec sage-python -m sage.misc.package_dir "$@" +fi + if [ "$1" = '-tox' -o "$1" = '--tox' ]; then shift if [ -n "$SAGE_SRC" -a -f "$SAGE_SRC/tox.ini" ]; then diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index fe636fa7a37..aaf054dd5b8 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -432,3 +432,60 @@ def seen(p, m={}): path = [p for p in path if not seen(p)] yield from walk_packages(path, info.name + '.', onerror) + + +if __name__ == '__main__': + + from argparse import ArgumentParser + + parser = ArgumentParser(description="Maintenance tool for distribution packages of the Sage library", + epilog=("Example usage:\n\n grep '^sage/' pkgs/sagemath-ntl/sagemath_ntl.egg-info/SOURCES.txt " + "| (cd src && xargs ../sage -fixdistributions --set sagemath-ntl)""")) + parser.add_argument('--add', metavar='distribution', type=str, default=None, + help=("add a 'sage_setup: distribution' directive to FILES; " + "do not change files that already have a nonempty directive")) + parser.add_argument('--set', metavar='distribution', type=str, default=None, + help="add or update the 'sage_setup: distribution' directive in FILES") + parser.add_argument("filename", nargs='*', type=str, + help="source files or directories (default: all file from SAGE_SRC)") + + args = parser.parse_args() + + if not args.filename: + from sage.env import SAGE_SRC + if (not SAGE_SRC + or not os.path.exists(os.path.join(SAGE_SRC, 'sage')) + or not os.path.exists(os.path.join(SAGE_SRC, 'conftest_test.py'))): + print(f'{SAGE_SRC=} does not seem to contain a copy of the Sage source tree') + sys.exit(1) + args.filename = [os.path.join(SAGE_SRC, 'sage')] + + def handle_file(path): + if args.set is not None: + update_distribution(path, args.set, verbose=True) + elif args.add is not None and not read_distribution(path): + update_distribution(path, args.add, verbose=True) + else: + distribution = read_distribution(path) + print(f'{path}: file in distribution {distribution!r}') + + for path in args.filename: + if os.path.isdir(path): + if not is_package_or_sage_namespace_package_dir(path): + print(f'{path}: non-package directory') + else: + for root, dirs, files in os.walk(path): + for dir in sorted(dirs): + path = os.path.join(root, dir) + if any(dir.startswith(prefix) for prefix in ['.', 'build', 'dist', '__pycache__']): + # Silently skip + dirs.remove(dir) + elif not is_package_or_sage_namespace_package_dir(path): + print(f'{path}: non-package directory') + dirs.remove(dir) + for file in sorted(files): + if any(file.endswith(ext) for ext in [".pyc", ".pyo", ".bak", ".so", "~"]): + continue + handle_file(os.path.join(root, file)) + else: + handle_file(path) From b5311bf6d0c4bbc5e3302e4557d35bfac01e880d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 21 Aug 2023 20:32:35 -0700 Subject: [PATCH 264/463] src/sage/misc/package_dir.py (update_distribution): Prevent self-mutilation --- src/sage/misc/package_dir.py | 42 ++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index aaf054dd5b8..9a03d34e329 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -1,4 +1,4 @@ -# sage_setup: distribution = sagemath-environment +# sage_setup:distribution = sagemath-environment """ Recognizing package directories """ @@ -27,12 +27,12 @@ class SourceDistributionFilter: - ``include_distributions`` -- (default: ``None``) if not ``None``, should be a sequence or set of strings: include files whose - ``distribution`` (from a ``# sage_setup: distribution = PACKAGE`` + ``distribution`` (from a ``# sage_setup:`` ``distribution = PACKAGE`` directive in the source file) is an element of ``distributions``. - ``exclude_distributions`` -- (default: ``None``) if not ``None``, should be a sequence or set of strings: exclude files whose - ``distribution`` (from a ``# sage_setup: distribution = PACKAGE`` + ``distribution`` (from a ``# sage_setup:`` ``distribution = PACKAGE`` directive in the module source file) is in ``exclude_distributions``. EXAMPLES:: @@ -96,7 +96,7 @@ def __contains__(self, filename): def read_distribution(src_file): r""" - Parse ``src_file`` for a ``# sage_setup: distribution = PKG`` directive. + Parse ``src_file`` for a ``# sage_setup:`` ``distribution = PKG`` directive. INPUT: @@ -136,12 +136,12 @@ def read_distribution(src_file): def update_distribution(src_file, distribution, *, verbose=False): r""" - Add or update a ``# sage_setup: distribution = PKG`` directive in ``src_file``. + Add or update a ``# sage_setup:`` ``distribution = PKG`` directive in ``src_file``. - For a Python or Cython file, if a ``sage_setup: distribution`` directive + For a Python or Cython file, if a ``distribution`` directive is not already present, it is added. - For any other file, if a ``sage_setup: distribution`` directive is not already + For any other file, if a ``distribution`` directive is not already present, no action is taken. INPUT: @@ -168,20 +168,20 @@ def update_distribution(src_file, distribution, *, verbose=False): sage: test('module.py', '# Python file\n') # Python file ==== - # sage_setup: distribution = sagemath-categories + # sage_setup: distribution...= sagemath-categories # Python file ==== - # sage_setup: distribution = + # sage_setup: distribution...= # Python file - sage: test('file.cpp', '// sage_setup: distribution=sagemath-modules\n' + sage: test('file.cpp', '// sage_setup: ' 'distribution=sagemath-modules\n' ....: '// C++ file with existing directive\n') - // sage_setup: distribution=sagemath-modules + // sage_setup: distribution...=sagemath-modules // C++ file with existing directive ==== - // sage_setup: distribution = sagemath-categories + // sage_setup: distribution...= sagemath-categories // C++ file with existing directive ==== - // sage_setup: distribution = + // sage_setup: distribution...= // C++ file with existing directive sage: test('file.cpp', '// C++ file without existing directive\n') // C++ file without existing directive @@ -192,9 +192,13 @@ def update_distribution(src_file, distribution, *, verbose=False): """ if not distribution: distribution = '' - directive = f'sage_setup: distribution = {distribution}'.rstrip() - with open(src_file, 'r') as f: - src_lines = f.read().splitlines(keepends=True) + directive = 'sage_setup: ' f'distribution = {distribution}'.rstrip() + try: + with open(src_file, 'r') as f: + src_lines = f.read().splitlines(keepends=True) + except UnicodeDecodeError: + # Silently skip binary files + return any_found = False any_change = False for i, line in enumerate(src_lines): @@ -210,7 +214,7 @@ def update_distribution(src_file, distribution, *, verbose=False): src_lines[i] = line any_change = True if verbose: - print(f"Changed 'sage_setup: distribution' in {src_file!r} " + print(f"Changed 'sage_setup: " f"distribution' in {src_file!r} " f"from {old_distribution!r} to {distribution!r}") any_found = True if not any_found: @@ -219,7 +223,7 @@ def update_distribution(src_file, distribution, *, verbose=False): src_lines.insert(0, f'# {directive}\n') any_change = True if verbose: - print(f"Added 'sage_setup: distribution = {distribution}' " + print("Added 'sage_setup: " f"distribution = {distribution}' " f"directive in {src_file!r}") if not any_change: return @@ -246,7 +250,7 @@ def is_package_or_sage_namespace_package_dir(path, *, distribution_filter=None): - ``distribution_filter`` -- (optional, default: ``None``) only consider ``all*.py`` files whose distribution (from a - ``# sage_setup: distribution = PACKAGE`` directive in the source file) + ``# sage_setup:`` ``distribution = PACKAGE`` directive in the source file) is an element of ``distribution_filter``. EXAMPLES: From 05681086a9c68340886e288454e6e1024dd2c6b6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 22 Aug 2023 22:13:18 -0700 Subject: [PATCH 265/463] sage --fixdistributions: Add switch --from-egg-info --- src/sage/misc/package_dir.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 9a03d34e329..c00d7148510 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -1,4 +1,4 @@ -# sage_setup:distribution = sagemath-environment +# sage_setup: distribution = sagemath-environment """ Recognizing package directories """ @@ -450,12 +450,32 @@ def seen(p, m={}): "do not change files that already have a nonempty directive")) parser.add_argument('--set', metavar='distribution', type=str, default=None, help="add or update the 'sage_setup: distribution' directive in FILES") + parser.add_argument('--from-egg-info', action="store_true", default=False, + help="take FILES from pkgs/DISTRIBUTION/DISTRIBUTION.egg-info/SOURCES.txt") parser.add_argument("filename", nargs='*', type=str, - help="source files or directories (default: all file from SAGE_SRC)") + help="source files or directories (default: all files from SAGE_SRC)") args = parser.parse_args() - if not args.filename: + distribution = args.set or args.add + + if args.from_egg_info: + from sage.env import SAGE_ROOT + if not distribution: + print("Switch '--from-egg-info' must be used with either " + "'--add DISTRIBUTION' or '--set DISTRIBUTION'") + sys.exit(1) + if (not SAGE_ROOT + or not os.path.exists(os.path.join(SAGE_ROOT, 'pkgs', distribution))): + print(f'{SAGE_ROOT=} does not seem to contain a copy of the Sage source root') + sys.exit(1) + distribution_underscore = distribution.replace('-', '_') + with open(os.path.join(SAGE_ROOT, 'pkgs', distribution, + f'{distribution_underscore}.egg-info', 'SOURCES.txt'), "r") as f: + args.filename.extend(os.path.join(SAGE_ROOT, 'src', line.strip()) + for line in f + if line.startswith('sage/')) + elif not args.filename: from sage.env import SAGE_SRC if (not SAGE_SRC or not os.path.exists(os.path.join(SAGE_SRC, 'sage')) From 299e6ceb119a1ea215845a3270719f850d2d4741 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 23:18:05 -0700 Subject: [PATCH 266/463] src/doc/en/developer/packaging_sage_library.rst: Explain sage --fixdistributions --- .../en/developer/packaging_sage_library.rst | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/doc/en/developer/packaging_sage_library.rst b/src/doc/en/developer/packaging_sage_library.rst index 0244d96e5ac..bebcee72747 100644 --- a/src/doc/en/developer/packaging_sage_library.rst +++ b/src/doc/en/developer/packaging_sage_library.rst @@ -146,6 +146,30 @@ The source directory of a distribution package, such as controls which files and directories of the monolithic Sage library source tree are included in the distribution + The manifest should be kept in sync with the directives of the form + ``# sage_setup: distribution = sagemath-polyhedra`` at the top of + source files. Sage provides a tool ``sage --fixdistributions`` + that assists with this task. For example:: + + $ ./sage --fixdistributions --set sagemath-polyhedra \ + src/sage/geometry/polyhedron/base*.py + + adds or updates the directives in the specified files; and:: + + $ ./sage --fixdistributions --set sagemath-polyhedra \ + src/sage/geometry/polyhedron + + adds the directive to all files in the given directory that do not + include a directive yet. + + After a distribution has been built (for example, by the command + ``make pypi-wheels``) or at least an sdist has been built (for + example, by the command ``make sagemath_polyhedra-sdist``), the + distribution directives in all files in the source distribution + can be updated using the switch ``--from--egg-info``:: + + $ ./sage --fixdistributions --set sagemath-polyhedra --from-egg-info + - `pyproject.toml `_, `setup.cfg `_, and `requirements.txt `_ -- From db827cff3a884e6e7c0e99095c9537ae8d362668 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 23:31:22 -0700 Subject: [PATCH 267/463] sage --fixpackages: Require at least one filename with --add and --set --- src/sage/misc/package_dir.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index c00d7148510..9d427981402 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -476,6 +476,10 @@ def seen(p, m={}): for line in f if line.startswith('sage/')) elif not args.filename: + if distribution: + print("Switches '--add' and '--set' require the switch '--from-egg-info' " + "or one or more file or directory names") + sys.exit(1) from sage.env import SAGE_SRC if (not SAGE_SRC or not os.path.exists(os.path.join(SAGE_SRC, 'sage')) From a55265f98a0157c9fd7bcf90d71d5ca7fe76bb3a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 23:36:52 -0700 Subject: [PATCH 268/463] src/doc/en/developer/packaging_sage_library.rst: Explain sage --fixdistributions (fixup) --- src/doc/en/developer/packaging_sage_library.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/developer/packaging_sage_library.rst b/src/doc/en/developer/packaging_sage_library.rst index bebcee72747..de19c135a24 100644 --- a/src/doc/en/developer/packaging_sage_library.rst +++ b/src/doc/en/developer/packaging_sage_library.rst @@ -156,7 +156,7 @@ The source directory of a distribution package, such as adds or updates the directives in the specified files; and:: - $ ./sage --fixdistributions --set sagemath-polyhedra \ + $ ./sage --fixdistributions --add sagemath-polyhedra \ src/sage/geometry/polyhedron adds the directive to all files in the given directory that do not From 3e9af944f4e2c1111d424181a21ab5c56e33182b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 18:18:44 -0700 Subject: [PATCH 269/463] sage --fixdistributions: Put filename first in all messages --- src/sage/misc/package_dir.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 9d427981402..1e4656aa115 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -214,7 +214,7 @@ def update_distribution(src_file, distribution, *, verbose=False): src_lines[i] = line any_change = True if verbose: - print(f"Changed 'sage_setup: " f"distribution' in {src_file!r} " + print(f"{src_file}: changed 'sage_setup: " f"distribution' " f"from {old_distribution!r} to {distribution!r}") any_found = True if not any_found: @@ -223,8 +223,8 @@ def update_distribution(src_file, distribution, *, verbose=False): src_lines.insert(0, f'# {directive}\n') any_change = True if verbose: - print("Added 'sage_setup: " f"distribution = {distribution}' " - f"directive in {src_file!r}") + print(f"{src_file}: Added 'sage_setup: " + f"distribution = {distribution}' directive") if not any_change: return with open(src_file, 'w') as f: From d1bbc45321d8e25ece7ab5b1f47351eadd6877ae Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 18:24:44 -0700 Subject: [PATCH 270/463] sage --fixdistributions: Check all*.py and __init__.py files --- src/sage/misc/package_dir.py | 49 +++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 1e4656aa115..2d76393c031 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -16,6 +16,8 @@ import glob import re import sys + +from collections import defaultdict from contextlib import contextmanager @@ -438,6 +440,20 @@ def seen(p, m={}): yield from walk_packages(path, info.name + '.', onerror) +def _all_filename(distribution): + if not distribution: + return 'all.py' + return f"all__{distribution.replace('-', '_')}.py" + + +def _distribution_from_all_filename(filename): + if m := re.match('all(__(.*?))?[.]py', file): + if distribution_per_all_filename := m.group(2): + return distribution_per_all_filename.replace('_', '-') + return '' + return False + + if __name__ == '__main__': from argparse import ArgumentParser @@ -486,9 +502,14 @@ def seen(p, m={}): or not os.path.exists(os.path.join(SAGE_SRC, 'conftest_test.py'))): print(f'{SAGE_SRC=} does not seem to contain a copy of the Sage source tree') sys.exit(1) - args.filename = [os.path.join(SAGE_SRC, 'sage')] + args.filename = [os.path.relpath(os.path.join(SAGE_SRC, 'sage'))] - def handle_file(path): + ordinary_packages = set() + package_distributions_per_directives = defaultdict(set) # path -> set of strings (distributions) + package_distributions_per_all_files = defaultdict(set) # path -> set of strings (distributions) + + def handle_file(root, file): + path = os.path.join(root, file) if args.set is not None: update_distribution(path, args.set, verbose=True) elif args.add is not None and not read_distribution(path): @@ -496,6 +517,13 @@ def handle_file(path): else: distribution = read_distribution(path) print(f'{path}: file in distribution {distribution!r}') + package_distributions_per_directives[root].add(distribution) + if file.startswith('__init__.'): + ordinary_packages.add(root) + elif (distribution_per_all_filename := _distribution_from_all_filename(file)) is not False: + if distribution_per_all_filename != distribution: + print(f'{path}: file should go in distribution {distribution_per_all_filename!r}, not {distribution!r}') + package_distributions_per_all_files[root].add(distribution_per_all_filename) for path in args.filename: if os.path.isdir(path): @@ -514,6 +542,21 @@ def handle_file(path): for file in sorted(files): if any(file.endswith(ext) for ext in [".pyc", ".pyo", ".bak", ".so", "~"]): continue - handle_file(os.path.join(root, file)) + handle_file(root, file) else: handle_file(path) + + for package in ordinary_packages: + if len(package_distributions_per_directives[package]) > 1: + print(f'{package}: ordinary packages (with __init__.py) cannot be split in several distributions (' + + ', '.join(f'{dist!r}' + for dist in sorted(package_distributions_per_directives[package])) + ')') + + for package, distributions in package_distributions_per_directives.items(): + if package in ordinary_packages: + pass + elif ((missing_all_files := distributions - package_distributions_per_all_files[package]) + and not(missing_all_files == set(['']) and len(distributions) < 2)): + s = '' if len(missing_all_files) == 1 else 's' + print(f'{package}: missing file{s} ' + ', '.join(_all_filename(distribution) + for distribution in missing_all_files)) From 54c5b794359ab5d61f991cc7674116c600f1e278 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 19:00:17 -0700 Subject: [PATCH 271/463] src/sage/misc/package_dir.py: Make case of messages uniform --- src/sage/misc/package_dir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 2d76393c031..6e35421d17e 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -225,7 +225,7 @@ def update_distribution(src_file, distribution, *, verbose=False): src_lines.insert(0, f'# {directive}\n') any_change = True if verbose: - print(f"{src_file}: Added 'sage_setup: " + print(f"{src_file}: added 'sage_setup: " f"distribution = {distribution}' directive") if not any_change: return From b61c4915285bbce96c23f215deca75bf1aac10d4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 19:06:18 -0700 Subject: [PATCH 272/463] sage --fixdistributions: Update --help epilog --- src/sage/misc/package_dir.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 6e35421d17e..fb7ee372d8e 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -459,8 +459,7 @@ def _distribution_from_all_filename(filename): from argparse import ArgumentParser parser = ArgumentParser(description="Maintenance tool for distribution packages of the Sage library", - epilog=("Example usage:\n\n grep '^sage/' pkgs/sagemath-ntl/sagemath_ntl.egg-info/SOURCES.txt " - "| (cd src && xargs ../sage -fixdistributions --set sagemath-ntl)""")) + epilog="By default, 'sage -fixdistributions' shows the distribution of each file.") parser.add_argument('--add', metavar='distribution', type=str, default=None, help=("add a 'sage_setup: distribution' directive to FILES; " "do not change files that already have a nonempty directive")) From 59bb4292d0e91e144a5524c9b4066b4a219f4628 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 19:37:10 -0700 Subject: [PATCH 273/463] sage --fixdistributions: Improve --help --- src/sage/misc/package_dir.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index fb7ee372d8e..5eef56479da 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -458,17 +458,19 @@ def _distribution_from_all_filename(filename): from argparse import ArgumentParser - parser = ArgumentParser(description="Maintenance tool for distribution packages of the Sage library", + parser = ArgumentParser(prog="sage --fixdistributions", + description="Maintenance tool for distribution packages of the Sage library", epilog="By default, 'sage -fixdistributions' shows the distribution of each file.") - parser.add_argument('--add', metavar='distribution', type=str, default=None, - help=("add a 'sage_setup: distribution' directive to FILES; " + parser.add_argument('--add', metavar='DISTRIBUTION', type=str, default=None, + help=("add a 'sage_setup: DISTRIBUTION' directive to FILES; " "do not change files that already have a nonempty directive")) - parser.add_argument('--set', metavar='distribution', type=str, default=None, - help="add or update the 'sage_setup: distribution' directive in FILES") + parser.add_argument('--set', metavar='DISTRIBUTION', type=str, default=None, + help="add or update the 'sage_setup: DISTRIBUTION' directive in FILES") parser.add_argument('--from-egg-info', action="store_true", default=False, help="take FILES from pkgs/DISTRIBUTION/DISTRIBUTION.egg-info/SOURCES.txt") - parser.add_argument("filename", nargs='*', type=str, - help="source files or directories (default: all files from SAGE_SRC)") + parser.add_argument("filename", metavar='FILES', nargs='*', type=str, + help=("source files or directories (default: all files from SAGE_SRC, " + "unless --from-egg-info, --add, or --set are used)")) args = parser.parse_args() From df4f4050f55f4df7d8fe0497d7e3bb0260d55fef Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 23:02:58 -0700 Subject: [PATCH 274/463] src/sage/misc/package_dir.py (update_distribution): Fix for empty string as distribution --- src/sage/misc/package_dir.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 5eef56479da..70dca22865e 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -197,7 +197,7 @@ def update_distribution(src_file, distribution, *, verbose=False): directive = 'sage_setup: ' f'distribution = {distribution}'.rstrip() try: with open(src_file, 'r') as f: - src_lines = f.read().splitlines(keepends=True) + src_lines = f.read().splitlines() except UnicodeDecodeError: # Silently skip binary files return @@ -222,7 +222,7 @@ def update_distribution(src_file, distribution, *, verbose=False): if not any_found: if any(src_file.endswith(ext) for ext in [".pxd", ".pxi", ".py", ".pyx", ".sage"]): - src_lines.insert(0, f'# {directive}\n') + src_lines.insert(0, f'# {directive}') any_change = True if verbose: print(f"{src_file}: added 'sage_setup: " @@ -232,7 +232,7 @@ def update_distribution(src_file, distribution, *, verbose=False): with open(src_file, 'w') as f: for line in src_lines: if line is not None: - f.write(line) + f.write(line + '\n') def is_package_or_sage_namespace_package_dir(path, *, distribution_filter=None): From be49fa74d126313528f24a635df93721f4ba8b40 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 23:11:44 -0700 Subject: [PATCH 275/463] sage --fixdistributions: Fix handling of file args, --set/--add --- src/sage/misc/package_dir.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 70dca22865e..1d6920d28d0 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -474,7 +474,7 @@ def _distribution_from_all_filename(filename): args = parser.parse_args() - distribution = args.set or args.add + distribution = args.set or args.add or '' if args.from_egg_info: from sage.env import SAGE_ROOT @@ -513,17 +513,20 @@ def handle_file(root, file): path = os.path.join(root, file) if args.set is not None: update_distribution(path, args.set, verbose=True) - elif args.add is not None and not read_distribution(path): - update_distribution(path, args.add, verbose=True) + file_distribution = distribution + elif args.add is not None: + if not (file_distribution := read_distribution(path)): + update_distribution(path, args.add, verbose=True) + file_distribution = distribution else: - distribution = read_distribution(path) - print(f'{path}: file in distribution {distribution!r}') - package_distributions_per_directives[root].add(distribution) + file_distribution = read_distribution(path) + print(f'{path}: file in distribution {file_distribution!r}') + package_distributions_per_directives[root].add(file_distribution) if file.startswith('__init__.'): ordinary_packages.add(root) elif (distribution_per_all_filename := _distribution_from_all_filename(file)) is not False: - if distribution_per_all_filename != distribution: - print(f'{path}: file should go in distribution {distribution_per_all_filename!r}, not {distribution!r}') + if distribution_per_all_filename != file_distribution: + print(f'{path}: file should go in distribution {distribution_per_all_filename!r}, not {file_distribution!r}') package_distributions_per_all_files[root].add(distribution_per_all_filename) for path in args.filename: @@ -545,7 +548,7 @@ def handle_file(root, file): continue handle_file(root, file) else: - handle_file(path) + handle_file(*os.path.split(path)) for package in ordinary_packages: if len(package_distributions_per_directives[package]) > 1: From ebbca9998eab3a198cf9929ebfb0e6442e1e2e33 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 23:12:08 -0700 Subject: [PATCH 276/463] sage --fixdistributions: Use %(prog)s --- src/sage/misc/package_dir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 1d6920d28d0..347310dce29 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -460,7 +460,7 @@ def _distribution_from_all_filename(filename): parser = ArgumentParser(prog="sage --fixdistributions", description="Maintenance tool for distribution packages of the Sage library", - epilog="By default, 'sage -fixdistributions' shows the distribution of each file.") + epilog="By default, '%(prog)s' shows the distribution of each file.") parser.add_argument('--add', metavar='DISTRIBUTION', type=str, default=None, help=("add a 'sage_setup: DISTRIBUTION' directive to FILES; " "do not change files that already have a nonempty directive")) From af9bf68b77ead4c4bf87321328fc22160e6f030b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 27 Aug 2023 18:34:00 -0700 Subject: [PATCH 277/463] sage --fixdistributions: Fix checks --- src/sage/misc/package_dir.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 347310dce29..0fe4f932891 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -447,7 +447,7 @@ def _all_filename(distribution): def _distribution_from_all_filename(filename): - if m := re.match('all(__(.*?))?[.]py', file): + if m := re.match('all(__(.*?))?[.]py', filename): if distribution_per_all_filename := m.group(2): return distribution_per_all_filename.replace('_', '-') return '' @@ -524,7 +524,18 @@ def handle_file(root, file): package_distributions_per_directives[root].add(file_distribution) if file.startswith('__init__.'): ordinary_packages.add(root) - elif (distribution_per_all_filename := _distribution_from_all_filename(file)) is not False: + elif (distribution_per_all_filename := _distribution_from_all_filename(file)) is False: + # Not an all*.py file. + pass + elif not distribution_per_all_filename: + # An all.py file. + if file_distribution: + # The all.py is declared to belong to a named distribution, that's OK + package_distributions_per_all_files[root].add(file_distribution) + else: + pass + else: + # An all__*.py file if distribution_per_all_filename != file_distribution: print(f'{path}: file should go in distribution {distribution_per_all_filename!r}, not {file_distribution!r}') package_distributions_per_all_files[root].add(distribution_per_all_filename) From 47a89b5b67cde0c2171ebee6b0e5fa979589f404 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 27 Aug 2023 20:53:52 -0700 Subject: [PATCH 278/463] sage --fixdistributions: Allow --set/add all --from-egg-info --- src/sage/misc/package_dir.py | 110 +++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 0fe4f932891..7d106d66740 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -476,22 +476,25 @@ def _distribution_from_all_filename(filename): distribution = args.set or args.add or '' + if distribution == 'all': + distributions = ["sagemath-symbolics", + "sagemath-schemes", + "sagemath-glpk", + "sagemath-polyhedra", + "sagemath-graphs", + "sagemath-combinat", + "sagemath-modules", + "sagemath-categories", + "sagemath-repl", + "sagemath-objects"] + else: + distributions = [distribution] + if args.from_egg_info: - from sage.env import SAGE_ROOT if not distribution: print("Switch '--from-egg-info' must be used with either " "'--add DISTRIBUTION' or '--set DISTRIBUTION'") sys.exit(1) - if (not SAGE_ROOT - or not os.path.exists(os.path.join(SAGE_ROOT, 'pkgs', distribution))): - print(f'{SAGE_ROOT=} does not seem to contain a copy of the Sage source root') - sys.exit(1) - distribution_underscore = distribution.replace('-', '_') - with open(os.path.join(SAGE_ROOT, 'pkgs', distribution, - f'{distribution_underscore}.egg-info', 'SOURCES.txt'), "r") as f: - args.filename.extend(os.path.join(SAGE_ROOT, 'src', line.strip()) - for line in f - if line.startswith('sage/')) elif not args.filename: if distribution: print("Switches '--add' and '--set' require the switch '--from-egg-info' " @@ -503,7 +506,7 @@ def _distribution_from_all_filename(filename): or not os.path.exists(os.path.join(SAGE_SRC, 'conftest_test.py'))): print(f'{SAGE_SRC=} does not seem to contain a copy of the Sage source tree') sys.exit(1) - args.filename = [os.path.relpath(os.path.join(SAGE_SRC, 'sage'))] + args.filename = [os.path.join(SAGE_SRC, 'sage')] ordinary_packages = set() package_distributions_per_directives = defaultdict(set) # path -> set of strings (distributions) @@ -512,11 +515,11 @@ def _distribution_from_all_filename(filename): def handle_file(root, file): path = os.path.join(root, file) if args.set is not None: - update_distribution(path, args.set, verbose=True) + update_distribution(path, distribution, verbose=True) file_distribution = distribution elif args.add is not None: if not (file_distribution := read_distribution(path)): - update_distribution(path, args.add, verbose=True) + update_distribution(path, distribution, verbose=True) file_distribution = distribution else: file_distribution = read_distribution(path) @@ -540,26 +543,61 @@ def handle_file(root, file): print(f'{path}: file should go in distribution {distribution_per_all_filename!r}, not {file_distribution!r}') package_distributions_per_all_files[root].add(distribution_per_all_filename) - for path in args.filename: - if os.path.isdir(path): - if not is_package_or_sage_namespace_package_dir(path): - print(f'{path}: non-package directory') + for distribution in distributions: + + paths = list(args.filename) + + if args.from_egg_info: + from sage.env import SAGE_ROOT + if not distribution: + print("Switch '--from-egg-info' must be used with either " + "'--add DISTRIBUTION' or '--set DISTRIBUTION'") + sys.exit(1) + if (not SAGE_ROOT + or not os.path.exists(os.path.join(SAGE_ROOT, 'pkgs', distribution))): + print(f'{SAGE_ROOT=} does not seem to contain a copy of the Sage source root') + sys.exit(1) + distribution_underscore = distribution.replace('-', '_') + try: + with open(os.path.join(SAGE_ROOT, 'pkgs', distribution, + f'{distribution_underscore}.egg-info', 'SOURCES.txt'), "r") as f: + paths.extend(os.path.join(SAGE_ROOT, 'src', line.strip()) + for line in f + if line.startswith('sage/')) + print(f"sage --fixdistributions: found egg-info of distribution {distribution!r}") + except FileNotFoundError: + if len(distributions) > 1: + print(f"sage --fixdistributions: distribution {distribution!r} does not have egg-info, skipping it; " + f"run 'make {distribution_underscore}-sdist' or 'make {distribution_underscore}' to create it") + continue + else: + print(f"sage --fixdistributions: distribution {distribution!r} does not have egg-info; " + f"run 'make {distribution_underscore}-sdist' or 'make {distribution_underscore}' to create it") + sys.exit(1) + + for path in paths: + path = os.path.relpath(path) + if os.path.isdir(path): + if not is_package_or_sage_namespace_package_dir(path): + print(f'{path}: non-package directory') + else: + for root, dirs, files in os.walk(path): + for dir in sorted(dirs): + path = os.path.join(root, dir) + if any(dir.startswith(prefix) for prefix in ['.', 'build', 'dist', '__pycache__']): + # Silently skip + dirs.remove(dir) + elif not is_package_or_sage_namespace_package_dir(path): + print(f'{path}: non-package directory') + dirs.remove(dir) + for file in sorted(files): + if any(file.endswith(ext) for ext in [".pyc", ".pyo", ".bak", ".so", "~"]): + continue + handle_file(root, file) else: - for root, dirs, files in os.walk(path): - for dir in sorted(dirs): - path = os.path.join(root, dir) - if any(dir.startswith(prefix) for prefix in ['.', 'build', 'dist', '__pycache__']): - # Silently skip - dirs.remove(dir) - elif not is_package_or_sage_namespace_package_dir(path): - print(f'{path}: non-package directory') - dirs.remove(dir) - for file in sorted(files): - if any(file.endswith(ext) for ext in [".pyc", ".pyo", ".bak", ".so", "~"]): - continue - handle_file(root, file) - else: - handle_file(*os.path.split(path)) + handle_file(*os.path.split(path)) + + print(f"sage --fixdistributions: checking consistency") for package in ordinary_packages: if len(package_distributions_per_directives[package]) > 1: @@ -567,11 +605,11 @@ def handle_file(root, file): + ', '.join(f'{dist!r}' for dist in sorted(package_distributions_per_directives[package])) + ')') - for package, distributions in package_distributions_per_directives.items(): + for package, distributions_per_directives in package_distributions_per_directives.items(): if package in ordinary_packages: pass - elif ((missing_all_files := distributions - package_distributions_per_all_files[package]) - and not(missing_all_files == set(['']) and len(distributions) < 2)): + elif ((missing_all_files := distributions_per_directives - package_distributions_per_all_files[package]) + and not(missing_all_files == set(['']) and len(distributions_per_directives) < 2)): s = '' if len(missing_all_files) == 1 else 's' print(f'{package}: missing file{s} ' + ', '.join(_all_filename(distribution) for distribution in missing_all_files)) From e6083d5b4aa1b1f9923e7feac83b749f76bee289 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 1 Sep 2023 12:07:02 -0700 Subject: [PATCH 279/463] sage --fixdistributions: Skip directories _vendor, .tox --- src/sage/misc/package_dir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 7d106d66740..222a415bf9a 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -584,7 +584,7 @@ def handle_file(root, file): for root, dirs, files in os.walk(path): for dir in sorted(dirs): path = os.path.join(root, dir) - if any(dir.startswith(prefix) for prefix in ['.', 'build', 'dist', '__pycache__']): + if any(dir.startswith(prefix) for prefix in ['.', 'build', 'dist', '__pycache__', '_vendor', '.tox']): # Silently skip dirs.remove(dir) elif not is_package_or_sage_namespace_package_dir(path): From 71b9c3cf59c788996f4457c29288503cff29c539 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 16 Sep 2023 17:25:42 -0700 Subject: [PATCH 280/463] src/sage/misc/package_dir.py (read_distribution): Handle C comments --- src/sage/misc/package_dir.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 222a415bf9a..d0fdb98ae3e 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -125,9 +125,12 @@ def read_distribution(src_file): line = line.lstrip() if not line: continue - if line[0] != '#': + if line.startswith('#'): + line = line[1:].lstrip() + elif line.startswith('/*') or line.startswith('//'): + line = line[2:].lstrip() + else: break - line = line[1:].lstrip() kind = "sage_setup:" if line.startswith(kind): key, _, value = (s.strip() for s in line[len(kind):].partition('=')) From 13bfb6663c947efb4f8a25afa9ec00304f8a61ff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Sep 2023 20:03:17 -0700 Subject: [PATCH 281/463] src/sage/misc/package_dir.py: Normalize distribution names, improve error message --- src/sage/misc/package_dir.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index d0fdb98ae3e..6fa69176596 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -491,7 +491,7 @@ def _distribution_from_all_filename(filename): "sagemath-repl", "sagemath-objects"] else: - distributions = [distribution] + distributions = [distribution.replace('_', '-')] if args.from_egg_info: if not distribution: @@ -556,13 +556,16 @@ def handle_file(root, file): print("Switch '--from-egg-info' must be used with either " "'--add DISTRIBUTION' or '--set DISTRIBUTION'") sys.exit(1) - if (not SAGE_ROOT - or not os.path.exists(os.path.join(SAGE_ROOT, 'pkgs', distribution))): + if not SAGE_ROOT: print(f'{SAGE_ROOT=} does not seem to contain a copy of the Sage source root') sys.exit(1) + distribution_dir = os.path.join(SAGE_ROOT, 'pkgs', distribution) + if not os.path.exists(distribution_dir): + print(f'{distribution_dir} does not exist') + sys.exit(1) distribution_underscore = distribution.replace('-', '_') try: - with open(os.path.join(SAGE_ROOT, 'pkgs', distribution, + with open(os.path.join(distribution_dir, f'{distribution_underscore}.egg-info', 'SOURCES.txt'), "r") as f: paths.extend(os.path.join(SAGE_ROOT, 'src', line.strip()) for line in f From 9663e10a80d8da63c4657cf9100f6cdafedc6ea7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 22:27:30 -0700 Subject: [PATCH 282/463] src/sage/misc/package_dir.py: Also recognize Lisp comments for sage_setup directives --- src/sage/misc/package_dir.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 6fa69176596..dea5e8e421b 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -125,9 +125,9 @@ def read_distribution(src_file): line = line.lstrip() if not line: continue - if line.startswith('#'): + if line.startswith('#') or line.startswith(';'): line = line[1:].lstrip() - elif line.startswith('/*') or line.startswith('//'): + elif line.startswith('/*') or line.startswith('//') or line.startswith(';;'): line = line[2:].lstrip() else: break From 331d02a12b115eec3fdea8f3366238576977d005 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 23 Oct 2023 11:44:29 -0700 Subject: [PATCH 283/463] src/sage/misc/package_dir.py: Update distribution list --- src/sage/misc/package_dir.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index dea5e8e421b..3749a4f2a91 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -480,13 +480,13 @@ def _distribution_from_all_filename(filename): distribution = args.set or args.add or '' if distribution == 'all': - distributions = ["sagemath-symbolics", - "sagemath-schemes", - "sagemath-glpk", - "sagemath-polyhedra", - "sagemath-graphs", - "sagemath-combinat", - "sagemath-modules", + distributions = ["sagemath-bliss", + "sagemath-coxeter3", + "sagemath-mcqd", + "sagemath-meataxe", + "sagemath-sirocco", + "sagemath-tdlib", + "sagemath-environment", "sagemath-categories", "sagemath-repl", "sagemath-objects"] From 880776f622abd90b24897fe74657fec39c9bc8ee Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 23 Oct 2023 11:49:01 -0700 Subject: [PATCH 284/463] src/doc/en/developer/packaging_sage_library.rst: Document 'sage --fixdistributions --set all --from-egg-info' --- src/doc/en/developer/packaging_sage_library.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/en/developer/packaging_sage_library.rst b/src/doc/en/developer/packaging_sage_library.rst index de19c135a24..576356a9dff 100644 --- a/src/doc/en/developer/packaging_sage_library.rst +++ b/src/doc/en/developer/packaging_sage_library.rst @@ -170,6 +170,10 @@ The source directory of a distribution package, such as $ ./sage --fixdistributions --set sagemath-polyhedra --from-egg-info + To take care of all distributions, use:: + + $ ./sage --fixdistributions --set all --from-egg-info + - `pyproject.toml `_, `setup.cfg `_, and `requirements.txt `_ -- From f6fabd8956b0e7522128a1ad287e702a284c2202 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 8 Nov 2023 15:11:53 -0800 Subject: [PATCH 285/463] src/bin/sage: Suggested help string edit --- src/bin/sage | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/sage b/src/bin/sage index e5bb07e4882..ec6c356f994 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -487,8 +487,8 @@ usage_advanced() { echo " imports when sage.PAC.KAGE is an implicit namespace" echo " package" echo " --fixdistributions " - echo " -- Check or update 'sage_setup: distribution' directives" - echo " in source files" + echo " -- Check or update '# sage_setup: distribution'" + echo " directives in source files" fi echo " --sh [...] -- run a shell with Sage environment variables" echo " as they are set in the runtime of Sage" From 675a3efdf65b679cb381b4e3a7b41c1919877eb2 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Thu, 16 Nov 2023 17:10:28 +0530 Subject: [PATCH 286/463] minor changes to code style --- src/sage/graphs/generic_graph.py | 40 ++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 62dc2be2ed9..6ca953ae84a 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15748,38 +15748,42 @@ def distance_all_pairs(self, by_weight=False, algorithm=None, def power(self, k): r""" - Compute the kth power graph of an undirected, unweighted graph based on - shortest distances between nodes using BFS. + Compute the kth power graph of an unweighted graph based on shortest + distances between nodes using BFS. INPUT: - - graph: An undirected, unweighted graph. - - k: The maximum path length for considering edges in the power graph. + - ``k`` -- integer; the maximum path length for considering edges in the power graph. OUTPUT: - The kth power graph based on shortest distances between nodes. - EXAMPLE: + EXAMPLES:: + + Testing on undirected graphs:: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: k = 2 + sage: PG = G.power(k) + sage: PG.edges(sort=True, labels=False) + [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (5, 4), (4, 5)] - sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) - sage: k = 2 - sage: PG = G.power(k) - sage: PG.edges() - [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (5, 4), (4, 5)] + Testing on directed graphs:: - sage: G = DiGraph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) - sage: k = 3 - sage: PG = g.power(k) - sage: PG.edges() - [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (1, 0, None), (1, 2, None), (1, 3, None), (1, 4, None), (1, 5, None), (2, 0, None), (2, 1, None), (2, 3, None), (2, 4, None), (2, 5, None), (3, 0, None), (3, 1, None), (3, 2, None), (4, 5, None)] + sage: G = DiGraph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: k = 3 + sage: PG = g.power(k) + sage: PG.edges(sort=True, labels=False) + [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (3, 0), (3, 1), (3, 2), (4, 5)] """ - power_of_graph = self.copy() + power_of_graph = self.copy() + for u in self: for v in self.breadth_first_search(u, distance=k): if u != v: power_of_graph.add_edge(u, v) - - return power_of_graph + + return power_of_graph def girth(self, certificate=False): """ From 1f6892ca12dc6cf03d62f39205b01d4a8ae35584 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Thu, 16 Nov 2023 17:45:03 +0530 Subject: [PATCH 287/463] handling multigraphs --- src/sage/graphs/generic_graph.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 6ca953ae84a..8cabf01ee2e 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15776,12 +15776,17 @@ def power(self, k): [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (3, 0), (3, 1), (3, 2), (4, 5)] """ - power_of_graph = self.copy() + from sage.graphs.graph import DiGraph, Graph + + power_of_graph = DiGraph() if self.is_directed() else Graph() + + added_edges = set() for u in self: for v in self.breadth_first_search(u, distance=k): - if u != v: + if u != v and (u, v) not in added_edges and (v, u) not in added_edges: power_of_graph.add_edge(u, v) + added_edges.add((u, v)) return power_of_graph From 1a97d5751460e23c696af2a720e5671a0354b7bd Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Thu, 16 Nov 2023 17:50:47 +0530 Subject: [PATCH 288/463] minor fixes --- src/sage/graphs/generic_graph.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 8cabf01ee2e..2ffd6dc7405 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15780,13 +15780,10 @@ def power(self, k): power_of_graph = DiGraph() if self.is_directed() else Graph() - added_edges = set() - for u in self: for v in self.breadth_first_search(u, distance=k): - if u != v and (u, v) not in added_edges and (v, u) not in added_edges: + if u != v: power_of_graph.add_edge(u, v) - added_edges.add((u, v)) return power_of_graph From d38cf45ab6e730678a18482961d23fb70265e517 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 16 Nov 2023 16:41:21 +0100 Subject: [PATCH 289/463] implement WeierstrassIsomorphism._call_() instead of .__call__() ...so that conversions are done properly (in particular, checking that the input point is actually on the curve) --- .../elliptic_curves/weierstrass_morphism.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py index 57ff015a2b2..1874396eb53 100644 --- a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py +++ b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py @@ -611,7 +611,7 @@ def _eval(self, P): Q = baseWI.__call__(self, P) return self._codomain.base_extend(k).point(Q) - def __call__(self, P): + def _call_(self, P): r""" Call function for WeierstrassIsomorphism class. @@ -648,6 +648,21 @@ def __call__(self, P): 432 sage: E(i(P))._order 432 + + Check that the isomorphism cannot be evaluated on points outside + its domain (see :issue:`35799`):: + + sage: # needs sage.rings.finite_rings + sage: E = EllipticCurve(GF(101), [1,1]) + sage: f = E.automorphisms()[0] + sage: EE = EllipticCurve(GF(101), [5,5]) + sage: P = EE.lift_x(2) + sage: P in f.domain() + False + sage: f(P) + Traceback (most recent call last): + ... + TypeError: (2 : 15 : 1) fails to convert into the map's domain Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 101, but a `pushforward` method is not properly implemented """ if P[2] == 0: return self._codomain(0) From 94068f7824a636fae9bfdc6aeddc0163461544a0 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 17 Nov 2023 01:43:02 +0100 Subject: [PATCH 290/463] break long line --- src/sage/schemes/elliptic_curves/weierstrass_morphism.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py index 1874396eb53..0d97887106f 100644 --- a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py +++ b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py @@ -662,7 +662,10 @@ def _call_(self, P): sage: f(P) Traceback (most recent call last): ... - TypeError: (2 : 15 : 1) fails to convert into the map's domain Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 101, but a `pushforward` method is not properly implemented + TypeError: (2 : 15 : 1) fails to convert into the map's + domain Elliptic Curve defined by y^2 = x^3 + x + 1 over + Finite Field of size 101, but a `pushforward` method is + not properly implemented """ if P[2] == 0: return self._codomain(0) From 1064a501ea2116b353d6728dedf1f8d8315a390a Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Fri, 17 Nov 2023 22:59:13 +0530 Subject: [PATCH 291/463] fixed linting error --- src/sage/graphs/generic_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 2ffd6dc7405..7b53fd4e013 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15757,7 +15757,7 @@ def power(self, k): OUTPUT: - The kth power graph based on shortest distances between nodes. - EXAMPLES:: + EXAMPLES: Testing on undirected graphs:: From f10820ff877ea61a2fdbf0d7fc3c1445ead77d72 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Fri, 17 Nov 2023 23:22:26 +0100 Subject: [PATCH 292/463] Updated SageMath version to 10.2.rc4 --- 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_bliss/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_coxeter3/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_mcqd/install-requires.txt | 2 +- build/pkgs/sagemath_meataxe/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- build/pkgs/sagemath_sirocco/install-requires.txt | 2 +- build/pkgs/sagemath_tdlib/install-requires.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 38 files changed, 45 insertions(+), 45 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index eaccedc842c..d065a454dc6 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.2.rc3 +version: 10.2.rc4 doi: 10.5281/zenodo.593563 -date-released: 2023-11-14 +date-released: 2023-11-17 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 1cd43ceaa73..529cf2e0639 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.2.rc3, Release Date: 2023-11-14 +SageMath version 10.2.rc4, Release Date: 2023-11-17 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index a64b77b1f9d..9b9aa7e4339 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=46d6c98534af39c08a9cf285bb734f0b1b1c16f4 -md5=fd67403136e022a4d94abb09b2312ab5 -cksum=2017974812 +sha1=374eca6cdfb4bd3dd2d3173e300639f86407077c +md5=5810e2d5a26f7457239a576b022b0a19 +cksum=409095104 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index b2c6dd1d758..d5b0ee2fa8f 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -df85b6c0cb0cafe8ca5703fc432b0045a8a95b7a +dcd23be6c05f8de220a8404175c6e4175842255e diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 10c84f5466c..768110a40b2 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.2rc3 +sage-conf ~= 10.2rc4 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index bf58047cc02..20b4014d9c9 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.2rc3 +sage-docbuild ~= 10.2rc4 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index 5b119bfa166..e8f9803223b 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.2rc3 +sage-setup ~= 10.2rc4 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index 275c1a2a673..210e209b2b1 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.2rc3 +sage-sws2rst ~= 10.2rc4 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index fb495be5a82..041db2e12b2 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 -sagemath-standard ~= 10.2rc3 +sagemath-standard ~= 10.2rc4 diff --git a/build/pkgs/sagemath_bliss/install-requires.txt b/build/pkgs/sagemath_bliss/install-requires.txt index e814f00da2f..489dabd64e2 100644 --- a/build/pkgs/sagemath_bliss/install-requires.txt +++ b/build/pkgs/sagemath_bliss/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.2rc3 +sagemath-bliss ~= 10.2rc4 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index a34419f8856..c6b1335bb36 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.2rc3 +sagemath-categories ~= 10.2rc4 diff --git a/build/pkgs/sagemath_coxeter3/install-requires.txt b/build/pkgs/sagemath_coxeter3/install-requires.txt index 4fec4930f3a..147b0859f3c 100644 --- a/build/pkgs/sagemath_coxeter3/install-requires.txt +++ b/build/pkgs/sagemath_coxeter3/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.2rc3 +sagemath-coxeter3 ~= 10.2rc4 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index 7816ad65151..7a744b52d45 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.2rc3 +sagemath-environment ~= 10.2rc4 diff --git a/build/pkgs/sagemath_mcqd/install-requires.txt b/build/pkgs/sagemath_mcqd/install-requires.txt index 0c7b94d7211..6aa36800227 100644 --- a/build/pkgs/sagemath_mcqd/install-requires.txt +++ b/build/pkgs/sagemath_mcqd/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.2rc3 +sagemath-mcqd ~= 10.2rc4 diff --git a/build/pkgs/sagemath_meataxe/install-requires.txt b/build/pkgs/sagemath_meataxe/install-requires.txt index 88049a9fe7e..f94e1aac639 100644 --- a/build/pkgs/sagemath_meataxe/install-requires.txt +++ b/build/pkgs/sagemath_meataxe/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.2rc3 +sagemath-meataxe ~= 10.2rc4 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index e3d5b03e30a..772df655f0d 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.2rc3 +sagemath-objects ~= 10.2rc4 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 65317d670db..850ce7e19d3 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.2rc3 +sagemath-repl ~= 10.2rc4 diff --git a/build/pkgs/sagemath_sirocco/install-requires.txt b/build/pkgs/sagemath_sirocco/install-requires.txt index 78b8532eb3c..f3cc76b26fa 100644 --- a/build/pkgs/sagemath_sirocco/install-requires.txt +++ b/build/pkgs/sagemath_sirocco/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.2rc3 +sagemath-sirocco ~= 10.2rc4 diff --git a/build/pkgs/sagemath_tdlib/install-requires.txt b/build/pkgs/sagemath_tdlib/install-requires.txt index fd4b8549a2e..bffa6c8223c 100644 --- a/build/pkgs/sagemath_tdlib/install-requires.txt +++ b/build/pkgs/sagemath_tdlib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.2rc3 +sagemath-tdlib ~= 10.2rc4 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/src/VERSION.txt b/src/VERSION.txt index 47b62e8563a..6bdcf0406e9 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.2.rc3 +10.2.rc4 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index fd00471303b..c2a6f2749ae 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.2.rc3' -SAGE_RELEASE_DATE='2023-11-14' -SAGE_VERSION_BANNER='SageMath version 10.2.rc3, Release Date: 2023-11-14' +SAGE_VERSION='10.2.rc4' +SAGE_RELEASE_DATE='2023-11-17' +SAGE_VERSION_BANNER='SageMath version 10.2.rc4, Release Date: 2023-11-17' diff --git a/src/sage/version.py b/src/sage/version.py index 528136535fa..106eb6564e7 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.2.rc3' -date = '2023-11-14' -banner = 'SageMath version 10.2.rc3, Release Date: 2023-11-14' +version = '10.2.rc4' +date = '2023-11-17' +banner = 'SageMath version 10.2.rc4, Release Date: 2023-11-17' From 15f0e90cfbf55665391798a753e203002446a817 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 16:20:50 -0800 Subject: [PATCH 293/463] build/pkgs/pillow/spkg-install.in: Allow discovery of libjpeg --- build/pkgs/pillow/spkg-install.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/pillow/spkg-install.in b/build/pkgs/pillow/spkg-install.in index e76b30f7383..0d04dc4ec2d 100644 --- a/build/pkgs/pillow/spkg-install.in +++ b/build/pkgs/pillow/spkg-install.in @@ -6,6 +6,6 @@ if [ "$CONDA_PREFIX" != "" ]; then PILLOW_CONFIG_SETTINGS="$PILLOW_CONFIG_SETTINGS -C platform-guessing=disable" fi -PILLOW_CONFIG_SETTINGS="-C debug=true -C jpeg=disable $PILLOW_CONFIG_SETTINGS" +PILLOW_CONFIG_SETTINGS="-C debug=true $PILLOW_CONFIG_SETTINGS" eval sdh_pip_install $PILLOW_CONFIG_SETTINGS . From 565bc0d410f5e97e07bff924eb28c3d1006fa496 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 17:42:31 -0800 Subject: [PATCH 294/463] build/pkgs/pillow: Update to 10.1.0 --- build/pkgs/pillow/checksums.ini | 6 +++--- build/pkgs/pillow/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/pillow/checksums.ini b/build/pkgs/pillow/checksums.ini index afa97cc028f..48c6c3f46ae 100644 --- a/build/pkgs/pillow/checksums.ini +++ b/build/pkgs/pillow/checksums.ini @@ -1,5 +1,5 @@ tarball=Pillow-VERSION.tar.gz -sha1=47c1f2179bc7de5e3413feed08f7a859854030c3 -md5=93a0585ab0ee9717a7576129bdabdf93 -cksum=3176045361 +sha1=be2dc6aeee145894f3ccbc2358a37f7849e710aa +md5=a55618c5d2fd64048dd3ea41bc39f7cd +cksum=3616378816 upstream_url=https://pypi.io/packages/source/p/pillow/Pillow-VERSION.tar.gz diff --git a/build/pkgs/pillow/package-version.txt b/build/pkgs/pillow/package-version.txt index 1532420512a..4149c39eec6 100644 --- a/build/pkgs/pillow/package-version.txt +++ b/build/pkgs/pillow/package-version.txt @@ -1 +1 @@ -10.0.1 +10.1.0 From b06fbad6fb493093ea47e4697ed2497dad097464 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 18:07:32 -0800 Subject: [PATCH 295/463] build/pkgs/_recommended/dependencies: Add libjpeg --- build/pkgs/_recommended/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/_recommended/dependencies b/build/pkgs/_recommended/dependencies index 6400b71fe7d..f4baa9b1fb2 100644 --- a/build/pkgs/_recommended/dependencies +++ b/build/pkgs/_recommended/dependencies @@ -1 +1 @@ -pandoc ffmpeg imagemagick texlive git +pandoc ffmpeg imagemagick texlive git libjpeg From 13b1115ee3a4b37c85d362a2b2416f526b8f9c33 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 18:17:36 -0800 Subject: [PATCH 296/463] build/pkgs/libjpeg: New optional dummy package --- build/pkgs/libjpeg/SPKG.rst | 10 ++++++++++ build/pkgs/libjpeg/distros/alpine.txt | 1 + build/pkgs/libjpeg/distros/arch.txt | 1 + build/pkgs/libjpeg/distros/debian.txt | 1 + build/pkgs/libjpeg/distros/fedora.txt | 1 + build/pkgs/libjpeg/distros/gentoo.txt | 1 + build/pkgs/libjpeg/distros/homebrew.txt | 1 + build/pkgs/libjpeg/distros/nix.txt | 1 + build/pkgs/libjpeg/distros/opensuse.txt | 1 + build/pkgs/libjpeg/distros/slackware.txt | 1 + build/pkgs/libjpeg/distros/void.txt | 1 + build/pkgs/libjpeg/type | 1 + build/pkgs/pandoc/SPKG.rst | 4 ++-- 13 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 build/pkgs/libjpeg/SPKG.rst create mode 100644 build/pkgs/libjpeg/distros/alpine.txt create mode 100644 build/pkgs/libjpeg/distros/arch.txt create mode 100644 build/pkgs/libjpeg/distros/debian.txt create mode 100644 build/pkgs/libjpeg/distros/fedora.txt create mode 100644 build/pkgs/libjpeg/distros/gentoo.txt create mode 100644 build/pkgs/libjpeg/distros/homebrew.txt create mode 100644 build/pkgs/libjpeg/distros/nix.txt create mode 100644 build/pkgs/libjpeg/distros/opensuse.txt create mode 100644 build/pkgs/libjpeg/distros/slackware.txt create mode 100644 build/pkgs/libjpeg/distros/void.txt create mode 100644 build/pkgs/libjpeg/type diff --git a/build/pkgs/libjpeg/SPKG.rst b/build/pkgs/libjpeg/SPKG.rst new file mode 100644 index 00000000000..3127c057c96 --- /dev/null +++ b/build/pkgs/libjpeg/SPKG.rst @@ -0,0 +1,10 @@ +libjpeg: JPEG image support +=========================== + +Description +----------- + +This dummy package represents the image library ``libjpeg``. + +We do not have an SPKG for it. The purpose of this dummy package is to +associate system package lists with it. diff --git a/build/pkgs/libjpeg/distros/alpine.txt b/build/pkgs/libjpeg/distros/alpine.txt new file mode 100644 index 00000000000..eff1bd137fb --- /dev/null +++ b/build/pkgs/libjpeg/distros/alpine.txt @@ -0,0 +1 @@ +libjpeg-turbo-dev diff --git a/build/pkgs/libjpeg/distros/arch.txt b/build/pkgs/libjpeg/distros/arch.txt new file mode 100644 index 00000000000..9cd50353517 --- /dev/null +++ b/build/pkgs/libjpeg/distros/arch.txt @@ -0,0 +1 @@ +libjpeg-turbo diff --git a/build/pkgs/libjpeg/distros/debian.txt b/build/pkgs/libjpeg/distros/debian.txt new file mode 100644 index 00000000000..0202c510b4d --- /dev/null +++ b/build/pkgs/libjpeg/distros/debian.txt @@ -0,0 +1 @@ +libjpeg-dev diff --git a/build/pkgs/libjpeg/distros/fedora.txt b/build/pkgs/libjpeg/distros/fedora.txt new file mode 100644 index 00000000000..1a9c66f7497 --- /dev/null +++ b/build/pkgs/libjpeg/distros/fedora.txt @@ -0,0 +1 @@ +libjpeg-turbo-devel diff --git a/build/pkgs/libjpeg/distros/gentoo.txt b/build/pkgs/libjpeg/distros/gentoo.txt new file mode 100644 index 00000000000..f729cd7a3e3 --- /dev/null +++ b/build/pkgs/libjpeg/distros/gentoo.txt @@ -0,0 +1 @@ +media-libs/libjpeg-turbo diff --git a/build/pkgs/libjpeg/distros/homebrew.txt b/build/pkgs/libjpeg/distros/homebrew.txt new file mode 100644 index 00000000000..6efed7bed64 --- /dev/null +++ b/build/pkgs/libjpeg/distros/homebrew.txt @@ -0,0 +1 @@ +jpeg-turbo diff --git a/build/pkgs/libjpeg/distros/nix.txt b/build/pkgs/libjpeg/distros/nix.txt new file mode 100644 index 00000000000..9cd50353517 --- /dev/null +++ b/build/pkgs/libjpeg/distros/nix.txt @@ -0,0 +1 @@ +libjpeg-turbo diff --git a/build/pkgs/libjpeg/distros/opensuse.txt b/build/pkgs/libjpeg/distros/opensuse.txt new file mode 100644 index 00000000000..e64e9089096 --- /dev/null +++ b/build/pkgs/libjpeg/distros/opensuse.txt @@ -0,0 +1 @@ +libjpeg-devel diff --git a/build/pkgs/libjpeg/distros/slackware.txt b/build/pkgs/libjpeg/distros/slackware.txt new file mode 100644 index 00000000000..9cd50353517 --- /dev/null +++ b/build/pkgs/libjpeg/distros/slackware.txt @@ -0,0 +1 @@ +libjpeg-turbo diff --git a/build/pkgs/libjpeg/distros/void.txt b/build/pkgs/libjpeg/distros/void.txt new file mode 100644 index 00000000000..1a9c66f7497 --- /dev/null +++ b/build/pkgs/libjpeg/distros/void.txt @@ -0,0 +1 @@ +libjpeg-turbo-devel diff --git a/build/pkgs/libjpeg/type b/build/pkgs/libjpeg/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/libjpeg/type @@ -0,0 +1 @@ +optional diff --git a/build/pkgs/pandoc/SPKG.rst b/build/pkgs/pandoc/SPKG.rst index b7fda6cc990..a511f0ebe86 100644 --- a/build/pkgs/pandoc/SPKG.rst +++ b/build/pkgs/pandoc/SPKG.rst @@ -4,7 +4,7 @@ pandoc: A document converter Description ----------- -This script package represents the document converter pandoc. +This dummy package represents the document converter pandoc. -We do not have an SPKG for it. The purpose of this script package is to +We do not have an SPKG for it. The purpose of this dummy package is to associate system package lists with it. From a6c4ad441ddc873b8394258e7ed0eca72749368e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 18:19:29 -0800 Subject: [PATCH 297/463] build/pkgs/libjpeg/SPKG.rst: Explain why useful --- build/pkgs/libjpeg/SPKG.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/pkgs/libjpeg/SPKG.rst b/build/pkgs/libjpeg/SPKG.rst index 3127c057c96..edd96c18593 100644 --- a/build/pkgs/libjpeg/SPKG.rst +++ b/build/pkgs/libjpeg/SPKG.rst @@ -8,3 +8,6 @@ This dummy package represents the image library ``libjpeg``. We do not have an SPKG for it. The purpose of this dummy package is to associate system package lists with it. + +If the system package is installed, the package ``pillow`` will include +support for JPEG images. From 49275fcf1bcc6c0065594c6867424517efe574d2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 19:19:44 -0800 Subject: [PATCH 298/463] build/pkgs/libjpeg/spkg-configure.m4: New --- build/pkgs/libjpeg/spkg-configure.m4 | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 build/pkgs/libjpeg/spkg-configure.m4 diff --git a/build/pkgs/libjpeg/spkg-configure.m4 b/build/pkgs/libjpeg/spkg-configure.m4 new file mode 100644 index 00000000000..5cd85cb16c3 --- /dev/null +++ b/build/pkgs/libjpeg/spkg-configure.m4 @@ -0,0 +1,3 @@ +SAGE_SPKG_CONFIGURE([libjpeg], [ + PKG_CHECK_MODULES([libjpeg], [libjpeg], [], [sage_spkg_install_libjpeg=yes]) +]) From 1d8f416ef2be06a157974603f6de111fce66938b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 20:52:48 -0800 Subject: [PATCH 299/463] build/pkgs/pillow/spkg-install.in: Remove outdated comment --- build/pkgs/pillow/spkg-install.in | 2 -- 1 file changed, 2 deletions(-) diff --git a/build/pkgs/pillow/spkg-install.in b/build/pkgs/pillow/spkg-install.in index 0d04dc4ec2d..44fdeb296e1 100644 --- a/build/pkgs/pillow/spkg-install.in +++ b/build/pkgs/pillow/spkg-install.in @@ -1,8 +1,6 @@ cd src if [ "$CONDA_PREFIX" != "" ]; then - # Quoted quotes so that whitespace in CONDA_PREFIX works correctly. - # Below we run the command line through eval. PILLOW_CONFIG_SETTINGS="$PILLOW_CONFIG_SETTINGS -C platform-guessing=disable" fi From c56760c6884801598d8239745f6d550b96404e16 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 18 Nov 2023 07:44:43 -0800 Subject: [PATCH 300/463] Pass SAGE_HAVE_LIBJPEG from configure to pillow spkg-install --- build/bin/sage-build-env-config.in | 2 ++ build/pkgs/libjpeg/spkg-configure.m4 | 6 +++++- build/pkgs/pillow/spkg-install.in | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/build/bin/sage-build-env-config.in b/build/bin/sage-build-env-config.in index 7d6cd113bf9..c1eb4dfe101 100644 --- a/build/bin/sage-build-env-config.in +++ b/build/bin/sage-build-env-config.in @@ -58,6 +58,8 @@ export SAGE_SUITESPARSE_PREFIX="@SAGE_SUITESPARSE_PREFIX@" export SAGE_CONFIGURE_FFLAS_FFPACK="@SAGE_CONFIGURE_FFLAS_FFPACK@" +export SAGE_HAVE_LIBJPEG="@SAGE_HAVE_LIBJPEG@" + export CONFIGURED_SAGE_EDITABLE="@SAGE_EDITABLE@" export CONFIGURED_SAGE_WHEELS="@SAGE_WHEELS@" diff --git a/build/pkgs/libjpeg/spkg-configure.m4 b/build/pkgs/libjpeg/spkg-configure.m4 index 5cd85cb16c3..6eba941222b 100644 --- a/build/pkgs/libjpeg/spkg-configure.m4 +++ b/build/pkgs/libjpeg/spkg-configure.m4 @@ -1,3 +1,7 @@ SAGE_SPKG_CONFIGURE([libjpeg], [ - PKG_CHECK_MODULES([libjpeg], [libjpeg], [], [sage_spkg_install_libjpeg=yes]) + PKG_CHECK_MODULES([libjpeg], [libjpeg], [ + AC_SUBST([SAGE_HAVE_LIBJPEG], [1]) + ], [ + sage_spkg_install_libjpeg=yes + ]) ]) diff --git a/build/pkgs/pillow/spkg-install.in b/build/pkgs/pillow/spkg-install.in index 44fdeb296e1..1d9d6139fe7 100644 --- a/build/pkgs/pillow/spkg-install.in +++ b/build/pkgs/pillow/spkg-install.in @@ -4,6 +4,10 @@ if [ "$CONDA_PREFIX" != "" ]; then PILLOW_CONFIG_SETTINGS="$PILLOW_CONFIG_SETTINGS -C platform-guessing=disable" fi +if [ "$SAGE_HAVE_LIBJPEG" != 1 ]; then + PILLOW_CONFIG_SETTINGS="-C jpeg=disable $PILLOW_CONFIG_SETTINGS" +fi + PILLOW_CONFIG_SETTINGS="-C debug=true $PILLOW_CONFIG_SETTINGS" eval sdh_pip_install $PILLOW_CONFIG_SETTINGS . From 643145f4a7be8e2e0b2da2944bdf33afc0e6e6cc Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Sat, 18 Nov 2023 22:42:51 +0530 Subject: [PATCH 301/463] fixed linting errors --- src/sage/graphs/generic_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 7b53fd4e013..c4c26918a43 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15745,7 +15745,7 @@ def distance_all_pairs(self, by_weight=False, algorithm=None, algorithm=algorithm, weight_function=weight_function, check_weight=check_weight)[0] - + def power(self, k): r""" Compute the kth power graph of an unweighted graph based on shortest From 5656d941339a3cd7e0e1ef9dfa70c22b3427aecb Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Sat, 18 Nov 2023 22:54:50 +0530 Subject: [PATCH 302/463] fixed linting errors --- src/sage/graphs/generic_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index c4c26918a43..be72d61ecae 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15745,7 +15745,7 @@ def distance_all_pairs(self, by_weight=False, algorithm=None, algorithm=algorithm, weight_function=weight_function, check_weight=check_weight)[0] - + def power(self, k): r""" Compute the kth power graph of an unweighted graph based on shortest From 0dcbeba20474413cd566d8e1dd06858ff899505f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 18 Nov 2023 11:05:29 -0800 Subject: [PATCH 303/463] .github/workflows/ci-linux-incremental.yml: Do not try to build dummy packages --- .github/workflows/ci-linux-incremental.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-linux-incremental.yml b/.github/workflows/ci-linux-incremental.yml index 7887597845c..f9e6767975e 100644 --- a/.github/workflows/ci-linux-incremental.yml +++ b/.github/workflows/ci-linux-incremental.yml @@ -61,7 +61,7 @@ jobs: id: build-targets run: | echo "uninstall_targets=$(echo $(for a in '' ${{ steps.changed-packages.outputs.configures_all_changed_files }}; do echo $a | sed -E 's,build/pkgs/([_.a-z0-9]*)/spkg-configure[.]m4 *,\1-uninstall,'; done | sort -u))" >> $GITHUB_OUTPUT - echo "build_targets=$(echo $(for a in '' ${{ steps.changed-packages.outputs.pkgs_all_changed_files }}; do echo $a | sed -E 's,-,_,g;s,(build/)?pkgs/([-_.a-z0-9]*)/[^ ]* *,\2-ensure,;'; done | sort -u))" >> $GITHUB_OUTPUT + echo "build_targets=$(echo $(for a in '' ${{ steps.changed-packages.outputs.pkgs_all_changed_files }}; do SPKG=$(echo $a | sed -E 's,-,_,g;s,(build/)?pkgs/([-_.a-z0-9]*)/[^ ]* *,\2,;'); if [ -f "build/pkgs/$SPKG/checksums.ini" -o -f "build/pkgs/$SPKG/requirements.txt" -o -f "build/pkgs/$SPKG/spkg-install" ]; then echo "$SPKG-ensure"; fi; done | sort -u))" >> $GITHUB_OUTPUT cat $GITHUB_OUTPUT test: From 30d5a7e0710513599e572c691cd9b033b008a964 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 18 Nov 2023 11:10:48 -0800 Subject: [PATCH 304/463] .github/workflows/ci-linux-incremental.yml: Do not try to build _... packages --- .github/workflows/ci-linux-incremental.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-linux-incremental.yml b/.github/workflows/ci-linux-incremental.yml index f9e6767975e..ff3260980d3 100644 --- a/.github/workflows/ci-linux-incremental.yml +++ b/.github/workflows/ci-linux-incremental.yml @@ -60,8 +60,8 @@ jobs: - name: Determine targets to build id: build-targets run: | - echo "uninstall_targets=$(echo $(for a in '' ${{ steps.changed-packages.outputs.configures_all_changed_files }}; do echo $a | sed -E 's,build/pkgs/([_.a-z0-9]*)/spkg-configure[.]m4 *,\1-uninstall,'; done | sort -u))" >> $GITHUB_OUTPUT - echo "build_targets=$(echo $(for a in '' ${{ steps.changed-packages.outputs.pkgs_all_changed_files }}; do SPKG=$(echo $a | sed -E 's,-,_,g;s,(build/)?pkgs/([-_.a-z0-9]*)/[^ ]* *,\2,;'); if [ -f "build/pkgs/$SPKG/checksums.ini" -o -f "build/pkgs/$SPKG/requirements.txt" -o -f "build/pkgs/$SPKG/spkg-install" ]; then echo "$SPKG-ensure"; fi; done | sort -u))" >> $GITHUB_OUTPUT + echo "uninstall_targets=$(echo $(for a in '' ${{ steps.changed-packages.outputs.configures_all_changed_files }}; do echo $a | sed -E 's,build/pkgs/([a-z0-9][_.a-z0-9]*)/spkg-configure[.]m4 *,\1-uninstall,'; done | sort -u))" >> $GITHUB_OUTPUT + echo "build_targets=$(echo $(for a in '' ${{ steps.changed-packages.outputs.pkgs_all_changed_files }}; do SPKG=$(echo $a | sed -E 's,-,_,g;s,(build/)?pkgs/([a-z0-9][-_.a-z0-9]*)/[^ ]* *,\2,;'); if [ -f "build/pkgs/$SPKG/checksums.ini" -o -f "build/pkgs/$SPKG/requirements.txt" -o -f "build/pkgs/$SPKG/spkg-install" ]; then echo "$SPKG-ensure"; fi; done | sort -u))" >> $GITHUB_OUTPUT cat $GITHUB_OUTPUT test: From c5b6f9d3252f9ca646e4257aebdaccf6053b4800 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 19 Nov 2023 12:47:57 -0800 Subject: [PATCH 305/463] build/sage_bootstrap/uninstall.py: Fix handling of piprm --- build/sage_bootstrap/uninstall.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/build/sage_bootstrap/uninstall.py b/build/sage_bootstrap/uninstall.py index 7cd808d0fe7..5940672b977 100644 --- a/build/sage_bootstrap/uninstall.py +++ b/build/sage_bootstrap/uninstall.py @@ -172,6 +172,17 @@ def modern_uninstall(spkg_name, sage_local, files, verbose=False): else: sys.exit(1) + # Run the package's piprm script, if it exists. + # Since #36452 the spkg-requirements.txt file appears in the installation + # manifest, so this step has to happen before removing the files. + try: + run_spkg_script(spkg_name, spkg_scripts, 'piprm', + 'pip-uninstall') + except Exception: + print("Warning: Error running the pip-uninstall script for " + "'{0}'; uninstallation may have left behind some files".format( + spkg_name), file=sys.stderr) + def rmdir(dirname): if pth.isdir(dirname): if not os.listdir(dirname): @@ -200,15 +211,6 @@ def rmdir(dirname): # Remove file's directory if it is now empty rmdir(dirname) - # Run the package's piprm script, if it exists. - try: - run_spkg_script(spkg_name, spkg_scripts, 'piprm', - 'pip-uninstall') - except Exception: - print("Warning: Error running the pip-uninstall script for " - "'{0}'; uninstallation may have left behind some files".format( - spkg_name), file=sys.stderr) - # Run the package's postrm script, if it exists. # If an error occurs here print a warning, but complete the # uninstallation; otherwise we leave the package in a broken From 7e3d4c16bd8a708aa38f1ddccc5b8dd79e1b472f Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sun, 25 Jun 2023 13:12:55 +0100 Subject: [PATCH 306/463] spkg-config for bliss, with a version check etc --- build/pkgs/bliss/distros/fedora.txt | 2 ++ build/pkgs/bliss/spkg-configure.m4 | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 build/pkgs/bliss/distros/fedora.txt create mode 100644 build/pkgs/bliss/spkg-configure.m4 diff --git a/build/pkgs/bliss/distros/fedora.txt b/build/pkgs/bliss/distros/fedora.txt new file mode 100644 index 00000000000..681ebb3f402 --- /dev/null +++ b/build/pkgs/bliss/distros/fedora.txt @@ -0,0 +1,2 @@ +bliss +bliss-devel diff --git a/build/pkgs/bliss/spkg-configure.m4 b/build/pkgs/bliss/spkg-configure.m4 new file mode 100644 index 00000000000..4c75013ac27 --- /dev/null +++ b/build/pkgs/bliss/spkg-configure.m4 @@ -0,0 +1,29 @@ +SAGE_SPKG_CONFIGURE([bliss], [ + m4_pushdef([SAGE_BLISS_MINVER],[0.77]) + m4_pushdef([SAGE_BLISS_MAJOR],[0]) + m4_pushdef([SAGE_BLISS_MINOR],[77]) + SAGE_SPKG_DEPCHECK([cmake], [ + AC_CHECK_HEADER([bliss/bliss_C.h], [ + AC_SEARCH_LIBS([bliss_new], [bliss], [ + AC_MSG_CHECKING([checking bliss version directly]) + AC_RUN_IFELSE([AC_LANG_PROGRAM([ + [#include + ]],[[ + if (BLISS_VERSION_MAJOR > ]] SAGE_BLISS_MAJOR [[ ) return 0; + if (BLISS_VERSION_MAJOR == ]] SAGE_BLISS_MAJOR [[ && + BLISS_VERSION_MINOR >= ]] SAGE_BLISS_MINOR [[ ) return 0; + else return 1; + ]])], + [AC_MSG_RESULT([Good.])], + [AC_MSG_RESULT([Too old.]) + sage_spkg_install_bliss=yes], + []) dnl cross-compilation - noop + ], + [sage_spkg_install_bliss=yes]) + ], [sage_spkg_install_bliss=yes]) + ]) + m4_popdef([SAGE_BLISS_MINVER]) + m4_popdef([SAGE_BLISS_MAJOR]) + m4_popdef([SAGE_BLISS_MINOR]) +]) + From 0ad40ea39dbbedc74f31ee5b57aa89f976612633 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Wed, 28 Jun 2023 09:05:48 +0100 Subject: [PATCH 307/463] no need for empty deps section --- build/pkgs/bliss/SPKG.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build/pkgs/bliss/SPKG.rst b/build/pkgs/bliss/SPKG.rst index 77407f16ac7..8abc6975ddf 100644 --- a/build/pkgs/bliss/SPKG.rst +++ b/build/pkgs/bliss/SPKG.rst @@ -23,8 +23,3 @@ https://users.aalto.fi/~tjunttil/bliss/index.html Bliss used to be maintained by Tommi Junttila and Petteri Kaski up to version 0.73 at http://www.tcs.tkk.fi/Software/bliss/index.html - -Dependencies ------------- - -None From dd30a2a026bc8e74dafbd86196acfceda6c449c0 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Wed, 28 Jun 2023 09:10:27 +0100 Subject: [PATCH 308/463] no need to check for external cmake --- build/pkgs/bliss/spkg-configure.m4 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/build/pkgs/bliss/spkg-configure.m4 b/build/pkgs/bliss/spkg-configure.m4 index 4c75013ac27..052d6d1e5e3 100644 --- a/build/pkgs/bliss/spkg-configure.m4 +++ b/build/pkgs/bliss/spkg-configure.m4 @@ -2,8 +2,7 @@ SAGE_SPKG_CONFIGURE([bliss], [ m4_pushdef([SAGE_BLISS_MINVER],[0.77]) m4_pushdef([SAGE_BLISS_MAJOR],[0]) m4_pushdef([SAGE_BLISS_MINOR],[77]) - SAGE_SPKG_DEPCHECK([cmake], [ - AC_CHECK_HEADER([bliss/bliss_C.h], [ + AC_CHECK_HEADER([bliss/bliss_C.h], [ AC_SEARCH_LIBS([bliss_new], [bliss], [ AC_MSG_CHECKING([checking bliss version directly]) AC_RUN_IFELSE([AC_LANG_PROGRAM([ @@ -20,8 +19,7 @@ SAGE_SPKG_CONFIGURE([bliss], [ []) dnl cross-compilation - noop ], [sage_spkg_install_bliss=yes]) - ], [sage_spkg_install_bliss=yes]) - ]) + ], [sage_spkg_install_bliss=yes]) m4_popdef([SAGE_BLISS_MINVER]) m4_popdef([SAGE_BLISS_MAJOR]) m4_popdef([SAGE_BLISS_MINOR]) From 75c1ccaa4b01c14ad725f3a6aca7d8844e653179 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 9 Oct 2023 12:49:19 +0100 Subject: [PATCH 309/463] alpine distinfo for bliss --- build/pkgs/bliss/distros/alpine.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 build/pkgs/bliss/distros/alpine.txt diff --git a/build/pkgs/bliss/distros/alpine.txt b/build/pkgs/bliss/distros/alpine.txt new file mode 100644 index 00000000000..d90d94bbcc3 --- /dev/null +++ b/build/pkgs/bliss/distros/alpine.txt @@ -0,0 +1 @@ +bliss From ffcd2bc6c31bad84bf81e476c6357a70d999a4d1 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Mon, 20 Nov 2023 17:58:56 +0530 Subject: [PATCH 310/463] added more doctests and improved code style --- src/sage/graphs/generic_graph.py | 55 +++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index be72d61ecae..3573b502665 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15752,9 +15752,12 @@ def power(self, k): distances between nodes using BFS. INPUT: - - ``k`` -- integer; the maximum path length for considering edges in the power graph. + + - ``k`` -- integer; the maximum path length for considering edges in the power + graph. OUTPUT: + - The kth power graph based on shortest distances between nodes. EXAMPLES: @@ -15765,18 +15768,62 @@ def power(self, k): sage: k = 2 sage: PG = G.power(k) sage: PG.edges(sort=True, labels=False) - [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (5, 4), (4, 5)] + [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (2, 5), (3, 4), (4, 5)] Testing on directed graphs:: sage: G = DiGraph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) sage: k = 3 - sage: PG = g.power(k) + sage: PG = G.power(k) sage: PG.edges(sort=True, labels=False) [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (3, 0), (3, 1), (3, 2), (4, 5)] + TESTS: + + Testing when k < 0:: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: k = -2 + sage: PG = G.power(k) + Traceback (most recent call last) + ... + ValueError: distance must be a non-negative integer, not -2 + + Testing when k = 0:: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: k = 0 + sage: PG = G.power(k) + sage: PG.edges(sort=True, labels=False) + [] + + Testing when k = 1:: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: k = 1 + sage: PG = G.power(k) + sage: PG.edges(sort=True, labels=False) + [(0, 1), (0, 3), (1, 2), (2, 3), (2, 4), (4, 5)] + + Testing when k = Infinity:: + + sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: k = Infinity + sage: PG = G.power(k) + Traceback (most recent call last) + ... + ValueError: distance must be a non-negative integer, not +Infinity + + Testing on graph with multiple edges:: + + sage: G = DiGraph([(0, 1), (0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: k = 3 + sage: PG = G.power(k) + sage: PG.edges(sort=True, labels=False) + [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (3, 0), (3, 1), (3, 2), (4, 5)] """ - from sage.graphs.graph import DiGraph, Graph + from sage.graphs.digraph import DiGraph + from sage.graphs.graph import Graph power_of_graph = DiGraph() if self.is_directed() else Graph() From b4a347a694ca12d44a7539fa2bb4111bca49ca33 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Mon, 20 Nov 2023 18:07:07 +0530 Subject: [PATCH 311/463] fixed linting errors --- src/sage/graphs/generic_graph.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 3573b502665..564fc071d53 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15753,8 +15753,7 @@ def power(self, k): INPUT: - - ``k`` -- integer; the maximum path length for considering edges in the power - graph. + - ``k`` -- integer; the maximum path length for considering edges in the power graph. OUTPUT: From dbb85c3ecfa830f509487acdc05437b71172c7bb Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Mon, 20 Nov 2023 23:27:54 +0530 Subject: [PATCH 312/463] fixed error in doctests --- src/sage/graphs/generic_graph.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 564fc071d53..e6c8756e5f2 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15753,7 +15753,8 @@ def power(self, k): INPUT: - - ``k`` -- integer; the maximum path length for considering edges in the power graph. + - ``k`` -- integer; the maximum path length for considering edges in + the power graph. OUTPUT: @@ -15784,7 +15785,7 @@ def power(self, k): sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) sage: k = -2 sage: PG = G.power(k) - Traceback (most recent call last) + Traceback (most recent call last): ... ValueError: distance must be a non-negative integer, not -2 @@ -15809,7 +15810,7 @@ def power(self, k): sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) sage: k = Infinity sage: PG = G.power(k) - Traceback (most recent call last) + Traceback (most recent call last): ... ValueError: distance must be a non-negative integer, not +Infinity From a19186171ae1c7571b7f35e7254037905868da91 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 21 Nov 2023 05:26:02 +0000 Subject: [PATCH 313/463] Remove fallback for output directory --- src/sage_setup/autogen/interpreters/__main__.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/sage_setup/autogen/interpreters/__main__.py b/src/sage_setup/autogen/interpreters/__main__.py index 96b25d61551..398a7b30039 100644 --- a/src/sage_setup/autogen/interpreters/__main__.py +++ b/src/sage_setup/autogen/interpreters/__main__.py @@ -1,16 +1,11 @@ +# Usage: python -m sage_setup.autogen.interpreters + import argparse -import os from . import rebuild parser = argparse.ArgumentParser() -parser.add_argument("output_dir") +parser.add_argument("output_dir", help="Output directory") args = parser.parse_args() -output_dir = args.output_dir -if not output_dir: - from sage.env import SAGE_SRC - output_dir = os.path.join(SAGE_SRC, "sage", "ext", "interpreters") - - -rebuild(output_dir) +rebuild(args.output_dir) From 4ec8bf97428a597897819938c56fab187dc956c3 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Tue, 21 Nov 2023 14:40:38 +0530 Subject: [PATCH 314/463] naming the graph before returning it --- src/sage/graphs/generic_graph.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index e6c8756e5f2..b70ba295a6c 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15832,6 +15832,9 @@ def power(self, k): if u != v: power_of_graph.add_edge(u, v) + if self.name(): + power_of_graph.name("power({})".format(self.name())) + return power_of_graph def girth(self, certificate=False): From bfd6e35102fc8bbb4f340ec74124f8053d90b06b Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Tue, 21 Nov 2023 15:39:15 +0530 Subject: [PATCH 315/463] fixed function definition and improved doctests readability --- src/sage/graphs/generic_graph.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index b70ba295a6c..fad8344923d 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15748,8 +15748,13 @@ def distance_all_pairs(self, by_weight=False, algorithm=None, def power(self, k): r""" - Compute the kth power graph of an unweighted graph based on shortest - distances between nodes using BFS. + Return the `k`-th power graph of ``self``. + + In the `k`-th power graph of a graph `G`, there is an edge between + any pair of vertices at distance at most `k` in `G`, where the + distance is considered in the unweighted graph. In a directed graph, + there is an arc from a vertex `u` to a vertex `v` if there is a path + of length at most `k` in `G` from `u` to `v`. INPUT: @@ -15765,16 +15770,14 @@ def power(self, k): Testing on undirected graphs:: sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) - sage: k = 2 - sage: PG = G.power(k) + sage: PG = G.power(2) sage: PG.edges(sort=True, labels=False) [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (2, 5), (3, 4), (4, 5)] Testing on directed graphs:: sage: G = DiGraph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) - sage: k = 3 - sage: PG = G.power(k) + sage: PG = G.power(3) sage: PG.edges(sort=True, labels=False) [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (3, 0), (3, 1), (3, 2), (4, 5)] @@ -15783,8 +15786,7 @@ def power(self, k): Testing when k < 0:: sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) - sage: k = -2 - sage: PG = G.power(k) + sage: PG = G.power(-2) Traceback (most recent call last): ... ValueError: distance must be a non-negative integer, not -2 @@ -15792,24 +15794,21 @@ def power(self, k): Testing when k = 0:: sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) - sage: k = 0 - sage: PG = G.power(k) + sage: PG = G.power(0) sage: PG.edges(sort=True, labels=False) [] Testing when k = 1:: sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) - sage: k = 1 - sage: PG = G.power(k) + sage: PG = G.power(1) sage: PG.edges(sort=True, labels=False) [(0, 1), (0, 3), (1, 2), (2, 3), (2, 4), (4, 5)] Testing when k = Infinity:: sage: G = Graph([(0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) - sage: k = Infinity - sage: PG = G.power(k) + sage: PG = G.power(Infinity) Traceback (most recent call last): ... ValueError: distance must be a non-negative integer, not +Infinity @@ -15817,8 +15816,7 @@ def power(self, k): Testing on graph with multiple edges:: sage: G = DiGraph([(0, 1), (0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) - sage: k = 3 - sage: PG = G.power(k) + sage: PG = G.power(3) sage: PG.edges(sort=True, labels=False) [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (3, 0), (3, 1), (3, 2), (4, 5)] """ From e0dc49dc569408e2988b45359a0bf817cc396ef0 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Tue, 21 Nov 2023 20:54:26 +0530 Subject: [PATCH 316/463] fixed doctest on multigraph --- src/sage/graphs/generic_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index fad8344923d..efddb03b1cc 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -15815,7 +15815,7 @@ def power(self, k): Testing on graph with multiple edges:: - sage: G = DiGraph([(0, 1), (0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)]) + sage: G = DiGraph([(0, 1), (0, 1), (1, 2), (2, 3), (3, 0), (2, 4), (4, 5)], multiedges=True) sage: PG = G.power(3) sage: PG.edges(sort=True, labels=False) [(0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (3, 0), (3, 1), (3, 2), (4, 5)] From 741fbc7c4aeecb0c85c70c618fc4194797e5f58b Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 22 Nov 2023 12:58:09 +0900 Subject: [PATCH 317/463] Fixes for reviewer comments --- src/sage/schemes/curves/affine_curve.py | 13 +++++++------ src/sage/schemes/curves/projective_curve.py | 10 +++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py index d329b21fddf..8d6474115ef 100644 --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -2194,18 +2194,19 @@ def pull_from_function_field(self, f): sage: C.function(C.pull_from_function_field(f2)) == f2 True """ - return self._pull_from_function_field(f) + return self._map_from_function_field(f) @lazy_attribute def _nonsingular_model(self): """ Return the data of a nonsingular model of the curve. - The data consists of an abstract function field `M` and a map from the + The data consists of an abstract function field `M`, a map from the fraction field of the coordinate ring `R` of the ambient space of the - curve to the function field. The coordinate ring of the curve is the - quotient of `R` by the kernel of the map restricted to `R`. + curve to the function field, and the inverse map. + The coordinate ring of the curve is the quotient of `R` by the kernel + of the map restricted to `R`. TESTS:: @@ -2406,7 +2407,7 @@ def _coordinate_functions(self): return self._nonsingular_model[1].im_gens() @lazy_attribute - def _pull_from_function_field(self): + def _map_from_function_field(self): """ Return the map from the function field of the curve. @@ -2414,7 +2415,7 @@ def _pull_from_function_field(self): sage: A. = AffineSpace(GF(11), 3) sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) - sage: C._pull_from_function_field + sage: C._map_from_function_field Ring morphism: From: Function field in z defined by z^3 + 10*x To: Fraction Field of Multivariate Polynomial Ring in x, y, z diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index fcb87d9e31c..3e6c40920c1 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -2410,7 +2410,7 @@ def pull_from_function_field(self, f): sage: C.function(C.pull_from_function_field(f2)) == f2 True """ - return self._pull_from_function_field(f) + return self._map_from_function_field(f) @lazy_attribute def _function_field(self): @@ -2465,7 +2465,7 @@ def _coordinate_functions(self): return tuple(coords) @lazy_attribute - def _pull_from_function_field(self): + def _map_from_function_field(self): """ Return the map to the function field of the curve. @@ -2475,7 +2475,7 @@ def _pull_from_function_field(self): sage: C = Curve(y^2*z^7 - x^9 - x*z^8) sage: F = C.function_field() sage: f = F.random_element() - sage: C.function(C._pull_from_function_field(f)) == f + sage: C.function(C._map_from_function_field(f)) == f True """ F = self._function_field @@ -2483,13 +2483,13 @@ def _pull_from_function_field(self): phi = self._open_affine._nonsingular_model[2] i = self._open_affine_index - def pull(f): + def m(f): pf = phi(f) num = S(pf.numerator()).homogenize(i) den = S(pf.denominator()).homogenize(i) return num / den * S.gen(i) ** (den.total_degree() - num.total_degree()) - return pull + return m @lazy_attribute def _singularities(self): From 703ce9e5edd15a9629a7d2fe8d005a79fc9eb4ef Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 22 Nov 2023 14:08:34 +0900 Subject: [PATCH 318/463] Change _lift_ too --- src/sage/schemes/curves/affine_curve.py | 10 +++++----- src/sage/schemes/curves/projective_curve.py | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py index 8d6474115ef..5eefb3f8e99 100644 --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -2143,7 +2143,7 @@ def function(self, f): if f not in R and f.parent() is self.coordinate_ring(): f = f.lift() - phi = self._lift_to_function_field + phi = self._map_to_function_field num = R(f.numerator()) den = R(f.denominator()) return phi(num) / phi(den) @@ -2373,7 +2373,7 @@ def _function_field(self): return self._nonsingular_model[0] @lazy_attribute - def _lift_to_function_field(self): + def _map_to_function_field(self): """ Return the map to the function field of the curve. @@ -2381,7 +2381,7 @@ def _lift_to_function_field(self): sage: A. = AffineSpace(GF(11), 3) sage: C = Curve([x*z - y^2, y - z^2, x - y*z], A) - sage: C._lift_to_function_field + sage: C._map_to_function_field Ring morphism: From: Fraction Field of Multivariate Polynomial Ring in x, y, z over Finite Field of size 11 @@ -2438,7 +2438,7 @@ def _singularities(self): [(Point (x, y), [Place (x, 1/x*y^3 + 1/x*y^2 + 1), Place (x, 1/x*y^3 + 1/x*y^2 + 6)])] """ - to_F = self._lift_to_function_field + to_F = self._map_to_function_field sing = self.singular_subscheme() funcs = [] @@ -2655,7 +2655,7 @@ def places_on(self, point): sage: Cp = Curve(x^3*y + y^3*z + x*z^3) sage: C = Cp.affine_patch(0) """ - phi = self._lift_to_function_field + phi = self._map_to_function_field gs = [phi(g) for g in point.prime_ideal().gens()] fs = [g for g in gs if not g.is_zero()] f = fs.pop() diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index 3e6c40920c1..21efc6b6109 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -2349,7 +2349,7 @@ def function(self, f): - Place (y, z + 1) """ S = self.ambient_space().coordinate_ring() - phi = self._lift_to_function_field + phi = self._map_to_function_field num = S(f.numerator()) den = S(f.denominator()) if num.degree() != den.degree(): @@ -2427,7 +2427,7 @@ def _function_field(self): return self._open_affine._function_field @lazy_attribute - def _lift_to_function_field(self): + def _map_to_function_field(self): """ Return the map to function field of the curve. @@ -2435,7 +2435,7 @@ def _lift_to_function_field(self): sage: P. = ProjectiveSpace(GF(5), 2) sage: C = Curve(y^2*z^7 - x^9 - x*z^8) - sage: C._lift_to_function_field + sage: C._map_to_function_field Ring morphism: From: Multivariate Polynomial Ring in x, y, z over Finite Field of size 5 To: Function field in z defined by z^8 + 4*y^2*z^7 + 1 @@ -2508,7 +2508,7 @@ def _singularities(self): """ S = self.ambient_space().coordinate_ring() - to_F = self._lift_to_function_field + to_F = self._map_to_function_field sing = self.singular_subscheme() # singular locus # for each affine patch, places on which the dehomogenized polynomials @@ -2694,7 +2694,7 @@ def places_on(self, point): if not S.gen(i) in prime: break - phi = self._lift_to_function_field + phi = self._map_to_function_field denom = self._coordinate_functions[i] gs = [phi(f)/denom**f.degree() for f in prime.gens()] fs = [g for g in gs if not g.is_zero()] From 29b040c9161971031bbc44ba933951fc85e7fe63 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 22 Nov 2023 15:25:03 +0900 Subject: [PATCH 319/463] Be precise in input/output description --- src/sage/schemes/curves/affine_curve.py | 5 +++-- src/sage/schemes/curves/projective_curve.py | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py index 5eefb3f8e99..e33092ca0d3 100644 --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -2119,7 +2119,7 @@ def function(self, f): INPUT: - ``f`` -- an element of the fraction field of the coordinate ring of - the curve or its ambient space. + the ambient space or the coordinate ring of the curve OUTPUT: An element of the function field of this curve. @@ -2173,7 +2173,8 @@ def pull_from_function_field(self, f): OUTPUT: - A fraction of polynomials in the coordinate ring of this curve. + A fraction of polynomials in the coordinate ring of the ambient space + of the curve. EXAMPLES:: diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index 21efc6b6109..cac2990fdd9 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -2325,11 +2325,12 @@ def __call__(self, *args): def function(self, f): """ - Return the function field element coerced from ``f``. + Return the function field element corresponding to ``f``. INPUT: - - ``f`` -- an element in the fraction field of the coordinate ring + - ``f`` -- a fraction of homogeneous polynomials of the coordinate ring + of the ambient space of the curve OUTPUT: An element of the function field. @@ -2389,7 +2390,8 @@ def pull_from_function_field(self, f): OUTPUT: - A fraction of homogeneous polynomials in the coordinate ring of this curve. + A fraction of homogeneous polynomials in the coordinate ring of the + ambient space of the curve. EXAMPLES:: From 5f383d6cfe22ee07eaa466d1b359eb0ed98f0d68 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 23:47:37 -0700 Subject: [PATCH 320/463] More # optional --- src/sage/misc/explain_pickle.py | 214 +++++++++++++++++--------------- 1 file changed, 112 insertions(+), 102 deletions(-) diff --git a/src/sage/misc/explain_pickle.py b/src/sage/misc/explain_pickle.py index 30c3988850b..2fb34a2234e 100644 --- a/src/sage/misc/explain_pickle.py +++ b/src/sage/misc/explain_pickle.py @@ -5,9 +5,9 @@ - Carl Witty (2009-03) -The explain_pickle function takes a pickle and produces Sage code that +The :func:`explain_pickle` function takes a pickle and produces Sage code that will evaluate to the contents of the pickle. Ideally, the combination -of explain_pickle to produce Sage code and sage_eval to evaluate the code +of :func:`explain_pickle` to produce Sage code and :func:`sage_eval` to evaluate the code would be a 100% compatible implementation of cPickle's unpickler; this is almost the case now. @@ -27,9 +27,9 @@ True By default (as above) the code produced contains calls to several -utility functions (unpickle_global, etc.); this is done so that the +utility functions (:func:`unpickle_global`, etc.); this is done so that the code is truly equivalent to the pickle. If the pickle can be loaded -into a future version of Sage, then the code that explain_pickle +into a future version of Sage, then the code that :func:`explain_pickle` produces today should work in that future Sage as well. It is also possible to produce simpler code, that is tied to the current @@ -44,11 +44,11 @@ from sage.rings.rational import make_rational Polynomial_rational_flint(unpickle_PolynomialRing(RationalField(), ('x',), None, False), [make_rational('0'), make_rational('1')], False, True) -The explain_pickle function has several use cases. +The :func:`explain_pickle` function has several use cases. - Write pickling support for your classes - You can use explain_pickle to see what will happen when a pickle + You can use :func:`explain_pickle` to see what will happen when a pickle is unpickled. Consider: is this sequence of commands something that can be easily supported in all future Sage versions, or does it expose internal design decisions that are subject to change? @@ -56,55 +56,55 @@ - Debug old pickles If you have a pickle from an old version of Sage that no longer - unpickles, you can use explain_pickle to see what it is trying to + unpickles, you can use :func:`explain_pickle` to see what it is trying to do, to figure out how to fix it. - - Use explain_pickle in doctests to help maintenance + - Use :func:`explain_pickle` in doctests to help maintenance If you have a ``loads(dumps(S))`` doctest, you could also add an ``explain_pickle(dumps(S))`` doctest. Then if something changes in a way that would invalidate old pickles, the output of - ``explain_pickle`` will also change. At that point, you can add + :func:`explain_pickle` will also change. At that point, you can add the previous output of :obj:`explain_pickle` as a new set of doctests (and then update the :obj:`explain_pickle` doctest to use the new output), to ensure that old pickles will continue to work. -As mentioned above, there are several output modes for :obj:`explain_pickle`, +As mentioned above, there are several output modes for :func:`explain_pickle`, that control fidelity versus simplicity of the output. For example, the GLOBAL instruction takes a module name and a class name and produces the corresponding class. So GLOBAL of ``sage.rings.integer``, ``Integer`` is approximately equivalent to ``sage.rings.integer.Integer``. However, this class lookup process can be customized (using -sage.misc.persist.register_unpickle_override). For instance, +:func:`sage.misc.persist.register_unpickle_override`). For instance, if some future version of Sage renamed ``sage/rings/integer.pyx`` to ``sage/rings/knuth_was_here.pyx``, old pickles would no longer work unless register_unpickle_override was used; in that case, GLOBAL of -'sage.rings.integer', 'integer' would mean +``sage.rings.integer``, ``integer`` would mean ``sage.rings.knuth_was_here.integer``. -By default, ``explain_pickle`` will map this GLOBAL instruction to +By default, :func:`explain_pickle` will map this GLOBAL instruction to ``unpickle_global('sage.rings.integer', 'integer')``. Then when this code -is evaluated, unpickle_global will look up the current mapping in the -register_unpickle_override table, so the generated code will continue -to work even in hypothetical future versions of Sage where integer.pyx +is evaluated, :func:`unpickle_global` will look up the current mapping in the +:func:`register_unpickle_override` table, so the generated code will continue +to work even in hypothetical future versions of Sage where ``integer.pyx`` has been renamed. If you pass the flag ``in_current_sage=True``, then -:obj:`explain_pickle` will generate code that may only work in the +:func:`explain_pickle` will generate code that may only work in the current version of Sage, not in future versions. In this case, it would generate:: from sage.rings.integer import integer -and if you ran explain_pickle in hypothetical future sage, it would generate: +and if you ran :func:`explain_pickle` in hypothetical future sage, it would generate: from sage.rings.knuth_was_here import integer but the current code wouldn't work in the future sage. If you pass the flag ``default_assumptions=True``, then -:obj:`explain_pickle` will generate code that would work in the +:func:`explain_pickle` will generate code that would work in the absence of any special unpickling information. That is, in either current Sage or hypothetical future Sage, it would generate:: @@ -114,32 +114,32 @@ human-readable), but may not actually work; so it is only intended for human reading. -There are several functions used in the output of :obj:`explain_pickle`. +There are several functions used in the output of :func:`explain_pickle`. Here I give a brief description of what they usually do, as well as how to modify their operation (for instance, if you're trying to get old pickles to work). - ``unpickle_global(module, classname)``: - unpickle_global('sage.foo.bar', 'baz') is usually equivalent to - sage.foo.bar.baz, but this can be customized with - register_unpickle_override. + ``unpickle_global('sage.foo.bar', 'baz')`` is usually equivalent to + ``sage.foo.bar.baz``, but this can be customized with + :func:`register_unpickle_override`. - ``unpickle_newobj(klass, args)``: Usually equivalent to ``klass.__new__(klass, *args)``. If ``klass`` is a Python class, then you can define :meth:`__new__` to control the result (this result actually need not be an - instance of klass). (This doesn't work for Cython classes.) + instance of ``klass``). (This doesn't work for Cython classes.) - ``unpickle_build(obj, state)``: If ``obj`` has a :meth:`__setstate__` method, then this is equivalent to - ``obj.__setstate__(state)``. Otherwise uses state to set the attributes + ``obj.__setstate__(state)``. Otherwise uses ``state`` to set the attributes of ``obj``. Customize by defining :meth:`__setstate__`. - ``unpickle_instantiate(klass, args)``: Usually equivalent to ``klass(*args)``. Cannot be customized. - - unpickle_appends(lst, vals): - Appends the values in vals to lst. If not ``isinstance(lst, list)``, + - ``unpickle_appends(lst, vals)``: + Appends the values in ``vals`` to ``lst``. If not ``isinstance(lst, list)``, can be customized by defining a :meth:`append` method. """ @@ -165,7 +165,6 @@ from pickletools import genops -import sage.all from sage.misc.sage_input import SageInputBuilder, SageInputExpression from sage.misc.sage_eval import sage_eval from sage.misc.persist import (unpickle_override, unpickle_global, dumps, @@ -181,30 +180,30 @@ def explain_pickle(pickle=None, file=None, compress=True, **kwargs): r""" Explain a pickle. That is, produce source code such that evaluating the code is equivalent to loading the pickle. Feeding the result - of ``explain_pickle`` to ``sage_eval`` should be totally equivalent to loading + of :func:`explain_pickle` to :func:`sage_eval` should be totally equivalent to loading the ``pickle`` with ``cPickle``. INPUT: - - ``pickle`` -- the pickle to explain, as a string (default: None) - - ``file`` -- a filename of a pickle (default: None) - - ``compress`` -- if False, don't attempt to decompress the pickle - (default: True) - - ``in_current_sage`` -- if True, produce potentially simpler code that is - tied to the current version of Sage. (default: False) - - ``default_assumptions`` -- if True, produce potentially simpler code that - assumes that generic unpickling code will be - used. This code may not actually work. - (default: False) - - ``eval`` -- if True, then evaluate the resulting code and return the - evaluated result. (default: False) - - ``preparse`` -- if True, then produce code to be evaluated with - Sage's preparser; if False, then produce standard - Python code; if None, then produce code that will work - either with or without the preparser. (default: True) - - ``pedantic`` -- if True, then carefully ensures that the result has - at least as much sharing as the result of cPickle - (it may have more, for immutable objects). (default: False) + - ``pickle`` -- the pickle to explain, as a string (default: ``None``) + - ``file`` -- a filename of a pickle (default: ``None``) + - ``compress`` -- if ``False``, don't attempt to decompress the pickle + (default: ``True``) + - ``in_current_sage`` -- if ``True``, produce potentially simpler code that is + tied to the current version of Sage. (default: ``False``) + - ``default_assumptions`` -- if ``True``, produce potentially simpler code that + assumes that generic unpickling code will be + used. This code may not actually work. + (default: ``False``) + - ``eval`` -- if ``True``, then evaluate the resulting code and return the + evaluated result. (default: ``False``) + - ``preparse`` -- if ``True``, then produce code to be evaluated with + Sage's preparser; if ``False``, then produce standard + Python code; if ``None``, then produce code that will work + either with or without the preparser. (default: ``True``) + - ``pedantic`` -- if ``True``, then carefully ensures that the result has + at least as much sharing as the result of cPickle + (it may have more, for immutable objects). (default: ``False``) Exactly one of ``pickle`` (a string containing a pickle) or ``file`` (the filename of a pickle) must be provided. @@ -263,16 +262,16 @@ def explain_pickle_string(pickle, in_current_sage=False, default_assumptions=False, eval=False, preparse=True, pedantic=False): r""" - This is a helper function for explain_pickle. It takes a decompressed + This is a helper function for :func:`explain_pickle`. It takes a decompressed pickle string as input; other than that, its options are all the same - as explain_pickle. + as :func:`explain_pickle`. EXAMPLES:: sage: sage.misc.explain_pickle.explain_pickle_string(dumps("Hello, world", compress=False)) 'Hello, world' - (See the documentation for ``explain_pickle`` for many more examples.) + (See the documentation for :func:`explain_pickle` for many more examples.) """ sib = SageInputBuilder(preparse=preparse) @@ -321,17 +320,19 @@ def name_is_valid(name): class PickleObject(): r""" - Pickles have a stack-based virtual machine. The explain_pickle - pickle interpreter mostly uses SageInputExpressions, from sage_input, + Pickles have a stack-based virtual machine. The :func:`explain_pickle` + pickle interpreter mostly uses :class:`sage.misc.sage_input.SageInputExpression` objects as the stack values. However, sometimes we want some more information about the value on the stack, so that we can generate better (prettier, less confusing) code. In such cases, we push - a PickleObject instead of a SageInputExpression. A PickleObject + a :class:`PickleObject` instead of a :class:`~sage.misc.sage_input.SageInputExpression`. + A :class:`PickleObject` contains a value (which may be a standard Python value, or a - PickleDict or PickleInstance), an expression (a SageInputExpression), + :class:`PickleDict` or :class:`PickleInstance`), an expression + (a :class:`~sage.misc.sage_input.SageInputExpression`), and an "immutable" flag (which checks whether this object - has been converted to a SageInputExpression; if it has, then we - must not mutate the object, since the SageInputExpression would not + has been converted to a :class:`SageInputExpression`; if it has, then we + must not mutate the object, since the :class:`SageInputExpression` would not reflect the changes). """ @@ -375,9 +376,9 @@ def _sage_input_(self, sib, coerced): class PickleDict(): r""" - An object which can be used as the value of a PickleObject. The items + An object which can be used as the value of a :class:`PickleObject`. The items is a list of key-value pairs, where the keys and values are - SageInputExpressions. We use this to help construct dictionary literals, + :class:`SageInputExpression` objects. We use this to help construct dictionary literals, instead of always starting with an empty dictionary and assigning to it. """ @@ -395,8 +396,8 @@ def __init__(self, items): class PickleInstance(): r""" - An object which can be used as the value of a PickleObject. Unlike - other possible values of a PickleObject, a PickleInstance doesn't represent + An object which can be used as the value of a :class:`PickleObject`. Unlike + other possible values of a :class:`PickleObject`, a :class:`PickleInstance` doesn't represent an exact value; instead, it gives the class (type) of the object. """ def __init__(self, klass): @@ -414,7 +415,7 @@ def __init__(self, klass): class PickleExplainer(): r""" An interpreter for the pickle virtual machine, that executes - symbolically and constructs SageInputExpressions instead of + symbolically and constructs :class:`SageInputExpression` objects instead of directly constructing values. """ def __init__(self, sib, in_current_sage=False, default_assumptions=False, @@ -448,7 +449,7 @@ def run_pickle(self, p): r""" Given an (uncompressed) pickle as a string, run the pickle in this virtual machine. Once a STOP has been executed, return - the result (a SageInputExpression representing code which, when + the result (a :class:`SageInputExpression` representing code which, when evaluated, will give the value of the pickle). EXAMPLES:: @@ -477,8 +478,8 @@ def run_pickle(self, p): def check_value(self, v): r""" - Check that the given value is either a SageInputExpression or a - PickleObject. Used for internal sanity checking. + Check that the given value is either a :class:`SageInputExpression` or a + :class:`PickleObject`. Used for internal sanity checking. EXAMPLES:: @@ -514,7 +515,7 @@ def push(self, v): def push_and_share(self, v): r""" Push a value onto the virtual machine's stack; also mark it as shared - for sage_input if we are in pedantic mode. + for :func:`sage_input` if we are in pedantic mode. EXAMPLES:: @@ -595,14 +596,15 @@ def pop_to_mark(self): def share(self, v): r""" - Mark a sage_input value as shared, if we are in pedantic mode. + Mark a :func:`sage_input` value as shared, if we are in pedantic mode. EXAMPLES:: sage: from sage.misc.explain_pickle import * sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() - sage: pe = PickleExplainer(sib, in_current_sage=True, default_assumptions=False, pedantic=True) + sage: pe = PickleExplainer(sib, in_current_sage=True, + ....: default_assumptions=False, pedantic=True) sage: v = sib(7) sage: v._sie_share False @@ -617,15 +619,16 @@ def share(self, v): def is_mutable_pickle_object(self, v): r""" - Test whether a PickleObject is mutable (has never been converted - to a SageInputExpression). + Test whether a :class:`PickleObject` is mutable (has never been converted + to a :class:`SageInputExpression`). EXAMPLES:: sage: from sage.misc.explain_pickle import * sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() - sage: pe = PickleExplainer(sib, in_current_sage=True, default_assumptions=False, pedantic=True) + sage: pe = PickleExplainer(sib, in_current_sage=True, + ....: default_assumptions=False, pedantic=True) sage: v = PickleObject(1, sib(1)) sage: pe.is_mutable_pickle_object(v) True @@ -1394,7 +1397,12 @@ def GLOBAL(self, name): # OK, we know what module and function name will actually # be used, as well as the actual function. # Is this already available at the command line? - cmdline_f = getattr(sage.all, func, None) + try: + import sage.all + except ImportError: + cmdline_f = None + else: + cmdline_f = getattr(sage.all, func, None) if cmdline_f is f: self.push(PickleObject(f, self.sib.name(func))) return @@ -2368,7 +2376,7 @@ def UNICODE(self, s): def unpickle_newobj(klass, args): r""" Create a new object; this corresponds to the C code - klass->tp_new(klass, args, NULL). Used by ``explain_pickle``. + ``klass->tp_new(klass, args, NULL)``. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2413,7 +2421,7 @@ def pers_load(id): def unpickle_build(obj, state): r""" - Set the state of an object. Used by ``explain_pickle``. + Set the state of an object. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2447,8 +2455,8 @@ def unpickle_build(obj, state): def unpickle_instantiate(fn, args): r""" - Instantiate a new object of class fn with arguments args. Almost always - equivalent to ``fn(*args)``. Used by ``explain_pickle``. + Instantiate a new object of class ``fn`` with arguments ``args``. Almost always + equivalent to ``fn(*args)``. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2469,7 +2477,7 @@ def unpickle_persistent(s): r""" Takes an integer index and returns the persistent object with that index; works by calling whatever callable is stored in - unpickle_persistent_loader. Used by ``explain_pickle``. + ``unpickle_persistent_loader``. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2484,7 +2492,7 @@ def unpickle_persistent(s): def unpickle_extension(code): r""" Takes an integer index and returns the extension object with that - index. Used by ``explain_pickle``. + index. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2512,7 +2520,7 @@ def unpickle_appends(lst, vals): r""" Given a list (or list-like object) and a sequence of values, appends the values to the end of the list. This is careful to do so using the - exact same technique that cPickle would use. Used by ``explain_pickle``. + exact same technique that cPickle would use. Used by :func:`explain_pickle`. EXAMPLES:: @@ -2532,7 +2540,9 @@ def unpickle_appends(lst, vals): def test_pickle(p, verbose_eval=False, pedantic=False, args=()): r""" - Tests explain_pickle on a given pickle p. p can be: + Test :func:`explain_pickle` on a given pickle ``p``. + + ``p`` can be: - a string containing an uncompressed pickle (which will always end with a '.') @@ -2542,14 +2552,14 @@ def test_pickle(p, verbose_eval=False, pedantic=False, args=()): the stack (using persistent IDs), run the pickle fragment, and then STOP (if the string 'mark' occurs in args, then a mark will be pushed) - - an arbitrary object; test_pickle will pickle the object + - an arbitrary object; :func:`test_pickle` will pickle the object - Once it has a pickle, test_pickle will print the pickle's - disassembly, run explain_pickle with in_current_sage=True and - False, print the results, evaluate the results, unpickle the + Once it has a pickle, :func:`test_pickle` will print the pickle's + disassembly, run :func:`explain_pickle` with ``in_current_sage=True`` and + ``False``, print the results, evaluate the results, unpickle the object with cPickle, and compare all three results. - If verbose_eval is True, then test_pickle will print messages + If ``verbose_eval`` is ``True``, then :func:`test_pickle` will print messages before evaluating the pickles; this is to allow for tests where the unpickling prints messages (to verify that the same operations occur in all cases). @@ -2636,7 +2646,7 @@ def pers_load(s): class EmptyOldstyleClass: r""" A featureless old-style class (does not inherit from object); used for - testing explain_pickle. + testing :func:`explain_pickle`. """ def __repr__(self): r""" @@ -2674,7 +2684,7 @@ def __hash__(self): class EmptyNewstyleClass(): r""" A featureless new-style class (inherits from object); used for - testing explain_pickle. + testing :func:`explain_pickle`. """ def __repr__(self): r""" @@ -2696,8 +2706,8 @@ def __repr__(self): class TestReduceGetinitargs: r""" - An old-style class with a __getinitargs__ method. Used for testing - explain_pickle. + An old-style class with a :func:`__getinitargs__` method. Used for testing + :func:`explain_pickle`. """ def __init__(self): r""" @@ -2748,8 +2758,8 @@ def __repr__(self): class TestReduceNoGetinitargs: r""" - An old-style class with no __getinitargs__ method. Used for testing - explain_pickle. + An old-style class with no :meth:`__getinitargs__` method. Used for testing + :func:`explain_pickle`. """ def __init__(self): r""" @@ -2786,8 +2796,8 @@ def __repr__(self): class TestAppendList(list): r""" - A subclass of list, with deliberately-broken append and extend methods. - Used for testing explain_pickle. + A subclass of :class:`list`, with deliberately-broken append and extend methods. + Used for testing :func:`explain_pickle`. """ def append(self): r""" @@ -2835,7 +2845,7 @@ def extend(self): class TestAppendNonlist(): r""" A list-like class, carefully designed to test exact unpickling - behavior. Used for testing explain_pickle. + behavior. Used for testing :func:`explain_pickle`. """ def __init__(self): r""" @@ -2918,8 +2928,8 @@ def __repr__(self): class TestBuild(): r""" - A simple class with a __getstate__ but no __setstate__. Used for testing - explain_pickle. + A simple class with a :meth:`__getstate__` but no :meth:`__setstate__`. Used for testing + :func:`explain_pickle`. """ def __getstate__(self): r""" @@ -2955,8 +2965,8 @@ def __repr__(self): class TestBuildSetstate(TestBuild): r""" - A simple class with a __getstate__ and a __setstate__. Used for testing - explain_pickle. + A simple class with a :meth:`__getstate__` and a :meth:`__setstate__`. Used for testing + :func:`explain_pickle`. """ def __setstate__(self, state): r""" @@ -2978,8 +2988,8 @@ def __setstate__(self, state): class TestGlobalOldName(): r""" A featureless new-style class. When you try to unpickle an instance - of this class, it is redirected to create a TestGlobalNewName instead. - Used for testing explain_pickle. + of this class, it is redirected to create a :class:`TestGlobalNewName` instead. + Used for testing :func:`explain_pickle`. EXAMPLES:: @@ -2993,8 +3003,8 @@ class TestGlobalOldName(): class TestGlobalNewName(): r""" A featureless new-style class. When you try to unpickle an instance - of TestGlobalOldName, it is redirected to create an instance of this - class instead. Used for testing explain_pickle. + of :class:`TestGlobalOldName`, it is redirected to create an instance of this + class instead. Used for testing :func:`explain_pickle`. EXAMPLES:: From 66db7aa276741cf67673b43ded108f8a3220d2ac Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 21:38:40 -0800 Subject: [PATCH 321/463] Add # optional - numpy etc. --- src/sage/interfaces/sympy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/interfaces/sympy.py b/src/sage/interfaces/sympy.py index a334c241127..c380731f8b7 100644 --- a/src/sage/interfaces/sympy.py +++ b/src/sage/interfaces/sympy.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sympy """ SymPy --> Sage conversion From 753ac98a9b0ffab5993f86a1fe86e8ae29d4f110 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 13 May 2023 15:58:37 -0700 Subject: [PATCH 322/463] src/sage/interfaces/tides.py: pycodestyle fix --- src/sage/interfaces/tides.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/interfaces/tides.py b/src/sage/interfaces/tides.py index f70a2357cd3..1b00f52df54 100644 --- a/src/sage/interfaces/tides.py +++ b/src/sage/interfaces/tides.py @@ -37,8 +37,10 @@ - [TIDES]_ """ + from sage.rings.real_mpfr import RealField -from sage.calculus.all import symbolic_expression +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.all", "symbolic_expression") from sage.misc.flatten import flatten from sage.ext.fast_callable import fast_callable from sage.rings.semirings.non_negative_integer_semiring import NN From 0eb6d0a834b992985ea035a27861cbf333bb54f1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 17 May 2023 13:20:30 -0700 Subject: [PATCH 323/463] Massive modularization fixes --- src/sage/interfaces/expect.py | 2 +- src/sage/interfaces/gp.py | 28 ++++++++++++++-------------- src/sage/interfaces/interface.py | 1 + src/sage/interfaces/jmoldata.py | 6 +++--- src/sage/interfaces/quit.py | 14 +++++++------- src/sage/interfaces/tests.py | 2 +- 6 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 17ad63cfbac..9c38a8c1cba 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic """ Common Interface Functionality through Pexpect diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index e5c77833cca..c777bc6bd40 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -787,26 +787,26 @@ def new_with_bits_prec(self, s, precision=0): EXAMPLES:: - sage: pi_def = gp(pi); pi_def + sage: pi_def = gp(pi); pi_def # optional - sage.symbolic 3.141592653589793238462643383 # 32-bit 3.1415926535897932384626433832795028842 # 64-bit - sage: pi_def.precision() + sage: pi_def.precision() # optional - sage.symbolic 28 # 32-bit 38 # 64-bit - sage: pi_150 = gp.new_with_bits_prec(pi, 150) - sage: new_prec = pi_150.precision(); new_prec + sage: pi_150 = gp.new_with_bits_prec(pi, 150) # optional - sage.symbolic + sage: new_prec = pi_150.precision(); new_prec # optional - sage.symbolic 48 # 32-bit 57 # 64-bit - sage: old_prec = gp.set_precision(new_prec); old_prec + sage: old_prec = gp.set_precision(new_prec); old_prec # optional - sage.symbolic 28 # 32-bit 38 # 64-bit - sage: pi_150 + sage: pi_150 # optional - sage.symbolic 3.14159265358979323846264338327950288419716939938 # 32-bit 3.14159265358979323846264338327950288419716939937510582098 # 64-bit - sage: gp.set_precision(old_prec) + sage: gp.set_precision(old_prec) # optional - sage.symbolic 48 # 32-bit 57 # 64-bit - sage: gp.get_precision() + sage: gp.get_precision() # optional - sage.symbolic 28 # 32-bit 38 # 64-bit """ @@ -877,9 +877,9 @@ def _sage_(self): EXAMPLES:: - sage: gp(SR(I)).sage() + sage: gp(SR(I)).sage() # optional - sage.symbolic i - sage: gp(SR(I)).sage().parent() + sage: gp(SR(I)).sage().parent() # optional - sage.symbolic Number Field in i with defining polynomial x^2 + 1 with i = 1*I :: @@ -955,11 +955,11 @@ def _complex_mpfr_field_(self, CC): EXAMPLES:: - sage: z = gp(SR(1+15*I)); z + sage: z = gp(SR(1+15*I)); z # optional - sage.symbolic 1 + 15*I - sage: z._complex_mpfr_field_(CC) + sage: z._complex_mpfr_field_(CC) # optional - sage.symbolic 1.00000000000000 + 15.0000000000000*I - sage: CC(z) # CC(gp(1+15*I)) + sage: CC(z) # CC(gp(1+15*I)) # optional - sage.symbolic 1.00000000000000 + 15.0000000000000*I sage: CC(gp(11243.9812+15*I)) 11243.9812000000 + 15.0000000000000*I @@ -977,7 +977,7 @@ def _complex_double_(self, CDF): EXAMPLES:: - sage: CDF(gp(pi+I*e)) + sage: CDF(gp(pi+I*e)) # optional - sage.symbolic 3.141592653589793 + 2.718281828459045*I """ # Retrieving values from another computer algebra system is diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 78f94269ff4..4c0f1205092 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic r""" Common Interface Functionality diff --git a/src/sage/interfaces/jmoldata.py b/src/sage/interfaces/jmoldata.py index a68e53e2d85..2890a8a7a76 100644 --- a/src/sage/interfaces/jmoldata.py +++ b/src/sage/interfaces/jmoldata.py @@ -134,10 +134,10 @@ def export_image(self, sage: from sage.interfaces.jmoldata import JmolData sage: JData = JmolData() - sage: D = dodecahedron() + sage: D = dodecahedron() # optional - sage.plot sage: from tempfile import NamedTemporaryFile sage: archive = NamedTemporaryFile(suffix=".zip") - sage: D.export_jmol(archive.name) + sage: D.export_jmol(archive.name) # optional - sage.plot sage: archive_native = archive.name sage: import sys sage: if sys.platform == 'cygwin': @@ -145,7 +145,7 @@ def export_image(self, ....: archive_native = cygwin.cygpath(archive_native, 'w') sage: script = f'set defaultdirectory "f{archive_native}"\n' sage: script += 'script SCRIPT\n' - sage: with NamedTemporaryFile(suffix=".png") as testfile: # optional -- java + sage: with NamedTemporaryFile(suffix=".png") as testfile: # optional -- java sage.plot ....: JData.export_image(targetfile=testfile.name, ....: datafile=script, ....: image_type="PNG") diff --git a/src/sage/interfaces/quit.py b/src/sage/interfaces/quit.py index 575646f2365..afc87aed1a7 100644 --- a/src/sage/interfaces/quit.py +++ b/src/sage/interfaces/quit.py @@ -140,19 +140,19 @@ def invalidate_all(): EXAMPLES:: - sage: a = maxima(2); b = gp(3) - sage: a, b + sage: a = maxima(2); b = gp(3) # optional - sage.libs.pari sage.symbolic + sage: a, b # optional - sage.libs.pari sage.symbolic (2, 3) - sage: sage.interfaces.quit.invalidate_all() - sage: a + sage: sage.interfaces.quit.invalidate_all() # optional - sage.libs.pari sage.symbolic + sage: a # optional - sage.libs.pari sage.symbolic (invalid Maxima object -- The maxima session in which this object was defined is no longer running.) - sage: b + sage: b # optional - sage.libs.pari sage.symbolic (invalid PARI/GP interpreter object -- The pari session in which this object was defined is no longer running.) However the maxima and gp sessions should still work out, though with their state reset:: - sage: a = maxima(2); b = gp(3) - sage: a, b + sage: a = maxima(2); b = gp(3) # optional - sage.libs.pari sage.symbolic + sage: a, b # optional - sage.libs.pari sage.symbolic (2, 3) """ for I in expect_objects: diff --git a/src/sage/interfaces/tests.py b/src/sage/interfaces/tests.py index 8c760c2a2c0..6c0942e04f4 100644 --- a/src/sage/interfaces/tests.py +++ b/src/sage/interfaces/tests.py @@ -13,7 +13,7 @@ 4 sage: parent(a) Gap - sage: a = 2 * maxima('2'); a + sage: a = 2 * maxima('2'); a # optional - sage.symbolic 4 sage: parent(a) Maxima From 8ee15dc876d97ec50ae701ee234afb08a9a7646e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 20 May 2023 15:38:10 -0700 Subject: [PATCH 324/463] More # optional --- src/sage/interfaces/axiom.py | 20 ++++++++++---------- src/sage/interfaces/tests.py | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index 5df8d2e184a..b00e9fc68a0 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -796,12 +796,12 @@ def _sage_(self): 2.12340000000000 sage: _.parent() #optional - axiom Real Field with 53 bits of precision - sage: a = RealField(100)(pi) - sage: axiom(a)._sage_() #optional - axiom + sage: a = RealField(100)(pi) # optional - sage.symbolic + sage: axiom(a)._sage_() #optional - axiom # optional - sage.symbolic 3.1415926535897932384626433833 - sage: _.parent() #optional - axiom + sage: _.parent() #optional - axiom # optional - sage.symbolic Real Field with 100 bits of precision - sage: axiom(a)._sage_() == a #optional - axiom + sage: axiom(a)._sage_() == a #optional - axiom # optional - sage.symbolic True sage: axiom(2.0)._sage_() #optional - axiom 2.00000000000000 @@ -810,16 +810,16 @@ def _sage_(self): We can also convert Axiom's polynomials to Sage polynomials. - sage: a = axiom(x^2 + 1) #optional - axiom - sage: a.type() #optional - axiom + sage: a = axiom(x^2 + 1) #optional - axiom # optional - sage.symbolic + sage: a.type() #optional - axiom # optional - sage.symbolic Polynomial Integer - sage: a.sage() #optional - axiom + sage: a.sage() #optional - axiom # optional - sage.symbolic x^2 + 1 - sage: _.parent() #optional - axiom + sage: _.parent() #optional - axiom # optional - sage.symbolic Univariate Polynomial Ring in x over Integer Ring - sage: axiom('x^2 + y^2 + 1/2').sage() #optional - axiom + sage: axiom('x^2 + y^2 + 1/2').sage() #optional - axiom # optional - sage.symbolic y^2 + x^2 + 1/2 - sage: _.parent() #optional - axiom + sage: _.parent() #optional - axiom # optional - sage.symbolic Multivariate Polynomial Ring in y, x over Rational Field diff --git a/src/sage/interfaces/tests.py b/src/sage/interfaces/tests.py index 6c0942e04f4..a77a66e7876 100644 --- a/src/sage/interfaces/tests.py +++ b/src/sage/interfaces/tests.py @@ -15,7 +15,7 @@ Gap sage: a = 2 * maxima('2'); a # optional - sage.symbolic 4 - sage: parent(a) + sage: parent(a) # optional - sage.symbolic Maxima sage: a = 2 * singular('2'); a 4 From caa86847954d72b88b6bfc69e39b5c0809fde134 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 31 May 2023 23:15:29 -0700 Subject: [PATCH 325/463] sage.interfaces: Modularization fixes --- src/sage/interfaces/gp.py | 1 + src/sage/interfaces/interface.py | 20 +++++++------- src/sage/interfaces/maxima_abstract.py | 37 +++++++++++++++----------- src/sage/interfaces/sympy_wrapper.py | 1 + 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index c777bc6bd40..974ef82a406 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari r""" Interface to the GP calculator of PARI/GP diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 4c0f1205092..3774d033e0f 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -349,14 +349,14 @@ def _coerce_impl(self, x, use_special=True): if isinstance(x, bool): return self(self._true_symbol() if x else self._false_symbol()) elif isinstance(x, int): - import sage.rings.all - return self(sage.rings.all.Integer(x)) + from sage.rings.integer import Integer + return self(Integer(x)) elif isinstance(x, float): - import sage.rings.all - return self(sage.rings.all.RDF(x)) + from sage.rings.real_double import RDF + return self(RDF(x)) elif isinstance(x, complex): - import sage.rings.all - return self(sage.rings.all.CDF(x)) + from sage.rings.complex_double import CDF + return self(CDF(x)) if use_special: try: return self._coerce_from_special_method(x) @@ -1374,8 +1374,8 @@ def _integer_(self, ZZ=None): sage: QQ(m) 1 """ - import sage.rings.all - return sage.rings.all.Integer(repr(self)) + from sage.rings.integer import Integer + return Integer(repr(self)) def _rational_(self): """ @@ -1389,8 +1389,8 @@ def _rational_(self): sage: QQ(m) 1/2 """ - import sage.rings.all - return sage.rings.all.Rational(repr(self)) + from sage.rings.rational import Rational + return Rational(repr(self)) def name(self, new_name=None): """ diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index 9fe624a7f02..bdb4494edf9 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -1020,11 +1020,13 @@ def plot_list(self, ptsx, ptsy, options=None): EXAMPLES:: - sage: zeta_ptsx = [ (pari(1/2 + i*I/10).zeta().real()).precision(1) for i in range(70,150)] - sage: zeta_ptsy = [ (pari(1/2 + i*I/10).zeta().imag()).precision(1) for i in range(70,150)] - sage: maxima.plot_list(zeta_ptsx, zeta_ptsy) # not tested + sage: zeta_ptsx = [(pari(1/2 + i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + ....: for i in range(70,150)] + sage: zeta_ptsy = [(pari(1/2 + i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + ....: for i in range(70,150)] + sage: maxima.plot_list(zeta_ptsx, zeta_ptsy) # not tested # optional - sage.libs.pari sage: opts='[gnuplot_preamble, "set nokey"], [gnuplot_term, ps], [gnuplot_out_file, "zeta.eps"]' - sage: maxima.plot_list(zeta_ptsx, zeta_ptsy, opts) # not tested + sage: maxima.plot_list(zeta_ptsx, zeta_ptsy, opts) # not tested # optional - sage.libs.pari """ cmd = 'plot2d([discrete,%s, %s]' % (ptsx, ptsy) if options is None: @@ -1056,18 +1058,23 @@ def plot_multilist(self, pts_list, options=None): EXAMPLES:: - sage: xx = [ i/10.0 for i in range(-10,10)] - sage: yy = [ i/10.0 for i in range(-10,10)] - sage: x0 = [ 0 for i in range(-10,10)] - sage: y0 = [ 0 for i in range(-10,10)] - sage: zeta_ptsx1 = [ (pari(1/2+i*I/10).zeta().real()).precision(1) for i in range(10)] - sage: zeta_ptsy1 = [ (pari(1/2+i*I/10).zeta().imag()).precision(1) for i in range(10)] - sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]]) # not tested - sage: zeta_ptsx1 = [ (pari(1/2+i*I/10).zeta().real()).precision(1) for i in range(10,150)] - sage: zeta_ptsy1 = [ (pari(1/2+i*I/10).zeta().imag()).precision(1) for i in range(10,150)] - sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]]) # not tested + sage: xx = [i/10.0 for i in range(-10,10)] + sage: yy = [i/10.0 for i in range(-10,10)] + sage: x0 = [0 for i in range(-10,10)] + sage: y0 = [0 for i in range(-10,10)] + sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + ....: for i in range(10)] + sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + ....: for i in range(10)] + sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1], [xx,y0], [x0,yy]]) # not tested + sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + ....: for i in range(10,150)] + sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + ....: for i in range(10,150)] + sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1], [xx,y0], [x0,yy]]) # not tested sage: opts='[gnuplot_preamble, "set nokey"]' - sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]],opts) # not tested + sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1], [xx,y0], [x0,yy]], # not tested + ....: opts) """ n = len(pts_list) cmd = '[' diff --git a/src/sage/interfaces/sympy_wrapper.py b/src/sage/interfaces/sympy_wrapper.py index 7f49cb76923..792d1eaee99 100644 --- a/src/sage/interfaces/sympy_wrapper.py +++ b/src/sage/interfaces/sympy_wrapper.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sympy """ Wrapper Class for Sage Sets as SymPy Sets """ From 2b0112d5ee64548920eaff8a201de1dfd2751121 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 23:47:37 -0700 Subject: [PATCH 326/463] More # optional --- src/sage/interfaces/quit.py | 18 +++++++++--------- src/sage/interfaces/sagespawn.pyx | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/sage/interfaces/quit.py b/src/sage/interfaces/quit.py index afc87aed1a7..720ea3f080a 100644 --- a/src/sage/interfaces/quit.py +++ b/src/sage/interfaces/quit.py @@ -63,14 +63,14 @@ def expect_quitall(verbose=False): EXAMPLES:: sage: sage.interfaces.quit.expect_quitall() - sage: gp.eval('a=10') + sage: gp.eval('a=10') # optional - sage.libs.pari '10' - sage: gp('a') + sage: gp('a') # optional - sage.libs.pari 10 sage: sage.interfaces.quit.expect_quitall() - sage: gp('a') + sage: gp('a') # optional - sage.libs.pari a - sage: sage.interfaces.quit.expect_quitall(verbose=True) + sage: sage.interfaces.quit.expect_quitall(verbose=True) # optional - sage.libs.pari Exiting PARI/GP interpreter with PID ... running .../gp --fast --emacs --quiet --stacksize 10000000 """ for P in expect_objects: @@ -87,18 +87,18 @@ def kill_spawned_jobs(verbose=False): """ INPUT: - - ``verbose`` -- bool (default: False); if True, display a - message each time a process is sent a kill signal + - ``verbose`` -- bool (default: ``False``); if ``True``, display a + message each time a process is sent a kill signal EXAMPLES:: - sage: gp.eval('a=10') + sage: gp.eval('a=10') # optional - sage.libs.pari '10' sage: sage.interfaces.quit.kill_spawned_jobs(verbose=False) sage: sage.interfaces.quit.expect_quitall() - sage: gp.eval('a=10') + sage: gp.eval('a=10') # optional - sage.libs.pari '10' - sage: sage.interfaces.quit.kill_spawned_jobs(verbose=True) + sage: sage.interfaces.quit.kill_spawned_jobs(verbose=True) # optional - sage.libs.pari Killing spawned job ... After doing the above, we do the following to avoid confusion in other doctests:: diff --git a/src/sage/interfaces/sagespawn.pyx b/src/sage/interfaces/sagespawn.pyx index 6bb9b90e580..497efc74bba 100644 --- a/src/sage/interfaces/sagespawn.pyx +++ b/src/sage/interfaces/sagespawn.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - ptyprocess """ Sage wrapper around pexpect's ``spawn`` class and the ptyprocess's ``PtyProcess`` class. From fa011659f1686a0870c9c5bc33549a2c18dba303 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 19 Jun 2023 00:11:47 -0700 Subject: [PATCH 327/463] More # optional --- src/sage/interfaces/sage0.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index 9eddb7019f7..a8bb27975c3 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -506,9 +506,9 @@ def _sage_(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: F == sage0(F)._sage_() + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.modules + sage: F,s = sr.polynomial_system() # optional - sage.modules + sage: F == sage0(F)._sage_() # optional - sage.modules True """ P = self.parent() From 19a524be5c2dd22be4fd894232766f8ccf0a81cb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 19 Jun 2023 23:43:13 -0700 Subject: [PATCH 328/463] More # optional --- src/sage/interfaces/sage0.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index a8bb27975c3..0d43f2bd6b9 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -506,9 +506,9 @@ def _sage_(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.modules - sage: F,s = sr.polynomial_system() # optional - sage.modules - sage: F == sage0(F)._sage_() # optional - sage.modules + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.modules sage.rings.finite_rings + sage: F,s = sr.polynomial_system() # optional - sage.modules sage.rings.finite_rings + sage: F == sage0(F)._sage_() # optional - sage.modules sage.rings.finite_rings True """ P = self.parent() From e953197fc52ea3504442cb0561a1f9cf31dfa7a1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 12 Jul 2023 17:25:38 -0700 Subject: [PATCH 329/463] ./sage -fixdoctests --no-test src/sage/interfaces --- src/sage/interfaces/axiom.py | 20 +++++++++--------- src/sage/interfaces/gfan.py | 4 ++-- src/sage/interfaces/gp.py | 28 +++++++++++++------------- src/sage/interfaces/jmoldata.py | 6 +++--- src/sage/interfaces/maxima_abstract.py | 16 +++++++-------- src/sage/interfaces/quit.py | 28 +++++++++++++------------- src/sage/interfaces/sage0.py | 6 +++--- src/sage/interfaces/tests.py | 4 ++-- 8 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index b00e9fc68a0..f61fcc638f9 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -796,12 +796,12 @@ def _sage_(self): 2.12340000000000 sage: _.parent() #optional - axiom Real Field with 53 bits of precision - sage: a = RealField(100)(pi) # optional - sage.symbolic - sage: axiom(a)._sage_() #optional - axiom # optional - sage.symbolic + sage: a = RealField(100)(pi) # needs sage.symbolic + sage: axiom(a)._sage_() # optional - axiom # needs sage.symbolic 3.1415926535897932384626433833 - sage: _.parent() #optional - axiom # optional - sage.symbolic + sage: _.parent() # optional - axiom # needs sage.symbolic Real Field with 100 bits of precision - sage: axiom(a)._sage_() == a #optional - axiom # optional - sage.symbolic + sage: axiom(a)._sage_() == a # optional - axiom # needs sage.symbolic True sage: axiom(2.0)._sage_() #optional - axiom 2.00000000000000 @@ -810,16 +810,16 @@ def _sage_(self): We can also convert Axiom's polynomials to Sage polynomials. - sage: a = axiom(x^2 + 1) #optional - axiom # optional - sage.symbolic - sage: a.type() #optional - axiom # optional - sage.symbolic + sage: a = axiom(x^2 + 1) # optional - axiom # needs sage.symbolic + sage: a.type() # optional - axiom # needs sage.symbolic Polynomial Integer - sage: a.sage() #optional - axiom # optional - sage.symbolic + sage: a.sage() # optional - axiom # needs sage.symbolic x^2 + 1 - sage: _.parent() #optional - axiom # optional - sage.symbolic + sage: _.parent() # optional - axiom # needs sage.symbolic Univariate Polynomial Ring in x over Integer Ring - sage: axiom('x^2 + y^2 + 1/2').sage() #optional - axiom # optional - sage.symbolic + sage: axiom('x^2 + y^2 + 1/2').sage() # optional - axiom # needs sage.symbolic y^2 + x^2 + 1/2 - sage: _.parent() #optional - axiom # optional - sage.symbolic + sage: _.parent() # optional - axiom # needs sage.symbolic Multivariate Polynomial Ring in y, x over Rational Field diff --git a/src/sage/interfaces/gfan.py b/src/sage/interfaces/gfan.py index ffb75c39b35..01429c5cde6 100644 --- a/src/sage/interfaces/gfan.py +++ b/src/sage/interfaces/gfan.py @@ -63,7 +63,7 @@ def __call__(self, input, cmd='', verbose=False, format=None): EXAMPLES:: - sage: print(gfan('Q[x,y]{x^2-y-1,y^2-xy-2/3}', cmd='bases')) # optional - gfan + sage: print(gfan('Q[x,y]{x^2-y-1,y^2-xy-2/3}', cmd='bases')) # needs gfan Q[x,y] {{ y^4+4/9-7/3*y^2-y^3, @@ -85,7 +85,7 @@ def __call__(self, input, cmd='', verbose=False, format=None): TESTS:: - sage: _ = gfan(I='Q[x,y]{x^2-y-1,y^2-xy-2/3}', cmd='bases') # optional - gfan + sage: _ = gfan(I='Q[x,y]{x^2-y-1,y^2-xy-2/3}', cmd='bases') # needs gfan doctest:...: DeprecationWarning: use the option 'input' instead of 'I' See https://github.com/sagemath/sage/issues/33468 for details. diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index 974ef82a406..d1085562828 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -788,26 +788,26 @@ def new_with_bits_prec(self, s, precision=0): EXAMPLES:: - sage: pi_def = gp(pi); pi_def # optional - sage.symbolic + sage: pi_def = gp(pi); pi_def # needs sage.symbolic 3.141592653589793238462643383 # 32-bit 3.1415926535897932384626433832795028842 # 64-bit - sage: pi_def.precision() # optional - sage.symbolic + sage: pi_def.precision() # needs sage.symbolic 28 # 32-bit 38 # 64-bit - sage: pi_150 = gp.new_with_bits_prec(pi, 150) # optional - sage.symbolic - sage: new_prec = pi_150.precision(); new_prec # optional - sage.symbolic + sage: pi_150 = gp.new_with_bits_prec(pi, 150) # needs sage.symbolic + sage: new_prec = pi_150.precision(); new_prec # needs sage.symbolic 48 # 32-bit 57 # 64-bit - sage: old_prec = gp.set_precision(new_prec); old_prec # optional - sage.symbolic + sage: old_prec = gp.set_precision(new_prec); old_prec # needs sage.symbolic 28 # 32-bit 38 # 64-bit - sage: pi_150 # optional - sage.symbolic + sage: pi_150 # needs sage.symbolic 3.14159265358979323846264338327950288419716939938 # 32-bit 3.14159265358979323846264338327950288419716939937510582098 # 64-bit - sage: gp.set_precision(old_prec) # optional - sage.symbolic + sage: gp.set_precision(old_prec) # needs sage.symbolic 48 # 32-bit 57 # 64-bit - sage: gp.get_precision() # optional - sage.symbolic + sage: gp.get_precision() # needs sage.symbolic 28 # 32-bit 38 # 64-bit """ @@ -878,9 +878,9 @@ def _sage_(self): EXAMPLES:: - sage: gp(SR(I)).sage() # optional - sage.symbolic + sage: gp(SR(I)).sage() # needs sage.symbolic i - sage: gp(SR(I)).sage().parent() # optional - sage.symbolic + sage: gp(SR(I)).sage().parent() # needs sage.symbolic Number Field in i with defining polynomial x^2 + 1 with i = 1*I :: @@ -956,11 +956,11 @@ def _complex_mpfr_field_(self, CC): EXAMPLES:: - sage: z = gp(SR(1+15*I)); z # optional - sage.symbolic + sage: z = gp(SR(1+15*I)); z # needs sage.symbolic 1 + 15*I - sage: z._complex_mpfr_field_(CC) # optional - sage.symbolic + sage: z._complex_mpfr_field_(CC) # needs sage.symbolic 1.00000000000000 + 15.0000000000000*I - sage: CC(z) # CC(gp(1+15*I)) # optional - sage.symbolic + sage: CC(z) # CC(gp(1+15*I)) # needs sage.symbolic 1.00000000000000 + 15.0000000000000*I sage: CC(gp(11243.9812+15*I)) 11243.9812000000 + 15.0000000000000*I @@ -978,7 +978,7 @@ def _complex_double_(self, CDF): EXAMPLES:: - sage: CDF(gp(pi+I*e)) # optional - sage.symbolic + sage: CDF(gp(pi+I*e)) # needs sage.symbolic 3.141592653589793 + 2.718281828459045*I """ # Retrieving values from another computer algebra system is diff --git a/src/sage/interfaces/jmoldata.py b/src/sage/interfaces/jmoldata.py index 2890a8a7a76..3e83043d747 100644 --- a/src/sage/interfaces/jmoldata.py +++ b/src/sage/interfaces/jmoldata.py @@ -134,10 +134,10 @@ def export_image(self, sage: from sage.interfaces.jmoldata import JmolData sage: JData = JmolData() - sage: D = dodecahedron() # optional - sage.plot + sage: D = dodecahedron() # needs sage.plot sage: from tempfile import NamedTemporaryFile sage: archive = NamedTemporaryFile(suffix=".zip") - sage: D.export_jmol(archive.name) # optional - sage.plot + sage: D.export_jmol(archive.name) # needs sage.plot sage: archive_native = archive.name sage: import sys sage: if sys.platform == 'cygwin': @@ -145,7 +145,7 @@ def export_image(self, ....: archive_native = cygwin.cygpath(archive_native, 'w') sage: script = f'set defaultdirectory "f{archive_native}"\n' sage: script += 'script SCRIPT\n' - sage: with NamedTemporaryFile(suffix=".png") as testfile: # optional -- java sage.plot + sage: with NamedTemporaryFile(suffix=".png") as testfile: # optional - java, needs sage.plot ....: JData.export_image(targetfile=testfile.name, ....: datafile=script, ....: image_type="PNG") diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index bdb4494edf9..abc43baf127 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -1020,13 +1020,13 @@ def plot_list(self, ptsx, ptsy, options=None): EXAMPLES:: - sage: zeta_ptsx = [(pari(1/2 + i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsx = [(pari(1/2 + i*I/10).zeta().real()).precision(1) # needs sage.libs.pari ....: for i in range(70,150)] - sage: zeta_ptsy = [(pari(1/2 + i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsy = [(pari(1/2 + i*I/10).zeta().imag()).precision(1) # needs sage.libs.pari ....: for i in range(70,150)] - sage: maxima.plot_list(zeta_ptsx, zeta_ptsy) # not tested # optional - sage.libs.pari + sage: maxima.plot_list(zeta_ptsx, zeta_ptsy) # not tested # needs sage.libs.pari sage: opts='[gnuplot_preamble, "set nokey"], [gnuplot_term, ps], [gnuplot_out_file, "zeta.eps"]' - sage: maxima.plot_list(zeta_ptsx, zeta_ptsy, opts) # not tested # optional - sage.libs.pari + sage: maxima.plot_list(zeta_ptsx, zeta_ptsy, opts) # not tested # needs sage.libs.pari """ cmd = 'plot2d([discrete,%s, %s]' % (ptsx, ptsy) if options is None: @@ -1062,14 +1062,14 @@ def plot_multilist(self, pts_list, options=None): sage: yy = [i/10.0 for i in range(-10,10)] sage: x0 = [0 for i in range(-10,10)] sage: y0 = [0 for i in range(-10,10)] - sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # needs sage.libs.pari ....: for i in range(10)] - sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # needs sage.libs.pari ....: for i in range(10)] sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1], [xx,y0], [x0,yy]]) # not tested - sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsx1 = [(pari(1/2+i*I/10).zeta().real()).precision(1) # needs sage.libs.pari ....: for i in range(10,150)] - sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # optional - sage.libs.pari + sage: zeta_ptsy1 = [(pari(1/2+i*I/10).zeta().imag()).precision(1) # needs sage.libs.pari ....: for i in range(10,150)] sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1], [xx,y0], [x0,yy]]) # not tested sage: opts='[gnuplot_preamble, "set nokey"]' diff --git a/src/sage/interfaces/quit.py b/src/sage/interfaces/quit.py index 720ea3f080a..99e5aa018f3 100644 --- a/src/sage/interfaces/quit.py +++ b/src/sage/interfaces/quit.py @@ -63,14 +63,14 @@ def expect_quitall(verbose=False): EXAMPLES:: sage: sage.interfaces.quit.expect_quitall() - sage: gp.eval('a=10') # optional - sage.libs.pari + sage: gp.eval('a=10') # needs sage.libs.pari '10' - sage: gp('a') # optional - sage.libs.pari + sage: gp('a') # needs sage.libs.pari 10 sage: sage.interfaces.quit.expect_quitall() - sage: gp('a') # optional - sage.libs.pari + sage: gp('a') # needs sage.libs.pari a - sage: sage.interfaces.quit.expect_quitall(verbose=True) # optional - sage.libs.pari + sage: sage.interfaces.quit.expect_quitall(verbose=True) # needs sage.libs.pari Exiting PARI/GP interpreter with PID ... running .../gp --fast --emacs --quiet --stacksize 10000000 """ for P in expect_objects: @@ -92,13 +92,13 @@ def kill_spawned_jobs(verbose=False): EXAMPLES:: - sage: gp.eval('a=10') # optional - sage.libs.pari + sage: gp.eval('a=10') # needs sage.libs.pari '10' sage: sage.interfaces.quit.kill_spawned_jobs(verbose=False) sage: sage.interfaces.quit.expect_quitall() - sage: gp.eval('a=10') # optional - sage.libs.pari + sage: gp.eval('a=10') # needs sage.libs.pari '10' - sage: sage.interfaces.quit.kill_spawned_jobs(verbose=True) # optional - sage.libs.pari + sage: sage.interfaces.quit.kill_spawned_jobs(verbose=True) # needs sage.libs.pari Killing spawned job ... After doing the above, we do the following to avoid confusion in other doctests:: @@ -140,19 +140,19 @@ def invalidate_all(): EXAMPLES:: - sage: a = maxima(2); b = gp(3) # optional - sage.libs.pari sage.symbolic - sage: a, b # optional - sage.libs.pari sage.symbolic + sage: a = maxima(2); b = gp(3) # needs sage.libs.pari sage.symbolic + sage: a, b # needs sage.libs.pari sage.symbolic (2, 3) - sage: sage.interfaces.quit.invalidate_all() # optional - sage.libs.pari sage.symbolic - sage: a # optional - sage.libs.pari sage.symbolic + sage: sage.interfaces.quit.invalidate_all() # needs sage.libs.pari sage.symbolic + sage: a # needs sage.libs.pari sage.symbolic (invalid Maxima object -- The maxima session in which this object was defined is no longer running.) - sage: b # optional - sage.libs.pari sage.symbolic + sage: b # needs sage.libs.pari sage.symbolic (invalid PARI/GP interpreter object -- The pari session in which this object was defined is no longer running.) However the maxima and gp sessions should still work out, though with their state reset:: - sage: a = maxima(2); b = gp(3) # optional - sage.libs.pari sage.symbolic - sage: a, b # optional - sage.libs.pari sage.symbolic + sage: a = maxima(2); b = gp(3) # needs sage.libs.pari sage.symbolic + sage: a, b # needs sage.libs.pari sage.symbolic (2, 3) """ for I in expect_objects: diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index 0d43f2bd6b9..1505d1f2f69 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -506,9 +506,9 @@ def _sage_(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.modules sage.rings.finite_rings - sage: F,s = sr.polynomial_system() # optional - sage.modules sage.rings.finite_rings - sage: F == sage0(F)._sage_() # optional - sage.modules sage.rings.finite_rings + sage: sr = mq.SR(allow_zero_inversions=True) # needs sage.modules sage.rings.finite_rings + sage: F,s = sr.polynomial_system() # needs sage.modules sage.rings.finite_rings + sage: F == sage0(F)._sage_() # needs sage.modules sage.rings.finite_rings True """ P = self.parent() diff --git a/src/sage/interfaces/tests.py b/src/sage/interfaces/tests.py index a77a66e7876..13f755b4d11 100644 --- a/src/sage/interfaces/tests.py +++ b/src/sage/interfaces/tests.py @@ -13,9 +13,9 @@ 4 sage: parent(a) Gap - sage: a = 2 * maxima('2'); a # optional - sage.symbolic + sage: a = 2 * maxima('2'); a # needs sage.symbolic 4 - sage: parent(a) # optional - sage.symbolic + sage: parent(a) # needs sage.symbolic Maxima sage: a = 2 * singular('2'); a 4 From 85baf286d318f4d453c2a586e4993118111523fc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 13 Jul 2023 22:30:42 -0700 Subject: [PATCH 330/463] sage.interfaces: Update # needs --- src/sage/interfaces/interface.py | 18 ++++++++++-------- src/sage/interfaces/quit.py | 11 ++++++----- src/sage/interfaces/sage0.py | 1 + 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 3774d033e0f..94b8307cea4 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -882,11 +882,12 @@ def _reduce(self): by the doctests because the original identifier was reused. This test makes sure that does not happen again:: - sage: a = r("'abc'") # optional - rpy2 - sage: b = dumps(a) # optional - rpy2 - sage: r.set(a.name(), 0) # make sure that identifier reuse # optional - rpy2 + sage: # optional - rpy2 + sage: a = r("'abc'") + sage: b = dumps(a) + sage: r.set(a.name(), 0) # make sure that identifier reuse ....: # does not accidentally lead to success - sage: loads(b) # optional - rpy2 + sage: loads(b) [1] "abc" """ @@ -1402,13 +1403,14 @@ def name(self, new_name=None): EXAMPLES:: - sage: x = r([1,2,3]); x # optional - rpy2 + sage: # optional - rpy2 + sage: x = r([1,2,3]); x [1] 1 2 3 - sage: x.name() # optional - rpy2 + sage: x.name() 'sage...' - sage: x = r([1,2,3]).name('x'); x # optional - rpy2 + sage: x = r([1,2,3]).name('x'); x [1] 1 2 3 - sage: x.name() # optional - rpy2 + sage: x.name() 'x' :: diff --git a/src/sage/interfaces/quit.py b/src/sage/interfaces/quit.py index 99e5aa018f3..c10b1414dde 100644 --- a/src/sage/interfaces/quit.py +++ b/src/sage/interfaces/quit.py @@ -140,13 +140,14 @@ def invalidate_all(): EXAMPLES:: - sage: a = maxima(2); b = gp(3) # needs sage.libs.pari sage.symbolic - sage: a, b # needs sage.libs.pari sage.symbolic + sage: # needs sage.libs.pari sage.symbolic + sage: a = maxima(2); b = gp(3) + sage: a, b (2, 3) - sage: sage.interfaces.quit.invalidate_all() # needs sage.libs.pari sage.symbolic - sage: a # needs sage.libs.pari sage.symbolic + sage: sage.interfaces.quit.invalidate_all() + sage: a (invalid Maxima object -- The maxima session in which this object was defined is no longer running.) - sage: b # needs sage.libs.pari sage.symbolic + sage: b (invalid PARI/GP interpreter object -- The pari session in which this object was defined is no longer running.) However the maxima and gp sessions should still work out, though with their state reset:: diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index 1505d1f2f69..11ece30ac56 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.all r""" Interface to Sage From 1393952b559324cbcb772c1a36b5a31f74e2eda3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 6 Aug 2023 20:45:08 -0700 Subject: [PATCH 331/463] src/sage/interfaces: Update file-level doctest tag --- src/sage/interfaces/expect.py | 2 +- src/sage/interfaces/gp.py | 3 ++- src/sage/interfaces/interface.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 9c38a8c1cba..a5ba8f09f4e 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic +# sage.doctest: needs sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic """ Common Interface Functionality through Pexpect diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index d1085562828..6e12504e829 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -1,4 +1,5 @@ -# sage.doctest: optional - sage.libs.pari +# sage_setup: distribution = sagemath-pari +# sage.doctest: needs sage.libs.pari r""" Interface to the GP calculator of PARI/GP diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 94b8307cea4..8e89aa65c1e 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic +# sage.doctest: needs sage.libs.gap sage.libs.pari sage.libs.singular sage.symbolic r""" Common Interface Functionality From 12e2a4628a52695e28835e8269966b4f05aa024b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 7 Aug 2023 22:44:16 -0700 Subject: [PATCH 332/463] src/sage/interfaces: sage -fixdoctests --only-tags --- src/sage/interfaces/axiom.py | 97 +++---- src/sage/interfaces/fricas.py | 137 +++++----- src/sage/interfaces/frobby.py | 85 ++++--- src/sage/interfaces/kash.py | 139 +++++----- src/sage/interfaces/kenzo.py | 396 +++++++++++++++-------------- src/sage/interfaces/lie.py | 80 +++--- src/sage/interfaces/macaulay2.py | 10 +- src/sage/interfaces/magma.py | 298 ++++++++++++---------- src/sage/interfaces/maple.py | 16 ++ src/sage/interfaces/mathematica.py | 88 ++++--- src/sage/interfaces/mathics.py | 160 ++++++------ src/sage/interfaces/matlab.py | 77 +++--- src/sage/interfaces/mupad.py | 80 +++--- src/sage/interfaces/octave.py | 126 ++++----- src/sage/interfaces/polymake.py | 164 ++++++------ src/sage/interfaces/qepcad.py | 70 ++--- src/sage/interfaces/rubik.py | 57 +++-- src/sage/interfaces/scilab.py | 134 +++++----- 18 files changed, 1209 insertions(+), 1005 deletions(-) diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index f61fcc638f9..5933e633d38 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -304,12 +304,13 @@ def _commands(self): EXAMPLES:: - sage: cmds = axiom._commands() #optional - axiom - sage: len(cmds) > 100 #optional - axiom + sage: # optional - axiom + sage: cmds = axiom._commands() + sage: len(cmds) > 100 True - sage: '<' in cmds #optional - axiom + sage: '<' in cmds True - sage: 'factor' in cmds #optional - axiom + sage: 'factor' in cmds True """ s = self.eval(")what things") @@ -327,18 +328,19 @@ def _tab_completion(self, verbose=True, use_disk_cache=True): EXAMPLES:: - sage: c = axiom._tab_completion(use_disk_cache=False, verbose=False) #optional - axiom - sage: len(c) > 100 #optional - axiom + sage: # optional - axiom + sage: c = axiom._tab_completion(use_disk_cache=False, verbose=False) + sage: len(c) > 100 True - sage: 'factor' in c #optional - axiom + sage: 'factor' in c True - sage: '**' in c #optional - axiom + sage: '**' in c False - sage: 'upperCase?' in c #optional - axiom + sage: 'upperCase?' in c False - sage: 'upperCase_q' in c #optional - axiom + sage: 'upperCase_q' in c True - sage: 'upperCase_e' in c #optional - axiom + sage: 'upperCase_e' in c True """ try: @@ -396,11 +398,12 @@ def get(self, var): EXAMPLES:: - sage: axiom.set('xx', '2') #optional - axiom - sage: axiom.get('xx') #optional - axiom + sage: # optional - axiom + sage: axiom.set('xx', '2') + sage: axiom.get('xx') '2' - sage: a = axiom('(1 + sqrt(2))^5') #optional - axiom - sage: axiom.get(a.name()) #optional - axiom + sage: a = axiom('(1 + sqrt(2))^5') + sage: axiom.get(a.name()) ' +-+\r\r\n 29\\|2 + 41' """ s = self._eval_line(str(var)) @@ -571,26 +574,28 @@ def _richcmp_(self, other, op): """ EXAMPLES:: - sage: two = axiom(2) #optional - axiom - sage: two == 2 #optional - axiom + sage: # optional - axiom + sage: two = axiom(2) + sage: two == 2 True - sage: two == 3 #optional - axiom + sage: two == 3 False - sage: two < 3 #optional - axiom + sage: two < 3 True - sage: two > 1 #optional - axiom + sage: two > 1 True - sage: a = axiom(1); b = axiom(2) #optional - axiom - sage: a == b #optional - axiom + sage: # optional - axiom + sage: a = axiom(1); b = axiom(2) + sage: a == b False - sage: a < b #optional - axiom + sage: a < b True - sage: a > b #optional - axiom + sage: a > b False - sage: b < a #optional - axiom + sage: b < a False - sage: b > a #optional - axiom + sage: b > a True We can also compare more complicated object such as functions:: @@ -649,15 +654,16 @@ def __getitem__(self, n): EXAMPLES:: - sage: v = axiom('[i*x^i for i in 0..5]'); v # optional - axiom + sage: # optional - axiom + sage: v = axiom('[i*x^i for i in 0..5]'); v 2 3 4 5 [0,x,2x ,3x ,4x ,5x ] - sage: v[4] # optional - axiom + sage: v[4] 3 3x - sage: v[1] # optional - axiom + sage: v[1] 0 - sage: v[10] # optional - axiom + sage: v[10] Traceback (most recent call last): ... IndexError: index out of range @@ -677,12 +683,13 @@ def comma(self, *args): EXAMPLES:: - sage: two = axiom(2) #optional - axiom - sage: two.comma(3) #optional - axiom + sage: # optional - axiom + sage: two = axiom(2) + sage: two.comma(3) [2,3] - sage: two.comma(3,4) #optional - axiom + sage: two.comma(3,4) [2,3,4] - sage: _.type() #optional - axiom + sage: _.type() Tuple PositiveInteger """ P = self._check_valid() @@ -810,16 +817,17 @@ def _sage_(self): We can also convert Axiom's polynomials to Sage polynomials. - sage: a = axiom(x^2 + 1) # optional - axiom # needs sage.symbolic - sage: a.type() # optional - axiom # needs sage.symbolic + sage: # optional - axiom, needs sage.symbolic + sage: a = axiom(x^2 + 1) + sage: a.type() Polynomial Integer - sage: a.sage() # optional - axiom # needs sage.symbolic + sage: a.sage() x^2 + 1 - sage: _.parent() # optional - axiom # needs sage.symbolic + sage: _.parent() Univariate Polynomial Ring in x over Integer Ring - sage: axiom('x^2 + y^2 + 1/2').sage() # optional - axiom # needs sage.symbolic + sage: axiom('x^2 + y^2 + 1/2').sage() y^2 + x^2 + 1/2 - sage: _.parent() # optional - axiom # needs sage.symbolic + sage: _.parent() Multivariate Polynomial Ring in y, x over Rational Field @@ -902,12 +910,13 @@ def __init__(self, object, name): """ TESTS:: - sage: a = axiom('"Hello"') #optional - axiom - sage: a.upperCase_q #optional - axiom + sage: # optional - axiom + sage: a = axiom('"Hello"') + sage: a.upperCase_q upperCase? - sage: a.upperCase_e #optional - axiom + sage: a.upperCase_e upperCase! - sage: a.upperCase_e() #optional - axiom + sage: a.upperCase_e() "HELLO" """ if name.endswith("_q"): diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index c771aea716c..c19feb3a7e5 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -313,13 +313,14 @@ def _start(self): EXAMPLES:: - sage: a = FriCAS() # optional - fricas - sage: a.is_running() # optional - fricas + sage: # optional - fricas + sage: a = FriCAS() + sage: a.is_running() False - sage: a._start() # optional - fricas - sage: a.is_running() # optional - fricas + sage: a._start() + sage: a.is_running() True - sage: a.quit() # optional - fricas + sage: a.quit() """ # setting the prompt properly is necessary for restarting FriCAS self._prompt = FRICAS_FIRST_PROMPT @@ -356,16 +357,17 @@ def _quit_string(self): EXAMPLES:: - sage: fricas._quit_string() # optional - fricas + sage: # optional - fricas + sage: fricas._quit_string() ')quit' - sage: a = FriCAS() # optional - fricas - sage: a.is_running() # optional - fricas + sage: a = FriCAS() + sage: a.is_running() False - sage: a._start() # optional - fricas - sage: a.is_running() # optional - fricas + sage: a._start() + sage: a.is_running() True - sage: a.quit() # optional - fricas - sage: a.is_running() # optional - fricas + sage: a.quit() + sage: a.is_running() False TESTS: @@ -387,12 +389,13 @@ def _commands(self): EXAMPLES:: - sage: cmds = fricas._commands() # optional - fricas - sage: len(cmds) > 100 # optional - fricas + sage: # optional - fricas + sage: cmds = fricas._commands() + sage: len(cmds) > 100 True - sage: '<' in cmds # optional - fricas + sage: '<' in cmds True - sage: 'factor' in cmds # optional - fricas + sage: 'factor' in cmds True """ output = self.eval(")what operations", reformat=False) @@ -408,18 +411,19 @@ def _tab_completion(self, verbose=True, use_disk_cache=True): EXAMPLES:: - sage: c = fricas._tab_completion(use_disk_cache=False, verbose=False) # optional - fricas - sage: len(c) > 100 # optional - fricas + sage: # optional - fricas + sage: c = fricas._tab_completion(use_disk_cache=False, verbose=False) + sage: len(c) > 100 True - sage: 'factor' in c # optional - fricas + sage: 'factor' in c True - sage: '**' in c # optional - fricas + sage: '**' in c False - sage: 'upperCase?' in c # optional - fricas + sage: 'upperCase?' in c False - sage: 'upperCase_q' in c # optional - fricas + sage: 'upperCase_q' in c True - sage: 'upperCase_e' in c # optional - fricas + sage: 'upperCase_e' in c True """ try: @@ -676,15 +680,16 @@ def get(self, var): EXAMPLES:: - sage: fricas.set('xx', '2') # optional - fricas - sage: fricas.get('xx') # optional - fricas + sage: # optional - fricas + sage: fricas.set('xx', '2') + sage: fricas.get('xx') '2' - sage: a = fricas('(1 + sqrt(2))^5') # optional - fricas - sage: fricas.get(a.name()) # optional - fricas + sage: a = fricas('(1 + sqrt(2))^5') + sage: fricas.get(a.name()) ' +-+\n29 \\|2 + 41' - sage: fricas.get('(1 + sqrt(2))^5') # optional - fricas + sage: fricas.get('(1 + sqrt(2))^5') ' +-+\n29 \\|2 + 41' - sage: fricas.new('(1 + sqrt(2))^5') # optional - fricas + sage: fricas.new('(1 + sqrt(2))^5') +-+ 29 \|2 + 41 """ @@ -728,19 +733,20 @@ def get_string(self, var): Check that :trac:`25628` is fixed:: - sage: var("a b"); f = 1/(1+a*cos(x)) # optional - fricas + sage: # optional - fricas + sage: var("a b"); f = 1/(1+a*cos(x)) (a, b) - sage: lF = integrate(f, x, algorithm="fricas") # optional - fricas - sage: (diff(lF[0], x) - f).simplify_trig() # optional - fricas + sage: lF = integrate(f, x, algorithm="fricas") + sage: (diff(lF[0], x) - f).simplify_trig() 0 - sage: (diff(lF[1], x) - f).simplify_trig() # optional - fricas + sage: (diff(lF[1], x) - f).simplify_trig() 0 - sage: f = 1/(b*x^2+a); lF = integrate(f, x, algorithm="fricas"); lF # optional - fricas + sage: f = 1/(b*x^2+a); lF = integrate(f, x, algorithm="fricas"); lF [1/2*log((2*a*b*x + (b*x^2 - a)*sqrt(-a*b))/(b*x^2 + a))/sqrt(-a*b), arctan(sqrt(a*b)*x/a)/sqrt(a*b)] - sage: (diff(lF[0], x) - f).simplify_trig() # optional - fricas + sage: (diff(lF[0], x) - f).simplify_trig() 0 - sage: (diff(lF[1], x) - f).simplify_trig() # optional - fricas + sage: (diff(lF[1], x) - f).simplify_trig() 0 """ @@ -1613,13 +1619,14 @@ def _sage_expression(fricas_InputForm): Check conversions of sums and products:: - sage: var("k, m, n") # optional - fricas + sage: # optional - fricas + sage: var("k, m, n") (k, m, n) - sage: fricas("sum(1/factorial(k), k=1..n)").sage() # optional - fricas + sage: fricas("sum(1/factorial(k), k=1..n)").sage() sum(1/factorial(_...), _..., 1, n) - sage: fricas("eval(sum(x/k, k=1..n), x=k)").sage() # optional - fricas + sage: fricas("eval(sum(x/k, k=1..n), x=k)").sage() k*harmonic_number(n) - sage: fricas("product(1/factorial(k), k=1..n)").sage() # optional - fricas + sage: fricas("product(1/factorial(k), k=1..n)").sage() 1/product(factorial(_...), _..., 1, n) sage: f = fricas.guess([sum(1/k, k,1,n) for n in range(10)])[0]; f # optional - fricas @@ -1772,20 +1779,21 @@ def _sage_(self): Floats:: - sage: fricas(2.1234).sage() # optional - fricas + sage: # optional - fricas + sage: fricas(2.1234).sage() 2.12340000000000 - sage: _.parent() # optional - fricas + sage: _.parent() Real Field with 53 bits of precision - sage: a = RealField(100)(pi) # optional - fricas - sage: fricas(a).sage() # optional - fricas + sage: a = RealField(100)(pi) + sage: fricas(a).sage() 3.1415926535897932384626433833 - sage: _.parent() # optional - fricas + sage: _.parent() Real Field with 100 bits of precision - sage: fricas(a).sage() == a # optional - fricas + sage: fricas(a).sage() == a True - sage: fricas(2.0).sage() # optional - fricas + sage: fricas(2.0).sage() 2.00000000000000 - sage: _.parent() # optional - fricas + sage: _.parent() Real Field with 53 bits of precision Algebraic numbers:: @@ -1810,15 +1818,16 @@ def _sage_(self): We can also convert FriCAS's polynomials to Sage polynomials:: - sage: a = fricas("x^2 + 1"); a.typeOf() # optional - fricas + sage: # optional - fricas + sage: a = fricas("x^2 + 1"); a.typeOf() Polynomial(Integer) - sage: a.sage() # optional - fricas + sage: a.sage() x^2 + 1 - sage: _.parent() # optional - fricas + sage: _.parent() Univariate Polynomial Ring in x over Integer Ring - sage: fricas('x^2 + y^2 + 1/2').sage() # optional - fricas + sage: fricas('x^2 + y^2 + 1/2').sage() y^2 + x^2 + 1/2 - sage: _.parent() # optional - fricas + sage: _.parent() Multivariate Polynomial Ring in y, x over Rational Field sage: fricas("1$Polynomial Integer").sage() # optional - fricas @@ -2067,12 +2076,13 @@ def __init__(self, object, name): TESTS:: - sage: a = fricas('"Hello"') # optional - fricas - sage: a.upperCase_q # optional - fricas + sage: # optional - fricas + sage: a = fricas('"Hello"') + sage: a.upperCase_q upperCase? - sage: a.upperCase_e # optional - fricas + sage: a.upperCase_e upperCase! - sage: a.upperCase_e() # optional - fricas + sage: a.upperCase_e() "HELLO" """ @@ -2167,13 +2177,14 @@ def __doctest_cleanup(): """ EXAMPLES:: - sage: from sage.interfaces.fricas import __doctest_cleanup # optional - fricas - sage: a = FriCAS() # optional - fricas - sage: two = a(2) # optional - fricas - sage: a.is_running() # optional - fricas + sage: # optional - fricas + sage: from sage.interfaces.fricas import __doctest_cleanup + sage: a = FriCAS() + sage: two = a(2) + sage: a.is_running() True - sage: __doctest_cleanup() # optional - fricas - sage: a.is_running() # optional - fricas + sage: __doctest_cleanup() + sage: a.is_running() False """ import sage.interfaces.quit diff --git a/src/sage/interfaces/frobby.py b/src/sage/interfaces/frobby.py index aab3bd9b58f..7eb5e53becd 100644 --- a/src/sage/interfaces/frobby.py +++ b/src/sage/interfaces/frobby.py @@ -115,20 +115,22 @@ def alexander_dual(self, monomial_ideal): This is a simple example of computing irreducible decomposition. :: - sage: (a, b, c, d) = QQ['a,b,c,d'].gens() # optional - frobby - sage: id = ideal(a * b, b * c, c * d, d * a) # optional - frobby - sage: alexander_dual = frobby.alexander_dual(id) # optional - frobby - sage: true_alexander_dual = ideal(b * d, a * c) # optional - frobby - sage: alexander_dual == true_alexander_dual # use sets to ignore order # optional - frobby + sage: # optional - frobby + sage: (a, b, c, d) = QQ['a,b,c,d'].gens() + sage: id = ideal(a * b, b * c, c * d, d * a) + sage: alexander_dual = frobby.alexander_dual(id) + sage: true_alexander_dual = ideal(b * d, a * c) + sage: alexander_dual == true_alexander_dual # use sets to ignore order True We see how it is much faster to compute this with frobby than the built-in procedure for simplicial complexes:: - sage: t=simplicial_complexes.PoincareHomologyThreeSphere() # optional - frobby - sage: R=PolynomialRing(QQ,16,'x') # optional - frobby - sage: I=R.ideal([prod([R.gen(i-1) for i in a]) for a in t.facets()]) # optional - frobby - sage: len(frobby.alexander_dual(I).gens()) # optional - frobby + sage: # optional - frobby + sage: t=simplicial_complexes.PoincareHomologyThreeSphere() + sage: R=PolynomialRing(QQ,16,'x') + sage: I=R.ideal([prod([R.gen(i-1) for i in a]) for a in t.facets()]) + sage: len(frobby.alexander_dual(I).gens()) 643 @@ -261,11 +263,12 @@ def irreducible_decomposition(self, monomial_ideal): This is a simple example of computing irreducible decomposition. :: - sage: (x, y, z) = QQ['x,y,z'].gens() # optional - frobby - sage: id = ideal(x ** 2, y ** 2, x * z, y * z) # optional - frobby - sage: decom = frobby.irreducible_decomposition(id) # optional - frobby - sage: true_decom = [ideal(x, y), ideal(x ** 2, y ** 2, z)] # optional - frobby - sage: set(decom) == set(true_decom) # use sets to ignore order # optional - frobby + sage: # optional - frobby + sage: (x, y, z) = QQ['x,y,z'].gens() + sage: id = ideal(x ** 2, y ** 2, x * z, y * z) + sage: decom = frobby.irreducible_decomposition(id) + sage: true_decom = [ideal(x, y), ideal(x ** 2, y ** 2, z)] + sage: set(decom) == set(true_decom) # use sets to ignore order True We now try the special case of the zero ideal in different rings. @@ -273,25 +276,27 @@ def irreducible_decomposition(self, monomial_ideal): We should also try PolynomialRing(QQ, names=[]), but it has a bug which makes that impossible (see :trac:`3028`). :: - sage: rings = [ZZ['x'], CC['x,y']] # optional - frobby - sage: allOK = True # optional - frobby - sage: for ring in rings: # optional - frobby + sage: # optional - frobby + sage: rings = [ZZ['x'], CC['x,y']] + sage: allOK = True + sage: for ring in rings: ....: id0 = ring.ideal(0) ....: decom0 = frobby.irreducible_decomposition(id0) ....: allOK = allOK and decom0 == [id0] - sage: allOK # optional - frobby + sage: allOK True Finally, we try the ideal that is all of the ring in different rings. :: - sage: rings = [ZZ['x'], CC['x,y']] # optional - frobby - sage: allOK = True # optional - frobby - sage: for ring in rings: # optional - frobby + sage: # optional - frobby + sage: rings = [ZZ['x'], CC['x,y']] + sage: allOK = True + sage: for ring in rings: ....: id1 = ring.ideal(1) ....: decom1 = frobby.irreducible_decomposition(id1) ....: allOK = allOK and decom1 == [id1] - sage: allOK # optional - frobby + sage: allOK True """ frobby_input = self._ideal_to_string(monomial_ideal) @@ -316,10 +321,11 @@ def _parse_ideals(self, string, ring): EXAMPLES:: - sage: ring = QQ['x,y,z'] # optional - frobby - sage: (x, y, z) = ring.gens() # optional - frobby - sage: string = '2 3\n1 2 3\n0 5 0\n2 3\n1 2 3\n4 5 6' # optional - frobby - sage: frobby._parse_ideals(string, ring) # optional - frobby + sage: # optional - frobby + sage: ring = QQ['x,y,z'] + sage: (x, y, z) = ring.gens() + sage: string = '2 3\n1 2 3\n0 5 0\n2 3\n1 2 3\n4 5 6' + sage: frobby._parse_ideals(string, ring) [Ideal (x*y^2*z^3, y^5) of Multivariate Polynomial Ring in x, y, z over Rational Field, Ideal (x*y^2*z^3, x^4*y^5*z^6) of Multivariate Polynomial Ring in x, y, z over Rational Field] @@ -365,10 +371,11 @@ def _parse_4ti2_matrix(self, string): The format is straight-forward, as this example shows. :: - sage: string = '2 3\n1 2 3\n 0 5 0' # optional - frobby - sage: parsed_matrix = frobby._parse_4ti2_matrix(string) # optional - frobby - sage: reference_matrix = [[1, 2, 3], [0, 5, 0]] # optional - frobby - sage: parsed_matrix == reference_matrix # optional - frobby + sage: # optional - frobby + sage: string = '2 3\n1 2 3\n 0 5 0' + sage: parsed_matrix = frobby._parse_4ti2_matrix(string) + sage: reference_matrix = [[1, 2, 3], [0, 5, 0]] + sage: parsed_matrix == reference_matrix True A number of syntax errors lead to exceptions. :: @@ -414,10 +421,11 @@ def _ideal_to_string(self, monomial_ideal): EXAMPLES:: - sage: ring = QQ['x,y,z'] # optional - frobby - sage: (x, y, z) = ring.gens() # optional - frobby - sage: id = ring.ideal(x ** 2, x * y * z) # optional - frobby - sage: frobby._ideal_to_string(id) == "2 3\n2 0 0\n1 1 1\n" # optional - frobby + sage: # optional - frobby + sage: ring = QQ['x,y,z'] + sage: (x, y, z) = ring.gens() + sage: id = ring.ideal(x ** 2, x * y * z) + sage: frobby._ideal_to_string(id) == "2 3\n2 0 0\n1 1 1\n" True """ # There is no exponent vector that represents zero as a generator, so @@ -447,10 +455,11 @@ def _monomial_to_string(self, monomial): EXAMPLES:: - sage: ring = QQ['x,y,z'] # optional - frobby - sage: (x, y, z) = ring.gens() # optional - frobby - sage: monomial = x * x * z # optional - frobby - sage: frobby._monomial_to_string(monomial) == '2 0 1\n' # optional - frobby + sage: # optional - frobby + sage: ring = QQ['x,y,z'] + sage: (x, y, z) = ring.gens() + sage: monomial = x * x * z + sage: frobby._monomial_to_string(monomial) == '2 0 1\n' True """ exponents = monomial.exponents() diff --git a/src/sage/interfaces/kash.py b/src/sage/interfaces/kash.py index ebfd9178c70..aecddae452b 100644 --- a/src/sage/interfaces/kash.py +++ b/src/sage/interfaces/kash.py @@ -89,11 +89,12 @@ :: - sage: a = kash(12345) # optional -- kash - sage: b = kash(25) # optional -- kash - sage: a/b # optional -- kash + sage: # optional - kash + sage: a = kash(12345) + sage: b = kash(25) + sage: a/b 2469/5 - sage: a**b # optional -- kash + sage: a**b 1937659030411463935651167391656422626577614411586152317674869233464019922771432158872187137603759765625 Variable assignment @@ -130,12 +131,13 @@ :: - sage: F = kash.Factorization(4352) # optional -- kash - sage: F[1] # optional -- kash + sage: # optional - kash + sage: F = kash.Factorization(4352) + sage: F[1] <2, 8> - sage: F[2] # optional -- kash + sage: F[2] <17, 1> - sage: F # optional -- kash + sage: F [ <2, 8>, <17, 1> ], extended by: ext1 := 1, ext2 := Unassign @@ -147,17 +149,18 @@ :: - sage: kash.GCD(15,25) # optional -- kash + sage: # optional - kash + sage: kash.GCD(15,25) 5 - sage: kash.LCM(15,25) # optional -- kash + sage: kash.LCM(15,25) 75 - sage: kash.Div(25,15) # optional -- kash + sage: kash.Div(25,15) 1 - sage: kash(17) % kash(5) # optional -- kash + sage: kash(17) % kash(5) 2 - sage: kash.IsPrime(10007) # optional -- kash + sage: kash.IsPrime(10007) TRUE - sage: kash.IsPrime(2005) # optional -- kash + sage: kash.IsPrime(2005) FALSE sage: kash.NextPrime(10007) # optional -- kash @@ -168,18 +171,19 @@ :: - sage: kash.Precision() # optional -- kash + sage: # optional - kash + sage: kash.Precision() 30 - sage: kash('R') # optional -- kash + sage: kash('R') Real field of precision 30 - sage: kash.Precision(40) # optional -- kash + sage: kash.Precision(40) 40 - sage: kash('R') # optional -- kash + sage: kash('R') Real field of precision 40 - sage: z = kash('1 + 2*I') # optional -- kash - sage: z # optional -- kash + sage: z = kash('1 + 2*I') + sage: z 1.000000000000000000000000000000000000000 + 2.000000000000000000000000000000000000000*I - sage: z*z # optional -- kash + sage: z*z -3.000000000000000000000000000000000000000 + 4.000000000000000000000000000000000000000*I sage: kash.Cos('1.24') # optional -- kash @@ -222,40 +226,42 @@ :: - sage: v = kash([1,2,3]); v # optional -- kash + sage: # optional - kash + sage: v = kash([1,2,3]); v [ 1, 2, 3 ] - sage: v[1] # optional -- kash + sage: v[1] 1 - sage: v[3] # optional -- kash + sage: v[3] 3 - sage: v.Append([5]) # optional -- kash + sage: v.Append([5]) [ 1, 2, 3, 5 ] - sage: v # optional -- kash + sage: v [ 1, 2, 3 ] - sage: v.Append_([5, 6]) # optional -- kash + sage: v.Append_([5, 6]) SUCCESS - sage: v # optional -- kash + sage: v [ 1, 2, 3, 5, 6 ] - sage: v.Add(5) # optional -- kash + sage: v.Add(5) [ 1, 2, 3, 5, 6, 5 ] - sage: v # optional -- kash + sage: v [ 1, 2, 3, 5, 6 ] - sage: v.Add_(5) # optional -- kash + sage: v.Add_(5) SUCCESS - sage: v # optional -- kash + sage: v [ 1, 2, 3, 5, 6, 5 ] The ``Apply`` command applies a function to each element of a list:: - sage: L = kash([1,2,3,4]) # optional -- kash - sage: L.Apply('i -> 3*i') # optional -- kash + sage: # optional - kash + sage: L = kash([1,2,3,4]) + sage: L.Apply('i -> 3*i') [ 3, 6, 9, 12 ] - sage: L # optional -- kash + sage: L [ 1, 2, 3, 4 ] - sage: L.Apply('IsEven') # optional -- kash + sage: L.Apply('IsEven') [ FALSE, TRUE, FALSE, TRUE ] - sage: L # optional -- kash + sage: L [ 1, 2, 3, 4 ] Ranges @@ -265,11 +271,12 @@ :: - sage: L = kash('[1..10]') # optional -- kash - sage: L # optional -- kash + sage: # optional - kash + sage: L = kash('[1..10]') + sage: L [ 1 .. 10 ] - sage: L = kash('[2,4..100]') # optional -- kash - sage: L # optional -- kash + sage: L = kash('[2,4..100]') + sage: L [ 2, 4 .. 100 ] Sequences @@ -283,15 +290,16 @@ :: - sage: f = kash('X^3 + X + 1') # optional -- kash - sage: f + f # optional -- kash + sage: # optional - kash + sage: f = kash('X^3 + X + 1') + sage: f + f 2*X^3 + 2*X + 2 - sage: f * f # optional -- kash + sage: f * f X^6 + 2*X^4 + 2*X^3 + X^2 + 2*X + 1 - sage: f.Evaluate(10) # optional -- kash + sage: f.Evaluate(10) 1011 - sage: Qx = kash.PolynomialAlgebra('Q') # optional -- kash - sage: Qx.gen(1)**5 + kash('7/3') # sage1 below somewhat random; optional -- kash + sage: Qx = kash.PolynomialAlgebra('Q') + sage: Qx.gen(1)**5 + kash('7/3') sage1.1^5 + 7/3 Number Fields @@ -308,12 +316,13 @@ :: - sage: f = kash('X^5 + 4*X^4 - 56*X^2 -16*X + 192') # optional -- kash - sage: O = f.EquationOrder() # optional -- kash - sage: a = O.gen(2) # optional -- kash - sage: a # optional -- kash + sage: # optional - kash + sage: f = kash('X^5 + 4*X^4 - 56*X^2 -16*X + 192') + sage: O = f.EquationOrder() + sage: a = O.gen(2) + sage: a [0, 1, 0, 0, 0] - sage: O.Basis() # output somewhat random; optional -- kash + sage: O.Basis() [ _NG.1, _NG.2, @@ -321,9 +330,9 @@ _NG.4, _NG.5 ] - sage: O.Discriminant() # optional -- kash + sage: O.Discriminant() 1364202618880 - sage: O.MaximalOrder() # name sage2 below somewhat random; optional -- kash + sage: O.MaximalOrder() Maximal Order of sage2 sage: O = kash.MaximalOrder('X^3 - 77') # optional -- kash @@ -353,10 +362,11 @@ Computation of class groups and unit groups:: - sage: f = kash('X^5 + 4*X^4 - 56*X^2 -16*X + 192') # optional -- kash - sage: O = kash.EquationOrder(f) # optional -- kash - sage: OK = O.MaximalOrder() # optional -- kash - sage: OK.ClassGroup() # name sage32 below random; optional -- kash + sage: # optional - kash + sage: f = kash('X^5 + 4*X^4 - 56*X^2 -16*X + 192') + sage: O = kash.EquationOrder(f) + sage: OK = O.MaximalOrder() + sage: OK.ClassGroup() Abelian Group isomorphic to Z/6 Defined on 1 generator Relations: @@ -381,12 +391,13 @@ :: - sage: k = kash.FiniteField(25) # optional -- kash - sage: kT = k.RationalFunctionField() # optional -- kash - sage: kTy = kT.PolynomialAlgebra() # optional -- kash - sage: T = kT.gen(1) # optional -- kash - sage: y = kTy.gen(1) # optional -- kash - sage: f = y**3 + T**4 + 1 # optional -- kash + sage: # optional - kash + sage: k = kash.FiniteField(25) + sage: kT = k.RationalFunctionField() + sage: kTy = kT.PolynomialAlgebra() + sage: T = kT.gen(1) + sage: y = kTy.gen(1) + sage: f = y**3 + T**4 + 1 Long Input ---------- diff --git a/src/sage/interfaces/kenzo.py b/src/sage/interfaces/kenzo.py index 3607dd7879e..e403b04dab7 100644 --- a/src/sage/interfaces/kenzo.py +++ b/src/sage/interfaces/kenzo.py @@ -193,12 +193,13 @@ def EilenbergMacLaneSpace(G, n): EXAMPLES:: - sage: from sage.interfaces.kenzo import EilenbergMacLaneSpace # optional - kenzo - sage: e3 = EilenbergMacLaneSpace(ZZ, 3) # optional - kenzo - sage: [e3.homology(i) for i in range(8)] # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import EilenbergMacLaneSpace + sage: e3 = EilenbergMacLaneSpace(ZZ, 3) + sage: [e3.homology(i) for i in range(8)] [Z, 0, 0, Z, 0, C2, 0, C3] - sage: f3 = EilenbergMacLaneSpace(AdditiveAbelianGroup([2]), 3) # optional - kenzo - sage: [f3.homology(i) for i in range(8)] # optional - kenzo + sage: f3 = EilenbergMacLaneSpace(AdditiveAbelianGroup([2]), 3) + sage: [f3.homology(i) for i in range(8)] [Z, 0, 0, C2, 0, C2, C2, C2] """ if G == ZZ: @@ -230,15 +231,16 @@ def __init__(self, kenzo_object): TESTS:: - sage: from sage.interfaces.kenzo import KenzoObject # optional -kenzo - sage: from sage.interfaces.kenzo import __sphere__ # optional -kenzo - sage: ks = __sphere__(2) # optional -kenzo - sage: ks # optional -kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import KenzoObject + sage: from sage.interfaces.kenzo import __sphere__ + sage: ks = __sphere__(2) + sage: ks - sage: s2 = KenzoObject(ks) # optional -kenzo - sage: s2 # optional -kenzo + sage: s2 = KenzoObject(ks) + sage: s2 [K1 Simplicial-Set] - sage: TestSuite(s2).run(skip='_test_pickling') # optional -kenzo + sage: TestSuite(s2).run(skip='_test_pickling') """ self._kenzo = kenzo_object @@ -280,12 +282,13 @@ def group(self, p, i, j): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: S2 = Sphere(2) # optional - kenzo - sage: EMS = S2.em_spectral_sequence() # optional - kenzo - sage: EMS.group(0, -1, 2) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: S2 = Sphere(2) + sage: EMS = S2.em_spectral_sequence() + sage: EMS.group(0, -1, 2) Additive abelian group isomorphic to Z - sage: EMS.group(0, -1, 3) # optional - kenzo + sage: EMS.group(0, -1, 3) Trivial group """ invs = __spectral_sequence_group__(self._kenzo, p, i, j).python() @@ -308,16 +311,17 @@ def matrix(self, p, i, j): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: S3 = Sphere(3) # optional - kenzo - sage: L = S3.loop_space() # optional - kenzo - sage: EMS = L.em_spectral_sequence() # optional - kenzo - sage: EMS.table(1, -5, -2, 5, 8) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: S3 = Sphere(3) + sage: L = S3.loop_space() + sage: EMS = L.em_spectral_sequence() + sage: EMS.table(1, -5, -2, 5, 8) 0 Z Z + Z + Z Z + Z + Z 0 0 0 0 0 0 Z Z + Z 0 0 0 0 - sage: EMS.matrix(1, -2 ,8) # optional - kenzo + sage: EMS.matrix(1, -2 ,8) [ 3 -2 0] [ 3 0 -3] [ 0 2 -3] @@ -344,18 +348,19 @@ def differential(self, p, i, j): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: S3 = Sphere(3) # optional - kenzo - sage: L = S3.loop_space() # optional - kenzo - sage: EMS = L.em_spectral_sequence() # optional - kenzo - sage: EMS.table(1,-5,-2,5,8) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: S3 = Sphere(3) + sage: L = S3.loop_space() + sage: EMS = L.em_spectral_sequence() + sage: EMS.table(1,-5,-2,5,8) 0 Z Z + Z + Z Z + Z + Z 0 0 0 0 0 0 Z Z + Z 0 0 0 0 - sage: EMS.matrix(1, -3, 8) # optional - kenzo + sage: EMS.matrix(1, -3, 8) [ 2 -2 2] - sage: EMS.differential(1, -3, 8) # optional - kenzo + sage: EMS.differential(1, -3, 8) Morphism from module over Integer Ring with invariants (0, 0, 0) to module with invariants (0,) that sends the generators to [(2), (-2), (2)] """ domain = self.group(p, i, j) @@ -458,13 +463,14 @@ def tensor_product(self, other): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: p = s2.tensor_product(s3) # optional - kenzo - sage: type(p) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: p = s2.tensor_product(s3) + sage: type(p) - sage: [p.homology(i) for i in range(8)] # optional - kenzo + sage: [p.homology(i) for i in range(8)] [Z, 0, Z, Z, 0, Z, 0, 0] """ return KenzoChainComplex(__tnsr_prdc__(self._kenzo, other._kenzo)) @@ -514,11 +520,12 @@ def identity_morphism(self): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: tp = s2.tensor_product(s2) # optional - kenzo - sage: idnt = tp.identity_morphism() # optional - kenzo - sage: type(idnt) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: tp = s2.tensor_product(s2) + sage: idnt = tp.identity_morphism() + sage: type(idnt) """ return KenzoChainComplexMorphism(__idnt_mrph__(self._kenzo)) @@ -542,20 +549,21 @@ def null_morphism(self, target=None, degree=None): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: tp22 = s2.tensor_product(s2) # optional - kenzo - sage: tp22 # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: tp22 = s2.tensor_product(s2) + sage: tp22 [K... Chain-Complex] - sage: tp23 = s2.tensor_product(s3) # optional - kenzo - sage: tp23 # optional - kenzo + sage: tp23 = s2.tensor_product(s3) + sage: tp23 [K... Chain-Complex] - sage: null1 = tp22.null_morphism() # optional - kenzo - sage: null1 # optional - kenzo + sage: null1 = tp22.null_morphism() + sage: null1 [K... Morphism (degree 0): K... -> K...] - sage: null2 = tp22.null_morphism(target = tp23, degree = -3) # optional - kenzo - sage: null2 # optional - kenzo + sage: null2 = tp22.null_morphism(target = tp23, degree = -3) + sage: null2 [K... Morphism (degree -3): K... -> K...] """ if target is None: @@ -634,13 +642,14 @@ def orgn(self): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: l2 = s2.loop_space() # optional - kenzo - sage: l2.orgn() # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: l2 = s2.loop_space() + sage: l2.orgn() '(LOOP-SPACE [K... Simplicial-Set])' - sage: A = l2.cartesian_product(s2) # optional - kenzo - sage: A.orgn() # optional - kenzo + sage: A = l2.cartesian_product(s2) + sage: A.orgn() '(CRTS-PRDC [K... Simplicial-Group] [K... Simplicial-Set])' """ return str(__orgn_aux1__(self._kenzo)) @@ -669,13 +678,14 @@ def loop_space(self, n=1): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: l2 = s2.loop_space() # optional - kenzo - sage: type(l2) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: l2 = s2.loop_space() + sage: type(l2) - sage: l2 = s2.loop_space() # optional - kenzo - sage: [l2.homology(i) for i in range(8)] # optional - kenzo + sage: l2 = s2.loop_space() + sage: [l2.homology(i) for i in range(8)] [Z, Z, Z, Z, Z, Z, Z, Z] """ return KenzoSimplicialGroup(__loop_space__(self._kenzo, n)) @@ -694,13 +704,14 @@ def cartesian_product(self, other): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: p = s2.cartesian_product(s3) # optional - kenzo - sage: type(p) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: p = s2.cartesian_product(s3) + sage: type(p) - sage: [p.homology(i) for i in range(6)] # optional - kenzo + sage: [p.homology(i) for i in range(6)] [Z, 0, Z, Z, 0, Z] """ prod_kenzo = __crts_prdc__(self._kenzo, other._kenzo) @@ -716,12 +727,13 @@ def suspension(self): EXAMPLES:: - sage: from sage.interfaces.kenzo import EilenbergMacLaneSpace # optional - kenzo - sage: e3 = EilenbergMacLaneSpace(ZZ, 3) # optional - kenzo - sage: s = e3.suspension() # optional - kenzo - sage: type(s) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import EilenbergMacLaneSpace + sage: e3 = EilenbergMacLaneSpace(ZZ, 3) + sage: s = e3.suspension() + sage: type(s) - sage: [s.homology(i) for i in range(6)] # optional - kenzo + sage: [s.homology(i) for i in range(6)] [Z, 0, 0, 0, Z, 0] """ return KenzoSimplicialSet(__suspension__(self._kenzo)) @@ -799,11 +811,12 @@ def sw_spectral_sequence(self): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: S3 = Sphere(3) # optional - kenzo - sage: E = S3.sw_spectral_sequence() # optional - kenzo - sage: T = E.table(0, 0, 4, 0, 4) # optional - kenzo - sage: T # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: S3 = Sphere(3) + sage: E = S3.sw_spectral_sequence() + sage: T = E.table(0, 0, 4, 0, 4) + sage: T Z 0 0 Z 0 0 0 0 0 0 Z 0 0 Z 0 @@ -827,12 +840,13 @@ def serre_spectral_sequence(self): EXAMPLES:: + sage: # optional - kenzo sage: from sage.interfaces.kenzo import Sphere - sage: S2 = Sphere(2) # optional - kenzo - sage: S3 = Sphere(3) # optional - kenzo - sage: P = S2.cartesian_product(S3) # optional - kenzo - sage: E = P.serre_spectral_sequence() # optional - kenzo - sage: E.table(0, 0, 2, 0, 3) # optional - kenzo + sage: S2 = Sphere(2) + sage: S3 = Sphere(3) + sage: P = S2.cartesian_product(S3) + sage: E = P.serre_spectral_sequence() + sage: E.table(0, 0, 2, 0, 3) Z 0 Z 0 0 0 0 0 0 @@ -862,13 +876,14 @@ def wedge(self, other): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: w = s2.wedge(s3) # optional - kenzo - sage: type(w) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: w = s2.wedge(s3) + sage: type(w) - sage: [w.homology(i) for i in range(6)] # optional - kenzo + sage: [w.homology(i) for i in range(6)] [Z, 0, Z, Z, 0, 0] """ wedge_kenzo = __wedge__(self._kenzo, other._kenzo) @@ -888,13 +903,14 @@ def join(self, other): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: j = s2.join(s3) # optional - kenzo - sage: type(j) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: j = s2.join(s3) + sage: type(j) - sage: [j.homology(i) for i in range(6)] # optional - kenzo + sage: [j.homology(i) for i in range(6)] [Z, 0, 0, 0, 0, 0] """ join_kenzo = __join__(self._kenzo, other._kenzo) @@ -914,13 +930,14 @@ def smash_product(self, other): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: s = s2.smash_product(s3) # optional - kenzo - sage: type(s) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: s = s2.smash_product(s3) + sage: type(s) - sage: [s.homology(i) for i in range(6)] # optional - kenzo + sage: [s.homology(i) for i in range(6)] [Z, 0, 0, 0, 0, Z] """ smash_kenzo = __smash_product__(self._kenzo, other._kenzo) @@ -942,13 +959,14 @@ def classifying_space(self): EXAMPLES:: - sage: from sage.interfaces.kenzo import MooreSpace # optional - kenzo - sage: m2 = MooreSpace(2,4) # optional - kenzo - sage: l2 = m2.loop_space() # optional - kenzo - sage: c = l2.classifying_space() # optional - kenzo - sage: type(c) # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import MooreSpace + sage: m2 = MooreSpace(2,4) + sage: l2 = m2.loop_space() + sage: c = l2.classifying_space() + sage: type(c) - sage: [c.homology(i) for i in range(8)] # optional - kenzo + sage: [c.homology(i) for i in range(8)] [Z, 0, 0, 0, C2, 0, 0, 0] """ return KenzoSimplicialGroup(__classifying_space__(self._kenzo)) @@ -1118,14 +1136,15 @@ def SChainComplex(kchaincomplex, start=0, end=15): :: - sage: from sage.interfaces.kenzo import SChainComplex, Sphere # optional - kenzo - sage: S4 = Sphere(4) # optional - kenzo - sage: C = SChainComplex(S4) # optional - kenzo - sage: C # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import SChainComplex, Sphere + sage: S4 = Sphere(4) + sage: C = SChainComplex(S4) + sage: C Chain complex with at most 3 nonzero terms over Integer Ring - sage: C._ascii_art_() # optional - kenzo + sage: C._ascii_art_() 0 <-- C_4 <-- 0 ... 0 <-- C_0 <-- 0 - sage: [C.homology(i) for i in range(6)] # optional - kenzo + sage: [C.homology(i) for i in range(6)] [Z, 0, 0, 0, Z, 0] """ matrices = {} @@ -1156,17 +1175,18 @@ def SAbstractSimplex(simplex, dim): EXAMPLES:: + sage: # optional - kenzo sage: from sage.libs.ecl import EclObject, ecl_eval - sage: from sage.interfaces.kenzo import ( # optional - kenzo + sage: from sage.interfaces.kenzo import ( ....: KenzoObject, SAbstractSimplex) - sage: KAbSm = KenzoObject(ecl_eval("(ABSM 15 'K)")) # optional - kenzo - sage: SAbSm1 = SAbstractSimplex(KAbSm, 2) # optional - kenzo - sage: SAbSm2 = SAbstractSimplex(KAbSm, 7) # optional - kenzo - sage: SAbSm1.degeneracies() # optional - kenzo + sage: KAbSm = KenzoObject(ecl_eval("(ABSM 15 'K)")) + sage: SAbSm1 = SAbstractSimplex(KAbSm, 2) + sage: SAbSm2 = SAbstractSimplex(KAbSm, 7) + sage: SAbSm1.degeneracies() [3, 2, 1, 0] - sage: SAbSm1.dimension() # optional - kenzo + sage: SAbSm1.dimension() 6 - sage: SAbSm2.dimension() # optional - kenzo + sage: SAbSm2.dimension() 11 """ degeneracies = __dgop_int_ext__(__dgop__(simplex._kenzo)).python() @@ -1192,15 +1212,16 @@ def KAbstractSimplex(simplex): EXAMPLES:: + sage: # optional - kenzo sage: from sage.topology.simplicial_set import AbstractSimplex - sage: from sage.interfaces.kenzo import ( # optional - kenzo + sage: from sage.interfaces.kenzo import ( ....: KAbstractSimplex, SAbstractSimplex) - sage: SAbSm = AbstractSimplex(1, (2,0,3,2,1), name = 'SAbSm') # optional - kenzo - sage: KAbSm = KAbstractSimplex(SAbSm) # optional - kenzo - sage: SAbSm2 = SAbstractSimplex(KAbSm, 1) # optional - kenzo - sage: SAbSm.degeneracies() == SAbSm2.degeneracies() # optional - kenzo + sage: SAbSm = AbstractSimplex(1, (2,0,3,2,1), name = 'SAbSm') + sage: KAbSm = KAbstractSimplex(SAbSm) + sage: SAbSm2 = SAbstractSimplex(KAbSm, 1) + sage: SAbSm.degeneracies() == SAbSm2.degeneracies() True - sage: SAbSm.dimension() == SAbSm2.dimension() # optional - kenzo + sage: SAbSm.dimension() == SAbSm2.dimension() True """ return KenzoObject(__kabstractsimplex_aux1__(simplex.degeneracies(), @@ -1289,30 +1310,31 @@ def SFiniteSimplicialSet(ksimpset, limit): EXAMPLES:: + sage: # optional - kenzo sage: from sage.topology.simplicial_set import SimplicialSet - sage: from sage.interfaces.kenzo import ( # optional - kenzo + sage: from sage.interfaces.kenzo import ( ....: AbstractSimplex, KFiniteSimplicialSet, ....: SFiniteSimplicialSet, Sphere) - sage: s0 = AbstractSimplex(0, name='s0') # optional - kenzo - sage: s1 = AbstractSimplex(0, name='s1') # optional - kenzo - sage: s2 = AbstractSimplex(0, name='s2') # optional - kenzo - sage: s01 = AbstractSimplex(1, name='s01') # optional - kenzo - sage: s02 = AbstractSimplex(1, name='s02') # optional - kenzo - sage: s12 = AbstractSimplex(1, name='s12') # optional - kenzo - sage: s012 = AbstractSimplex(2, name='s012') # optional - kenzo - sage: Triangle = SimplicialSet({s01: (s1, s0), # optional - kenzo + sage: s0 = AbstractSimplex(0, name='s0') + sage: s1 = AbstractSimplex(0, name='s1') + sage: s2 = AbstractSimplex(0, name='s2') + sage: s01 = AbstractSimplex(1, name='s01') + sage: s02 = AbstractSimplex(1, name='s02') + sage: s12 = AbstractSimplex(1, name='s12') + sage: s012 = AbstractSimplex(2, name='s012') + sage: Triangle = SimplicialSet({s01: (s1, s0), ....: s02: (s2, s0), ....: s12: (s2, s1)}, ....: base_point = s0) - sage: KTriangle = KFiniteSimplicialSet(Triangle) # optional - kenzo - sage: STriangle = SFiniteSimplicialSet(KTriangle, 1) # optional - kenzo - sage: STriangle.homology() # optional - kenzo + sage: KTriangle = KFiniteSimplicialSet(Triangle) + sage: STriangle = SFiniteSimplicialSet(KTriangle, 1) + sage: STriangle.homology() {0: 0, 1: Z} - sage: S1 = simplicial_sets.Sphere(1) # optional - kenzo - sage: S3 = simplicial_sets.Sphere(3) # optional - kenzo - sage: KS1vS3 = KFiniteSimplicialSet(S1.wedge(S3)) # optional - kenzo - sage: SS1vS3 = SFiniteSimplicialSet(KS1vS3, 3) # optional - kenzo - sage: SS1vS3.homology() # optional - kenzo + sage: S1 = simplicial_sets.Sphere(1) + sage: S3 = simplicial_sets.Sphere(3) + sage: KS1vS3 = KFiniteSimplicialSet(S1.wedge(S3)) + sage: SS1vS3 = SFiniteSimplicialSet(KS1vS3, 3) + sage: SS1vS3.homology() {0: 0, 1: Z, 2: 0, 3: Z} """ list_orgn = __orgn_aux1__(ksimpset._kenzo).python() @@ -1587,18 +1609,19 @@ def composite(self, object=None): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere # optional - kenzo - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: tp22 = s2.tensor_product(s2) # optional - kenzo - sage: tp23 = s2.tensor_product(s3) # optional - kenzo - sage: idnt = tp22.identity_morphism() # optional - kenzo - sage: idnt # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: tp22 = s2.tensor_product(s2) + sage: tp23 = s2.tensor_product(s3) + sage: idnt = tp22.identity_morphism() + sage: idnt [K... Morphism (degree 0): K... -> K...] - sage: null = tp23.null_morphism(target = tp22, degree = 4) # optional - kenzo - sage: null # optional - kenzo + sage: null = tp23.null_morphism(target = tp22, degree = 4) + sage: null [K... Morphism (degree 4): K... -> K...] - sage: idnt.composite((tp22, null)) # optional - kenzo + sage: idnt.composite((tp22, null)) [K... Morphism (degree 3): K... -> K...] """ if object is None: @@ -1765,25 +1788,26 @@ def change_source_target_complex(self, source=None, target=None): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere, KenzoChainComplex # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere, KenzoChainComplex sage: from sage.libs.ecl import ecl_eval - sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) # optional - kenzo - sage: ZCC # optional - kenzo + sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) + sage: ZCC [K... Chain-Complex] - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: tp = s2.tensor_product(s3) # optional - kenzo - sage: tp # optional - kenzo + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: tp = s2.tensor_product(s3) + sage: tp [K... Filtered-Chain-Complex] - sage: null = ZCC.null_morphism(tp) # optional - kenzo - sage: null # optional - kenzo + sage: null = ZCC.null_morphism(tp) + sage: null [K... Morphism (degree 0): K... -> K...] - sage: null.source_complex() # optional - kenzo + sage: null.source_complex() [K... Chain-Complex] - sage: null2 = null.change_source_target_complex(source = tp) # optional - kenzo - sage: null2 # optional - kenzo + sage: null2 = null.change_source_target_complex(source = tp) + sage: null2 [K... Morphism (degree 0): K... -> K...] - sage: null2.source_complex() # optional - kenzo + sage: null2.source_complex() [K... Filtered-Chain-Complex] """ source = source or self.source_complex() @@ -1810,24 +1834,25 @@ def destructive_change_source_target_complex(self, source=None, target=None): EXAMPLES:: - sage: from sage.interfaces.kenzo import Sphere, KenzoChainComplex # optional - kenzo + sage: # optional - kenzo + sage: from sage.interfaces.kenzo import Sphere, KenzoChainComplex sage: from sage.libs.ecl import ecl_eval - sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) # optional - kenzo - sage: ZCC # optional - kenzo + sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) + sage: ZCC [K... Chain-Complex] - sage: s2 = Sphere(2) # optional - kenzo - sage: s3 = Sphere(3) # optional - kenzo - sage: tp = s2.tensor_product(s3) # optional - kenzo - sage: tp # optional - kenzo + sage: s2 = Sphere(2) + sage: s3 = Sphere(3) + sage: tp = s2.tensor_product(s3) + sage: tp [K... Filtered-Chain-Complex] - sage: null = ZCC.null_morphism(tp) # optional - kenzo - sage: null # optional - kenzo + sage: null = ZCC.null_morphism(tp) + sage: null [K... Morphism (degree 0): K... -> K...] - sage: null.target_complex() # optional - kenzo + sage: null.target_complex() [K... Filtered-Chain-Complex] - sage: null.destructive_change_source_target_complex(target = ZCC) # optional - kenzo + sage: null.destructive_change_source_target_complex(target = ZCC) [K... Cohomology-Class on K... of degree 0] - sage: null.target_complex() # optional - kenzo + sage: null.target_complex() [K... Chain-Complex] """ source = source or self.source_complex() @@ -1864,19 +1889,20 @@ def build_morphism(source_complex, target_complex, degree, algorithm, strategy, EXAMPLES:: + sage: # optional - kenzo sage: from sage.interfaces.kenzo import (KenzoChainComplex, ....: build_morphism) sage: from sage.libs.ecl import ecl_eval - sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) # optional - kenzo - sage: A = build_morphism( # optional - kenzo + sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)")) + sage: A = build_morphism( ....: ZCC, ZCC, -1, ....: ecl_eval("#'(lambda (comb) (cmbn (1- (degr comb))))"), ....: "cmbn", ["zero morphism on ZCC"]) - sage: A.target_complex() # optional - kenzo + sage: A.target_complex() [K... Chain-Complex] - sage: A.degree() # optional - kenzo + sage: A.degree() -1 - sage: type(A) # optional - kenzo + sage: type(A) """ return KenzoChainComplexMorphism( diff --git a/src/sage/interfaces/lie.py b/src/sage/interfaces/lie.py index 84aee7d7259..2866dfbb828 100644 --- a/src/sage/interfaces/lie.py +++ b/src/sage/interfaces/lie.py @@ -53,36 +53,38 @@ You can perform basic arithmetic operations in LiE. :: - sage: lie.eval('19+68') # optional - lie + sage: # optional - lie + sage: lie.eval('19+68') '87' - sage: a = lie('1111111111*1111111111') # optional - lie - sage: a # optional - lie + sage: a = lie('1111111111*1111111111') + sage: a 1234567900987654321 - sage: a/1111111111 # optional - lie + sage: a/1111111111 1111111111 - sage: a = lie('345') # optional - lie - sage: a^2+3*a-5 # optional - lie + sage: a = lie('345') + sage: a^2+3*a-5 120055 - sage: _ / 7*a # optional - lie + sage: _ / 7*a 5916750 Vectors in LiE are created using square brackets. Notice that the indexing in LiE is 1-based, unlike Python/Sage which is 0-based. :: - sage: v = lie('[3,2,6873,-38]') # optional - lie - sage: v # optional - lie + sage: # optional - lie + sage: v = lie('[3,2,6873,-38]') + sage: v [3,2,6873,-38] - sage: v[3] # optional - lie + sage: v[3] 6873 - sage: v+v # optional - lie + sage: v+v [6,4,13746,-76] - sage: v*v # optional - lie + sage: v*v 47239586 - sage: v+234786 # optional - lie + sage: v+234786 [3,2,6873,-38,234786] - sage: v-3 # optional - lie + sage: v-3 [3,2,-38] - sage: v^v # optional - lie + sage: v^v [3,2,6873,-38,3,2,6873,-38] You can also work with matrices in LiE. :: @@ -101,19 +103,20 @@ ,[3, 7, 0, 9] ] - sage: m^3 # optional - lie + sage: # optional - lie + sage: m^3 [[ 220, 87, 81, 375] ,[-168,-1089, 13,1013] ,[1550, 357,-55,1593] ,[-854, -652, 98,-170] ] - sage: v*m # optional - lie + sage: v*m [-6960,62055,55061,-319] - sage: m*v # optional - lie + sage: m*v [20508,-27714,54999,-14089] - sage: v*m*v # optional - lie + sage: v*m*v 378549605 - sage: m+v # optional - lie + sage: m+v [[ 1, 0, 3, 3] ,[12, 4, -4, 7] ,[-1, 9, 8, 0] @@ -130,17 +133,18 @@ LiE handles multivariate (Laurent) polynomials. :: - sage: lie('X[1,2]') # optional - lie + sage: # optional - lie + sage: lie('X[1,2]') 1X[1,2] - sage: -3*_ # optional - lie + sage: -3*_ -3X[1,2] - sage: _ + lie('4X[-1,4]') # optional - lie + sage: _ + lie('4X[-1,4]') 4X[-1,4] - 3X[ 1,2] - sage: _^2 # optional - lie + sage: _^2 16X[-2,8] - 24X[ 0,6] + 9X[ 2,4] - sage: lie('(4X[-1,4]-3X[1,2])*(X[2,0]-X[0,-4])') # optional - lie + sage: lie('(4X[-1,4]-3X[1,2])*(X[2,0]-X[0,-4])') -4X[-1, 0] + 3X[ 1,-2] + 4X[ 1, 4] - 3X[ 3, 2] - sage: _ - _ # optional - lie + sage: _ - _ 0X[0,0] @@ -172,15 +176,16 @@ a function (say f), you can call it using lie.f ; however, user-defined functions do not show up when using tab-completion. :: - sage: lie.eval('f(int x) = 2*x') # optional - lie + sage: # optional - lie + sage: lie.eval('f(int x) = 2*x') '' - sage: lie.f(984) # optional - lie + sage: lie.f(984) 1968 - sage: lie.eval('f(int n) = a=3*n-7; if a < 0 then a = -a fi; 7^a+a^3-4*a-57') # optional - lie + sage: lie.eval('f(int n) = a=3*n-7; if a < 0 then a = -a fi; 7^a+a^3-4*a-57') '' - sage: lie.f(2) # optional - lie + sage: lie.f(2) -53 - sage: lie.f(5) # optional - lie + sage: lie.f(5) 5765224 @@ -250,7 +255,8 @@ which evaluates a polynomial at a point. Below is a (roughly) direct translation of that program into Python / Sage. :: - sage: def eval_pol(p, pt): # optional - lie + sage: # optional - lie + sage: def eval_pol(p, pt): ....: s = 0 ....: for i in range(1,p.length().sage()+1): ....: m = 1 @@ -258,12 +264,12 @@ ....: m *= pt[j]^p.expon(i)[j] ....: s += p.coef(i)*m ....: return s - sage: a = lie('X[1,2]') # optional - lie - sage: b1 = lie('[1,2]') # optional - lie - sage: b2 = lie('[2,3]') # optional - lie - sage: eval_pol(a, b1) # optional - lie + sage: a = lie('X[1,2]') + sage: b1 = lie('[1,2]') + sage: b2 = lie('[2,3]') + sage: eval_pol(a, b1) 4 - sage: eval_pol(a, b2) # optional - lie + sage: eval_pol(a, b2) 18 diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index 4ed5ab46542..e8a4d94d2dc 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -496,7 +496,11 @@ def _contains(self, v1, v2): sage: 0 in a, 2 in a, 3 in a (True, True, False) sage: b = macaulay2('hashTable {"x" => 1, "y" => 2}') +<<<<<<< HEAD sage: 'x' in b, '"x"' in b # indirect doctest +======= + sage: 'x' in b, '"x"' in b +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) (False, True) """ return self.eval("%s#?%s" % (v2, v1)) == self._true_symbol() @@ -645,7 +649,11 @@ def cputime(self, t=None): sage: R = macaulay2("QQ[x,y]") sage: x,y = R.gens() sage: a = (x+y+1)^20 +<<<<<<< HEAD sage: macaulay2.cputime() # random +======= + sage: macaulay2.cputime() +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.48393700000000001 """ _t = float(self.cpuTime()._sage_()) @@ -958,7 +966,7 @@ def _repr_(self): Sequence sage: str(macaulay2('1..25')) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) - sage: macaulay2.options.after_print = False # optional - macaulay2 + sage: macaulay2.options.after_print = False """ from sage.typeset.ascii_art import empty_ascii_art P = self.parent() diff --git a/src/sage/interfaces/magma.py b/src/sage/interfaces/magma.py index 529bfbc349b..7d66375f25f 100644 --- a/src/sage/interfaces/magma.py +++ b/src/sage/interfaces/magma.py @@ -47,23 +47,25 @@ how many you get using the ``nvals`` named parameter to a function call:: - sage: n = magma(100) # optional - magma - sage: n.IsSquare(nvals = 1) # optional - magma + sage: # optional - magma + sage: n = magma(100) + sage: n.IsSquare(nvals = 1) true - sage: n.IsSquare(nvals = 2) # optional - magma + sage: n.IsSquare(nvals = 2) (true, 10) - sage: n = magma(-2006) # optional - magma - sage: n.Factorization() # optional - magma + sage: n = magma(-2006) + sage: n.Factorization() [ <2, 1>, <17, 1>, <59, 1> ] - sage: n.Factorization(nvals=2) # optional - magma + sage: n.Factorization(nvals=2) ([ <2, 1>, <17, 1>, <59, 1> ], -1) We verify that an obviously principal ideal is principal:: - sage: _ = magma.eval('R := PolynomialRing(RationalField())') # optional - magma - sage: O = magma.NumberField('x^2+23').MaximalOrder() # optional - magma - sage: I = magma('ideal<%s|%s.1>'%(O.name(),O.name())) # optional - magma - sage: I.IsPrincipal(nvals=2) # optional - magma + sage: # optional - magma + sage: _ = magma.eval('R := PolynomialRing(RationalField())') + sage: O = magma.NumberField('x^2+23').MaximalOrder() + sage: I = magma('ideal<%s|%s.1>'%(O.name(),O.name())) + sage: I.IsPrincipal(nvals=2) (true, [1, 0]) Long Input @@ -142,14 +144,15 @@ structure S is denoted by S(x). This also works for the Magma interface:: - sage: G = magma.DirichletGroup(20) # optional - magma - sage: G.AssignNames(['a', 'b']) # optional - magma - sage: (G.1).Modulus() # optional - magma + sage: # optional - magma + sage: G = magma.DirichletGroup(20) + sage: G.AssignNames(['a', 'b']) + sage: (G.1).Modulus() 20 - sage: e = magma.DirichletGroup(40)(G.1) # optional - magma - sage: print(e) # optional - magma + sage: e = magma.DirichletGroup(40)(G.1) + sage: print(e) Kronecker character -4 in modulus 40 - sage: print(e.Modulus()) # optional - magma + sage: print(e.Modulus()) 40 We coerce some polynomial rings into Magma:: @@ -713,13 +716,14 @@ def __call__(self, x, gens=None): EXAMPLES:: - sage: magma(EllipticCurve('37a')) # optional - magma + sage: # optional - magma + sage: magma(EllipticCurve('37a')) Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field - sage: magma('EllipticCurve([GF(5)|1,2,3,4,1])') # optional - magma + sage: magma('EllipticCurve([GF(5)|1,2,3,4,1])') Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 1 over GF(5) - sage: magma('PowerSeriesRing(Rationals())', 't') # optional - magma + sage: magma('PowerSeriesRing(Rationals())', 't') Power series ring in t over Rational Field - sage: magma('PolynomialRing(RationalField(), 3)', 'x,y,z') # optional - magma + sage: magma('PolynomialRing(RationalField(), 3)', 'x,y,z') Polynomial ring of rank 3 over Rational Field Order: Lexicographical Variables: x, y, z @@ -736,25 +740,27 @@ def __call__(self, x, gens=None): We test caching:: - sage: R. = ZZ[] # optional - magma - sage: magma(R) is magma(R) # optional - magma + sage: # optional - magma + sage: R. = ZZ[] + sage: magma(R) is magma(R) True - sage: m = Magma() # optional - magma - sage: m(R) # optional - magma + sage: m = Magma() + sage: m(R) Univariate Polynomial Ring in x over Integer Ring - sage: m(R) is magma(R) # optional - magma + sage: m(R) is magma(R) False - sage: R._magma_cache # optional - magma + sage: R._magma_cache {Magma: Univariate Polynomial Ring in x over Integer Ring, Magma: Univariate Polynomial Ring in x over Integer Ring} - sage: P. = PolynomialRing(GF(127)) # optional - magma - sage: m = Magma() # optional - magma - sage: m(P) # optional - magma + sage: # optional - magma + sage: P. = PolynomialRing(GF(127)) + sage: m = Magma() + sage: m(P) Polynomial ring of rank 2 over GF(127) Order: Graded Reverse Lexicographical Variables: x, y - sage: P._magma_cache # optional - magma + sage: P._magma_cache {Magma: Polynomial ring of rank 2 over GF(127) Order: Graded Reverse Lexicographical Variables: x, y} @@ -891,16 +897,17 @@ def clear(self, var): :: - sage: magma = Magma() # optional - magma - sage: a = magma('100') # optional - magma - sage: a.name() # optional - magma + sage: # optional - magma + sage: magma = Magma() + sage: a = magma('100') + sage: a.name() '_sage_[1]' - sage: del a # optional - magma - sage: b = magma('257') # optional - magma - sage: b.name() # optional - magma + sage: del a + sage: b = magma('257') + sage: b.name() '_sage_[1]' - sage: del b # optional - magma - sage: magma('_sage_[1]') # optional - magma + sage: del b + sage: magma('_sage_[1]') 0 """ self.__available_var.insert(0, var) # adds var to front of list @@ -931,12 +938,13 @@ def cputime(self, t=None): EXAMPLES:: - sage: type(magma.cputime()) # optional - magma + sage: # optional - magma + sage: type(magma.cputime()) <... 'float'> - sage: magma.cputime() # random, optional - magma + sage: magma.cputime() 1.9399999999999999 - sage: t = magma.cputime() # optional - magma - sage: magma.cputime(t) # random, optional - magma + sage: t = magma.cputime() + sage: magma.cputime(t) 0.02 """ if t: @@ -1251,15 +1259,16 @@ def bar_call(self, left, name, gens, nvals=1): methods of Magma elements. Here we illustrate directly using bar_call to create quotients:: - sage: V = magma.RModule(ZZ,3) # optional - magma - sage: V # optional - magma + sage: # optional - magma + sage: V = magma.RModule(ZZ,3) + sage: V RModule(IntegerRing(), 3) - sage: magma.bar_call(V, 'quo', [[1,2,3]], nvals=1) # optional - magma + sage: magma.bar_call(V, 'quo', [[1,2,3]], nvals=1) RModule(IntegerRing(), 2) - sage: magma.bar_call(V, 'quo', [[1,2,3]], nvals=2) # optional - magma + sage: magma.bar_call(V, 'quo', [[1,2,3]], nvals=2) (RModule(IntegerRing(), 2), Mapping from: RModule(IntegerRing(), 3) to RModule(IntegerRing(), 2)) - sage: magma.bar_call(V, 'quo', V, nvals=2) # optional - magma + sage: magma.bar_call(V, 'quo', V, nvals=2) (RModule(IntegerRing(), 0), Mapping from: RModule(IntegerRing(), 3) to RModule(IntegerRing(), 0)) """ @@ -1644,11 +1653,12 @@ def __call__(self, *args, **kwds): EXAMPLES: We create a MagmaFunctionElement:: - sage: n = magma(-15) # optional - magma - sage: f = n.Factorisation # optional - magma - sage: type(f) # optional - magma + sage: # optional - magma + sage: n = magma(-15) + sage: f = n.Factorisation + sage: type(f) - sage: f() # optional - magma + sage: f() [ <3, 1>, <5, 1> ] We verify that the nvals argument works. @@ -1686,12 +1696,13 @@ def _instancedoc_(self): EXAMPLES:: - sage: n = magma(-15) # optional - magma - sage: f = n.Factorisation # optional - magma - sage: print(f.__doc__) # optional - magma + sage: # optional - magma + sage: n = magma(-15) + sage: f = n.Factorisation + sage: print(f.__doc__) (n::RngIntElt) -> RngIntEltFact, RngIntElt, SeqEnum ... - sage: print(n.Factorisation.__doc__) # optional - magma + sage: print(n.Factorisation.__doc__) (n::RngIntElt) -> RngIntEltFact, RngIntElt, SeqEnum ... """ @@ -1728,13 +1739,14 @@ def _repr_(self): :: - sage: V = magma('VectorSpace(RationalField(),2)') # optional - magma - sage: V.set_magma_attribute('M', 290398) # optional - magma - sage: V.M # optional - magma + sage: # optional - magma + sage: V = magma('VectorSpace(RationalField(),2)') + sage: V.set_magma_attribute('M', 290398) + sage: V.M 290398 - sage: type(V.M) # optional - magma + sage: type(V.M) - sage: type(V.M.__repr__()) # optional - magma + sage: type(V.M.__repr__()) <... 'str'> Displaying a non-attribute function works as above. @@ -1898,13 +1910,14 @@ def __getattr__(self, attrname): EXAMPLES:: - sage: n = magma(-15) # optional - magma - sage: type(n) # optional - magma + sage: # optional - magma + sage: n = magma(-15) + sage: type(n) - sage: f = n.__getattr__('Factorization') # optional - magma - sage: type(f) # optional - magma + sage: f = n.__getattr__('Factorization') + sage: type(f) - sage: f # optional - magma + sage: f Partially evaluated Magma function or intrinsic 'Factorization' ... """ @@ -1921,24 +1934,25 @@ def _sage_(self): EXAMPLES: Enumerated Sets:: - sage: a = magma('{1,2/3,-5/9}') # optional - magma - sage: a.sage() # optional - magma + sage: # optional - magma + sage: a = magma('{1,2/3,-5/9}') + sage: a.sage() {1, -5/9, 2/3} - sage: a._sage_() # optional - magma + sage: a._sage_() {1, -5/9, 2/3} - sage: type(a.sage()) # optional - magma + sage: type(a.sage()) - sage: a = magma('{1,2/3,-5/9}'); a # optional - magma + sage: a = magma('{1,2/3,-5/9}'); a { -5/9, 2/3, 1 } - sage: a.Type() # optional - magma + sage: a.Type() SetEnum - sage: b = a.sage(); b # optional - magma + sage: b = a.sage(); b {1, -5/9, 2/3} - sage: type(b) # optional - magma + sage: type(b) - sage: c = magma(b); c # optional - magma + sage: c = magma(b); c { -5/9, 2/3, 1 } - sage: c.Type() # optional - magma + sage: c.Type() SetEnum Multisets are converted to lists:: @@ -1986,20 +2000,22 @@ def _sage_(self): Multivariate polynomials:: - sage: R. = QQ[] # optional - magma - sage: f = x^2+3*y # optional - magma - sage: g = magma(f).sage(); g # optional - magma + sage: # optional - magma + sage: R. = QQ[] + sage: f = x^2+3*y + sage: g = magma(f).sage(); g x^2 + 3*y - sage: parent(f) == parent(g) # optional - magma + sage: parent(f) == parent(g) True Real and complex numbers:: - sage: m = magma(RealField(200)(1/3)) # optional - magma - sage: m.sage() # indirect doctest, optional - magma + sage: # optional - magma + sage: m = magma(RealField(200)(1/3)) + sage: m.sage() 0.33333333333333333333333333333333333333333333333333333333333 - sage: m = magma(RealField(1000)(1/3)) # optional - magma - sage: m.sage() # indirect doctest, optional - magma + sage: m = magma(RealField(1000)(1/3)) + sage: m.sage() 0.333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 sage: m = magma(ComplexField(200)).1; m # optional - magma @@ -2041,14 +2057,15 @@ def _sage_(self): to relative number fields. Conversion of their elements has not yet been implemented.:: - sage: magma.eval('P := PolynomialRing(Rationals());') # optional - magma + sage: # optional - magma + sage: magma.eval('P := PolynomialRing(Rationals());') '' - sage: K = magma('NumberField([x^2-2,x^2-3]:Abs);') # optional - magma - sage: L = K.sage(); L # optional - magma + sage: K = magma('NumberField([x^2-2,x^2-3]:Abs);') + sage: L = K.sage(); L Number Field in K1 with defining polynomial x^2 - 2 over its base field - sage: L.base_field() # optional - magma + sage: L.base_field() Number Field in K2 with defining polynomial x^2 - 3 - sage: K.GeneratorsSequence()[1].sage() # optional - magma + sage: K.GeneratorsSequence()[1].sage() Traceback (most recent call last): ... NameError: name 'K' is not defined @@ -2083,11 +2100,12 @@ def AssignNames(self, names): """ EXAMPLES:: - sage: S = magma.PolynomialRing(magma.Integers(), 2) # optional - magma - sage: S.AssignNames(['a', 'b']) # optional - magma - sage: S.1 # optional - magma + sage: # optional - magma + sage: S = magma.PolynomialRing(magma.Integers(), 2) + sage: S.AssignNames(['a', 'b']) + sage: S.1 a - sage: S.1^2 + S.2 # optional - magma + sage: S.1^2 + S.2 a^2 + b """ P = self._check_valid() @@ -2214,13 +2232,14 @@ def evaluate(self, *args): EXAMPLES:: - sage: f = magma('Factorization') # optional - magma - sage: f.evaluate(15) # optional - magma + sage: # optional - magma + sage: f = magma('Factorization') + sage: f.evaluate(15) [ <3, 1>, <5, 1> ] - sage: f(15) # optional - magma + sage: f(15) [ <3, 1>, <5, 1> ] - sage: f = magma('GCD') # optional - magma - sage: f.evaluate(15,20) # optional - magma + sage: f = magma('GCD') + sage: f.evaluate(15,20) 5 sage: m = matrix(QQ, 2, 2, [2,3,5,7]) # optional - magma @@ -2242,13 +2261,14 @@ def __call__(self, *args): EXAMPLES:: - sage: M = magma.RMatrixSpace(magma.IntegerRing(), 2, 2) # optional - magma - sage: A = M([1,2,3,4]); A # optional - magma + sage: # optional - magma + sage: M = magma.RMatrixSpace(magma.IntegerRing(), 2, 2) + sage: A = M([1,2,3,4]); A [1 2] [3 4] - sage: type(A) # optional - magma + sage: type(A) - sage: A.Type() # optional - magma + sage: A.Type() ModMatRngElt """ if len(args) > 1: @@ -2274,16 +2294,17 @@ def __iter__(self): EXAMPLES:: - sage: V = magma('VectorSpace(GF(3),2)') # optional - magma - sage: V # optional - magma + sage: # optional - magma + sage: V = magma('VectorSpace(GF(3),2)') + sage: V Full Vector space of degree 2 over GF(3) - sage: w = V.__iter__(); w # optional - magma + sage: w = V.__iter__(); w - sage: next(w) # optional - magma + sage: next(w) (0 0) - sage: next(w) # optional - magma + sage: next(w) (1 0) - sage: list(w) # optional - magma + sage: list(w) [(2 0), (0 1), (1 1), (2 1), (0 2), (1 2), (2 2)] """ P = self._check_valid() @@ -2299,12 +2320,13 @@ def __len__(self): EXAMPLES:: - sage: V = magma('VectorSpace(GF(3),2)') # optional - magma - sage: V # optional - magma + sage: # optional - magma + sage: V = magma('VectorSpace(GF(3),2)') + sage: V Full Vector space of degree 2 over GF(3) - sage: len(V) # optional - magma + sage: len(V) 9 - sage: V.__len__() # optional - magma + sage: V.__len__() 9 """ P = self._check_valid() @@ -2431,11 +2453,12 @@ def _latex_(self): Power Series:: - sage: _=magma.eval('R := PowerSeriesRing(RationalField())') # optional - magma - sage: latex(magma('(1/(1+x))')) # optional - magma + sage: # optional - magma + sage: _=magma.eval('R := PowerSeriesRing(RationalField())') + sage: latex(magma('(1/(1+x))')) 1-x+x^{2}-x^{3}+x^{4}-x^{5}+x^{6}-x^{7}+x^{8}-x^{9}+x^{10}-x^{11}+x^{12}-x^{13}+x^{14}-x^{15}+x^{16}-x^{17}+x^{18}-x^{19}+O(x^{20}) - sage: _=magma.eval('R := PowerSeriesRing(RationalField())') # optional - magma - sage: latex(magma('(-1/(2+x + O(x^3)))')) # optional - magma + sage: _=magma.eval('R := PowerSeriesRing(RationalField())') + sage: latex(magma('(-1/(2+x + O(x^3)))')) \frac{-1}{2}+\frac{1}{4}x-\frac{1}{8}x^{2}+O(x^{3}) p-adic Numbers:: @@ -2457,11 +2480,12 @@ def set_magma_attribute(self, attrname, value): EXAMPLES:: - sage: V = magma("VectorSpace(RationalField(),2)") # optional - magma - sage: V.set_magma_attribute('M',10) # optional - magma - sage: V.get_magma_attribute('M') # optional - magma + sage: # optional - magma + sage: V = magma("VectorSpace(RationalField(),2)") + sage: V.set_magma_attribute('M',10) + sage: V.get_magma_attribute('M') 10 - sage: V.M # optional - magma + sage: V.M 10 """ P = self.parent() # instance of Magma that contains this element. @@ -2478,11 +2502,12 @@ def get_magma_attribute(self, attrname): EXAMPLES:: - sage: V = magma("VectorSpace(RationalField(),10)") # optional - magma - sage: V.set_magma_attribute('M','"hello"') # optional - magma - sage: V.get_magma_attribute('M') # optional - magma + sage: # optional - magma + sage: V = magma("VectorSpace(RationalField(),10)") + sage: V.set_magma_attribute('M','"hello"') + sage: V.get_magma_attribute('M') hello - sage: V.M # optional - magma + sage: V.M hello """ P = self.parent() @@ -2620,13 +2645,14 @@ def __bool__(self): Test use in bool conversions of bools:: - sage: bool(magma(False)) # optional - magma + sage: # optional - magma + sage: bool(magma(False)) False - sage: bool(magma(True)) # optional - magma + sage: bool(magma(True)) True - sage: bool(magma(1)) # optional - magma + sage: bool(magma(1)) True - sage: bool(magma(0)) # optional - magma + sage: bool(magma(0)) False TESTS: @@ -2713,12 +2739,13 @@ def quo(self, gens, **args): :: - sage: V = magma.RModule(ZZ,3); V # optional - magma + sage: # optional - magma + sage: V = magma.RModule(ZZ,3); V RModule(IntegerRing(), 3) - sage: W, phi = V.quo([[1,2,3]]) # optional - magma - sage: W # optional - magma + sage: W, phi = V.quo([[1,2,3]]) + sage: W RModule(IntegerRing(), 2) - sage: phi # optional - magma + sage: phi Mapping from: RModule(IntegerRing(), 3) to RModule(IntegerRing(), 2) """ return self.parent().bar_call(self, 'quo', gens, nvals=2) @@ -2741,10 +2768,11 @@ def ideal(self, gens): EXAMPLES:: - sage: R = magma('PolynomialRing(RationalField())') # optional - magma - sage: R.assign_names(['x']) # optional - magma - sage: x = R.1 # optional - magma - sage: R.ideal([x^2 - 1, x^3 - 1]) # optional - magma + sage: # optional - magma + sage: R = magma('PolynomialRing(RationalField())') + sage: R.assign_names(['x']) + sage: x = R.1 + sage: R.ideal([x^2 - 1, x^3 - 1]) Ideal of Univariate Polynomial Ring in x over Rational Field generated by x - 1 """ return self.parent().bar_call(self, 'ideal', gens, nvals=1) diff --git a/src/sage/interfaces/maple.py b/src/sage/interfaces/maple.py index 7ba21a66cf6..1f4f209f127 100644 --- a/src/sage/interfaces/maple.py +++ b/src/sage/interfaces/maple.py @@ -605,12 +605,20 @@ def cputime(self, t=None): sage: # optional - maple sage: t = maple.cputime() +<<<<<<< HEAD sage: t # random +======= + sage: t +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.02 sage: x = maple('x') sage: maple.diff(x^2, x) 2*x +<<<<<<< HEAD sage: maple.cputime(t) # random +======= + sage: maple.cputime(t) +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.0 """ if t is None: @@ -810,7 +818,11 @@ def with_package(self, package): :: sage: # optional - maple +<<<<<<< HEAD sage: maple.quit() # reset maple +======= + sage: maple.quit() +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) sage: maple('partition(10)') partition(10) sage: maple('bell(10)') @@ -947,7 +959,11 @@ def __hash__(self): sage: # optional - maple sage: m = maple('x^2+y^2') +<<<<<<< HEAD sage: m.__hash__() # random +======= + sage: m.__hash__() +>>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 188724254834261060184983038723355865733 sage: hash(m) # random 5035731711831192733 diff --git a/src/sage/interfaces/mathematica.py b/src/sage/interfaces/mathematica.py index 9c6e3ca86e9..9c64e9f4286 100644 --- a/src/sage/interfaces/mathematica.py +++ b/src/sage/interfaces/mathematica.py @@ -31,14 +31,15 @@ call the Mathematica wrapper object's ``sage()`` method. This method returns a native Sage object:: - sage: mobj = mathematica(x^2-1) # optional - mathematica - sage: mobj2 = mobj.Factor(); mobj2 # optional - mathematica + sage: # optional - mathematica + sage: mobj = mathematica(x^2-1) + sage: mobj2 = mobj.Factor(); mobj2 (-1 + x)*(1 + x) - sage: mobj2.parent() # optional - mathematica + sage: mobj2.parent() Mathematica - sage: sobj = mobj2.sage(); sobj # optional - mathematica + sage: sobj = mobj2.sage(); sobj (x + 1)*(x - 1) - sage: sobj.parent() # optional - mathematica + sage: sobj.parent() Symbolic Ring @@ -122,16 +123,17 @@ We solve an equation and a system of two equations:: - sage: eqn = mathematica('3x + 5 == 14') # optional - mathematica - sage: eqn # optional - mathematica + sage: # optional - mathematica + sage: eqn = mathematica('3x + 5 == 14') + sage: eqn 5 + 3*x == 14 - sage: eqn.Solve('x') # optional - mathematica + sage: eqn.Solve('x') {{x -> 3}} - sage: sys = mathematica('{x^2 - 3y == 3, 2x - y == 1}') # optional - mathematica - sage: print(sys) # optional - mathematica + sage: sys = mathematica('{x^2 - 3y == 3, 2x - y == 1}') + sage: print(sys) 2 {x - 3 y == 3, 2 x - y == 1} - sage: sys.Solve('{x, y}') # optional - mathematica + sage: sys.Solve('{x, y}') {{x -> 0, y -> -1}, {x -> 6, y -> 11}} Assignments and definitions @@ -227,15 +229,16 @@ We factor an integer:: - sage: n = mathematica(2434500) # optional - mathematica - sage: n.FactorInteger() # optional - mathematica + sage: # optional - mathematica + sage: n = mathematica(2434500) + sage: n.FactorInteger() {{2, 2}, {3, 2}, {5, 3}, {541, 1}} - sage: n = mathematica(2434500) # optional - mathematica - sage: F = n.FactorInteger(); F # optional - mathematica + sage: n = mathematica(2434500) + sage: F = n.FactorInteger(); F {{2, 2}, {3, 2}, {5, 3}, {541, 1}} - sage: F[1] # optional - mathematica + sage: F[1] {2, 2} - sage: F[4] # optional - mathematica + sage: F[4] {541, 1} Mathematica's ECM package is no longer available. @@ -261,17 +264,18 @@ :: - sage: x = mathematica(pi/2) # optional - mathematica - sage: print(x) # optional - mathematica + sage: # optional - mathematica + sage: x = mathematica(pi/2) + sage: print(x) Pi -- 2 - sage: loads(dumps(x)) == x # optional - mathematica + sage: loads(dumps(x)) == x True - sage: n = x.N(50) # optional - mathematica - sage: print(n) # optional - mathematica + sage: n = x.N(50) + sage: print(n) 1.5707963267948966192313216916397514420985846996876 - sage: loads(dumps(n)) == n # optional - mathematica + sage: loads(dumps(n)) == n True Complicated translations @@ -351,13 +355,14 @@ Check that numerical approximations via Mathematica's `N[]` function work correctly (:trac:`18888`, :trac:`28907`):: - sage: mathematica('Pi/2').N(10) # optional -- mathematica + sage: # optional - mathematica + sage: mathematica('Pi/2').N(10) 1.5707963268 - sage: mathematica('Pi').N(10) # optional -- mathematica + sage: mathematica('Pi').N(10) 3.1415926536 - sage: mathematica('Pi').N(50) # optional -- mathematica + sage: mathematica('Pi').N(50) 3.14159265358979323846264338327950288419716939937511 - sage: str(mathematica('Pi*x^2-1/2').N()) # optional -- mathematica + sage: str(mathematica('Pi*x^2-1/2').N()) 2 -0.5 + 3.14159 x @@ -373,13 +378,14 @@ Check that all trig/hyperbolic functions and their reciprocals are correctly translated to Mathematica (:trac:`34087`):: - sage: x=var('x') # optional - mathematica - sage: FL=[sin, cos, tan, csc, sec, cot, # optional - mathematica + sage: # optional - mathematica + sage: x=var('x') + sage: FL=[sin, cos, tan, csc, sec, cot, ....: sinh, cosh, tanh, csch, sech, coth] - sage: IFL=[arcsin, arccos, arctan, arccsc, # optional - mathematica + sage: IFL=[arcsin, arccos, arctan, arccsc, ....: arcsec, arccot, arcsinh, arccosh, ....: arctanh, arccsch, arcsech, arccoth] - sage: [mathematica.TrigToExp(u(x)).sage() # optional - mathematica + sage: [mathematica.TrigToExp(u(x)).sage() ....: for u in FL] [-1/2*I*e^(I*x) + 1/2*I*e^(-I*x), 1/2*e^(I*x) + 1/2*e^(-I*x), @@ -393,7 +399,7 @@ -2/(e^(-x) - e^x), 2/(e^(-x) + e^x), -(e^(-x) + e^x)/(e^(-x) - e^x)] - sage: [mathematica.TrigToExp(u(x)).sage() # optional - mathematica + sage: [mathematica.TrigToExp(u(x)).sage() ....: for u in IFL] [-I*log(I*x + sqrt(-x^2 + 1)), 1/2*pi + I*log(I*x + sqrt(-x^2 + 1)), @@ -789,12 +795,13 @@ def _sage_(self, locals={}): Mathematica lists of numbers/constants become Sage lists of numbers/constants:: - sage: m = mathematica('{{1., 4}, Pi, 3.2e100, I}') # optional - mathematica - sage: s = m.sage(); s # optional - mathematica + sage: # optional - mathematica + sage: m = mathematica('{{1., 4}, Pi, 3.2e100, I}') + sage: s = m.sage(); s [[1.00000000000000, 4], pi, 3.20000000000000*e100, I] - sage: s[1].n() # optional - mathematica + sage: s[1].n() 3.14159265358979 - sage: s[3]^2 # optional - mathematica + sage: s[3]^2 -1 :: @@ -825,11 +832,12 @@ def _sage_(self, locals={}): :: - sage: m = mathematica('bla^2') # optional - mathematica - sage: mb = m.sage() # optional - mathematica - sage: var('bla') # optional - mathematica + sage: # optional - mathematica + sage: m = mathematica('bla^2') + sage: mb = m.sage() + sage: var('bla') bla - sage: bla^2 - mb # optional - mathematica + sage: bla^2 - mb 0 diff --git a/src/sage/interfaces/mathics.py b/src/sage/interfaces/mathics.py index 0bf0bc78829..aec033d3173 100644 --- a/src/sage/interfaces/mathics.py +++ b/src/sage/interfaces/mathics.py @@ -47,14 +47,15 @@ call the Mathics wrapper object's ``sage()`` method. This method returns a native Sage object:: - sage: mobj = mathics(x^2-1) # optional - mathics - sage: mobj2 = mobj.Factor(); mobj2 # optional - mathics + sage: # optional - mathics + sage: mobj = mathics(x^2-1) + sage: mobj2 = mobj.Factor(); mobj2 (-1 + x) (1 + x) - sage: mobj2.parent() # optional - mathics + sage: mobj2.parent() Mathics - sage: sobj = mobj2.sage(); sobj # optional - mathics + sage: sobj = mobj2.sage(); sobj (x + 1)*(x - 1) - sage: sobj.parent() # optional - mathics + sage: sobj.parent() Symbolic Ring @@ -132,15 +133,16 @@ We solve an equation and a system of two equations:: - sage: eqn = mathics('3x + 5 == 14') # optional - mathics - sage: eqn # optional - mathics + sage: # optional - mathics + sage: eqn = mathics('3x + 5 == 14') + sage: eqn 5 + 3 x == 14 - sage: eqn.Solve('x') # optional - mathics + sage: eqn.Solve('x') {{x -> 3}} - sage: sys = mathics('{x^2 - 3y == 3, 2x - y == 1}') # optional - mathics - sage: print(sys) # optional - mathics + sage: sys = mathics('{x^2 - 3y == 3, 2x - y == 1}') + sage: print(sys) {x ^ 2 - 3 y == 3, 2 x - y == 1} - sage: sys.Solve('{x, y}') # optional - mathics + sage: sys.Solve('{x, y}') {{x -> 0, y -> -1}, {x -> 6, y -> 11}} Assignments and definitions @@ -233,15 +235,16 @@ We factor an integer:: - sage: n = mathics(2434500) # optional - mathics - sage: n.FactorInteger() # optional - mathics + sage: # optional - mathics + sage: n = mathics(2434500) + sage: n.FactorInteger() {{2, 2}, {3, 2}, {5, 3}, {541, 1}} - sage: n = mathics(2434500) # optional - mathics - sage: F = n.FactorInteger(); F # optional - mathics + sage: n = mathics(2434500) + sage: F = n.FactorInteger(); F {{2, 2}, {3, 2}, {5, 3}, {541, 1}} - sage: F[1] # optional - mathics + sage: F[1] {2, 2} - sage: F[4] # optional - mathics + sage: F[4] {541, 1} @@ -266,15 +269,16 @@ :: - sage: x = mathics(pi/2) # optional - mathics - sage: print(x) # optional - mathics + sage: # optional - mathics + sage: x = mathics(pi/2) + sage: print(x) Pi / 2 - sage: loads(dumps(x)) == x # optional - mathics + sage: loads(dumps(x)) == x True - sage: n = x.N(50) # optional - mathics - sage: print(n) # optional - mathics + sage: n = x.N(50) + sage: print(n) 1.5707963267948966192313216916397514420985846996876 - sage: loads(dumps(n)) == n # optional - mathics + sage: loads(dumps(n)) == n True Complicated translations @@ -356,13 +360,14 @@ Check that numerical approximations via Mathics's `N[]` function work correctly (:trac:`18888`, :trac:`28907`):: - sage: mathics('Pi/2').N(10) # optional -- mathics + sage: # optional - mathics + sage: mathics('Pi/2').N(10) 1.570796327 - sage: mathics('Pi').N(10) # optional -- mathics + sage: mathics('Pi').N(10) 3.141592654 - sage: mathics('Pi').N(50) # optional -- mathics + sage: mathics('Pi').N(50) 3.1415926535897932384626433832795028841971693993751 - sage: str(mathics('Pi*x^2-1/2').N()) # optional -- mathics + sage: str(mathics('Pi*x^2-1/2').N()) '-0.5 + 3.14159 x ^ 2.' Check that Mathics's `E` exponential symbol is correctly backtranslated @@ -405,15 +410,16 @@ def _mathics_sympysage_symbol(self): EXAMPLES:: + sage: # optional - mathics sage: from sage.interfaces.mathics import _mathics_sympysage_symbol - sage: mt = mathics('t') # optional - mathics - sage: st = mt.to_sympy(); st # optional - mathics + sage: mt = mathics('t') + sage: st = mt.to_sympy(); st _Mathics_User_Global`t - sage: _mathics_sympysage_symbol(st) # optional - mathics + sage: _mathics_sympysage_symbol(st) t - sage: bool(_ == st._sage_()) # optional - mathics + sage: bool(_ == st._sage_()) True - sage: type(st._sage_()) # optional - mathics + sage: type(st._sage_()) """ from sage.symbolic.ring import SR @@ -442,20 +448,21 @@ class Mathics(Interface): EXAMPLES:: - sage: t = mathics('Tan[I + 0.5]') # optional - mathics - sage: t.parent() # optional - mathics + sage: # optional - mathics + sage: t = mathics('Tan[I + 0.5]') + sage: t.parent() Mathics - sage: ts = t.sage() # optional - mathics - sage: ts.parent() # optional - mathics + sage: ts = t.sage() + sage: ts.parent() Complex Field with 53 bits of precision - sage: t == mathics(ts) # optional - mathics + sage: t == mathics(ts) True - sage: mtan = mathics.Tan # optional - mathics - sage: mt = mtan(I+1/2) # optional - mathics - sage: mt == t # optional - mathics + sage: mtan = mathics.Tan + sage: mt = mtan(I+1/2) + sage: mt == t True - sage: u = mathics(I+1/2) # optional - mathics - sage: u.Tan() == mt # optional - mathics + sage: u = mathics(I+1/2) + sage: u.Tan() == mt True @@ -829,34 +836,37 @@ class MathicsElement(ExtraTabCompletion, InterfaceElement): EXAMPLES:: - sage: me=mathics(e); me # optional - mathics + sage: # optional - mathics + sage: me=mathics(e); me E - sage: type(me) # optional - mathics + sage: type(me) - sage: P = me.parent(); P # optional - mathics + sage: P = me.parent(); P Mathics - sage: type(P) # optional - mathics + sage: type(P) Access to the Mathics expression objects:: - sage: res = me._mathics_result # optional - mathics - sage: type(res) # optional - mathics + sage: # optional - mathics + sage: res = me._mathics_result + sage: type(res) - sage: expr = res.last_eval; expr # optional - mathics + sage: expr = res.last_eval; expr - sage: type(expr) # optional - mathics + sage: type(expr) Applying Mathics methods:: - sage: me.to_sympy() # optional - mathics + sage: # optional - mathics + sage: me.to_sympy() E - sage: me.get_name() # optional - mathics + sage: me.get_name() 'System`E' - sage: me.is_inexact() # optional - mathics + sage: me.is_inexact() False - sage: me.is_symbol() # optional - mathics + sage: me.is_symbol() True Conversion to Sage:: @@ -900,12 +910,13 @@ def __getattr__(self, attrname): r""" EXAMPLES:: - sage: a = mathics(5*x) # optional - mathics - sage: res = a._mathics_result # optional - mathics - sage: str(a) == res.result # optional - mathics + sage: # optional - mathics + sage: a = mathics(5*x) + sage: res = a._mathics_result + sage: str(a) == res.result True - sage: t = mathics._eval('5*x') # optional - mathics - sage: t.last_eval == res.last_eval # optional - mathics + sage: t = mathics._eval('5*x') + sage: t.last_eval == res.last_eval True """ P = self._check_valid() @@ -1004,12 +1015,13 @@ def _sage_(self, locals={}): Mathics lists of numbers/constants become Sage lists of numbers/constants:: - sage: m = mathics('{{1., 4}, Pi, 3.2e100, I}') # optional - mathics - sage: s = m.sage(); s # optional - mathics + sage: # optional - mathics + sage: m = mathics('{{1., 4}, Pi, 3.2e100, I}') + sage: s = m.sage(); s [[1.00000000000000, 4], pi, 3.20000000000000*e100, 1.00000000000000*I] - sage: s[1].n() # optional - mathics + sage: s[1].n() 3.14159265358979 - sage: s[3]^2 # optional - mathics + sage: s[3]^2 -1.00000000000000 :: @@ -1040,11 +1052,12 @@ def _sage_(self, locals={}): :: - sage: m = mathics('bla^2') # optional - mathics - sage: mb = m.sage() # optional - mathics - sage: var('bla') # optional - mathics + sage: # optional - mathics + sage: m = mathics('bla^2') + sage: mb = m.sage() + sage: var('bla') bla - sage: bla^2 - mb # optional - mathics + sage: bla^2 - mb 0 """ @@ -1203,14 +1216,15 @@ def _richcmp_(self, other, op): r""" EXAMPLES:: - sage: mobj1 = mathics([x^2-1, 2]) # optional - mathics - sage: mobj2 = mathics('{x^2-1, 2}') # optional - mathics - sage: mobj3 = mathics('5*x + y') # optional - mathics - sage: mobj1 == mobj2 # optional - mathics + sage: # optional - mathics + sage: mobj1 = mathics([x^2-1, 2]) + sage: mobj2 = mathics('{x^2-1, 2}') + sage: mobj3 = mathics('5*x + y') + sage: mobj1 == mobj2 True - sage: mobj1 < mobj2 # optional - mathics + sage: mobj1 < mobj2 False - sage: mobj1 == mobj3 # optional - mathics + sage: mobj1 == mobj3 False """ P = self.parent() diff --git a/src/sage/interfaces/matlab.py b/src/sage/interfaces/matlab.py index 24c40a3647c..74354b77412 100644 --- a/src/sage/interfaces/matlab.py +++ b/src/sage/interfaces/matlab.py @@ -30,53 +30,57 @@ EXAMPLES:: - sage: matlab('4+10') # optional - matlab + sage: # optional - matlab + sage: matlab('4+10') 14 - sage: matlab('date') # optional - matlab; random output + sage: matlab('date') 18-Oct-2006 - sage: matlab('5*10 + 6') # optional - matlab + sage: matlab('5*10 + 6') 56 - sage: matlab('(6+6)/3') # optional - matlab + sage: matlab('(6+6)/3') 4 - sage: matlab('9')^2 # optional - matlab + sage: matlab('9')^2 81 - sage: a = matlab(10); b = matlab(20); c = matlab(30) # optional - matlab - sage: avg = (a+b+c)/3 ; avg # optional - matlab + sage: a = matlab(10); b = matlab(20); c = matlab(30) + sage: avg = (a+b+c)/3 ; avg 20 - sage: parent(avg) # optional - matlab + sage: parent(avg) Matlab :: - sage: my_scalar = matlab('3.1415') # optional - matlab - sage: my_scalar # optional - matlab + sage: # optional - matlab + sage: my_scalar = matlab('3.1415') + sage: my_scalar 3.1415 - sage: my_vector1 = matlab('[1,5,7]') # optional - matlab - sage: my_vector1 # optional - matlab + sage: my_vector1 = matlab('[1,5,7]') + sage: my_vector1 1 5 7 - sage: my_vector2 = matlab('[1;5;7]') # optional - matlab - sage: my_vector2 # optional - matlab + sage: my_vector2 = matlab('[1;5;7]') + sage: my_vector2 1 5 7 - sage: my_vector1 * my_vector2 # optional - matlab + sage: my_vector1 * my_vector2 75 :: - sage: row_vector1 = matlab('[1 2 3]') # optional - matlab - sage: row_vector2 = matlab('[3 2 1]') # optional - matlab - sage: matrix_from_row_vec = matlab('[%s; %s]'%(row_vector1.name(), row_vector2.name())) # optional - matlab - sage: matrix_from_row_vec # optional - matlab + sage: # optional - matlab + sage: row_vector1 = matlab('[1 2 3]') + sage: row_vector2 = matlab('[3 2 1]') + sage: matrix_from_row_vec = matlab('[%s; %s]'%(row_vector1.name(), row_vector2.name())) + sage: matrix_from_row_vec 1 2 3 3 2 1 :: - sage: column_vector1 = matlab('[1;3]') # optional - matlab - sage: column_vector2 = matlab('[2;8]') # optional - matlab - sage: matrix_from_col_vec = matlab('[%s %s]'%(column_vector1.name(), column_vector2.name())) # optional - matlab - sage: matrix_from_col_vec # optional - matlab + sage: # optional - matlab + sage: column_vector1 = matlab('[1;3]') + sage: column_vector2 = matlab('[2;8]') + sage: matrix_from_col_vec = matlab('[%s %s]'%(column_vector1.name(), column_vector2.name())) + sage: matrix_from_col_vec 1 2 3 8 @@ -106,12 +110,13 @@ :: - sage: my_vector1 = matlab('[1,5,7]') # optional - matlab - sage: my_vector1(1) # optional - matlab + sage: # optional - matlab + sage: my_vector1 = matlab('[1,5,7]') + sage: my_vector1(1) 1 - sage: my_vector1(2) # optional - matlab + sage: my_vector1(2) 5 - sage: my_vector1(3) # optional - matlab + sage: my_vector1(3) 7 Matrix indexing works as follows:: @@ -159,10 +164,11 @@ class Matlab(Expect): EXAMPLES:: - sage: a = matlab('[ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]') # optional - matlab - sage: b = matlab('[ 1; 3; 13]') # optional - matlab - sage: c = a * b # optional - matlab - sage: print(c) # optional - matlab + sage: # optional - matlab + sage: a = matlab('[ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]') + sage: b = matlab('[ 1; 3; 13]') + sage: c = a * b + sage: print(c) 30 122 505 @@ -328,12 +334,13 @@ def _matrix_(self, R): EXAMPLES:: - sage: A = matlab('[1,2;3,4]') # optional - matlab - sage: matrix(ZZ, A) # optional - matlab + sage: # optional - matlab + sage: A = matlab('[1,2;3,4]') + sage: matrix(ZZ, A) [1 2] [3 4] - sage: A = matlab('[1,2;3,4.5]') # optional - matlab - sage: matrix(RR, A) # optional - matlab + sage: A = matlab('[1,2;3,4.5]') + sage: matrix(RR, A) [1.00000000000000 2.00000000000000] [3.00000000000000 4.50000000000000] diff --git a/src/sage/interfaces/mupad.py b/src/sage/interfaces/mupad.py index 956de696806..82920a9edaa 100644 --- a/src/sage/interfaces/mupad.py +++ b/src/sage/interfaces/mupad.py @@ -13,23 +13,25 @@ TESTS:: - sage: mupad.package('"MuPAD-Combinat"') # optional - mupad - sage: combinat = mupad.combinat # optional - mupad - sage: examples = mupad.examples # optional - mupad - sage: S = examples.SymmetricFunctions() # optional - mupad - sage: S.s[2,1]^2 # optional - mupad + sage: # optional - mupad + sage: mupad.package('"MuPAD-Combinat"') + sage: combinat = mupad.combinat + sage: examples = mupad.examples + sage: S = examples.SymmetricFunctions() + sage: S.s[2,1]^2 s[3, 3] + s[4, 2] + s[2, 2, 1, 1] + s[2, 2, 2] + 2 s[3, 2, 1] + s[4, 1, 1] + s[3, 1, 1, 1] - sage: S.omega( S.s[3] ) # optional - mupad + sage: S.omega( S.s[3] ) s[1, 1, 1] - sage: s = S.s # optional - mupad - sage: p = S.p # optional - mupad - sage: s(s[2,1] + p[2,1]) # optional - mupad + sage: s = S.s + sage: p = S.p + sage: s(s[2,1] + p[2,1]) s[2, 1] + s[3] - s[1, 1, 1] - sage: s(_) # optional - mupad + sage: s(_) s[2, 1] + s[3] - s[1, 1, 1] - sage: combinat.tableaux.list(3) # optional - mupad # note: the order of the result seems to depend on the version of MuPAD / MuPAD-Combinat + sage: # optional - mupad + sage: combinat.tableaux.list(3) -- +---+ -- | | 3 | | | +---+ +---+ +---+ | @@ -37,8 +39,8 @@ | +---+---+---+ +---+---+ +---+---+ +---+ | | | 1 | 2 | 3 |, | 1 | 2 |, | 1 | 3 |, | 1 | | -- +---+---+---+ +---+---+ +---+---+ +---+ -- - sage: three = mupad(3) # optional - mupad - sage: three.combinat.tableaux.list() # optional - mupad + sage: three = mupad(3) + sage: three.combinat.tableaux.list() -- +---+ -- | | 3 | | | +---+ +---+ +---+ | @@ -46,12 +48,12 @@ | +---+---+---+ +---+---+ +---+---+ +---+ | | | 1 | 2 | 3 |, | 1 | 2 |, | 1 | 3 |, | 1 | | -- +---+---+---+ +---+---+ +---+---+ +---+ -- - sage: t = _[1] # optional - mupad - sage: t # optional - mupad + sage: t = _[1] + sage: t +---+---+---+ | 1 | 2 | 3 | +---+---+---+ - sage: combinat.tableaux.conjugate(t) # optional - mupad + sage: combinat.tableaux.conjugate(t) +---+ | 3 | +---+ @@ -60,21 +62,22 @@ | 1 | +---+ - sage: combinat.ribbonsTableaux.list([2,2],[1,1],2) # optional - mupad + sage: # optional - mupad + sage: combinat.ribbonsTableaux.list([2,2],[1,1],2) -- +---+---+ +---+---+ -- | | | 2 | | 2 | | | + + +, +---+---+ | | | 1 | | | 1 | | -- +---+---+ +---+---+ -- - sage: combinat.tableaux.kAtom([2,1],3) # optional - mupad + sage: combinat.tableaux.kAtom([2,1],3) -- +---+ -- | | 2 | | | +---+---+ | | | 1 | 1 | | -- +---+---+ -- - sage: M = S.Macdonald() # optional - mupad - sage: a = M.P[1]^2 # optional - mupad - sage: mupad.mapcoeffs(a, 'normal') # optional - mupad + sage: M = S.Macdonald() + sage: a = M.P[1]^2 + sage: mupad.mapcoeffs(a, 'normal') q - t + q t - 1 P[2] + --------------- P[1, 1] q t - 1 @@ -491,13 +494,14 @@ def __getattr__(self, attrname): """ EXAMPLES:: - sage: mupad.package('"MuPAD-Combinat"') # optional - mupad-Combinat - sage: combinat = mupad.combinat # optional - mupad-Combinat - sage: three = mupad(3) # optional - mupad-Combinat - sage: type(three.combinat) # optional - mupad-Combinat + sage: # optional - mupad + sage: mupad.package('"MuPAD-Combinat"') + sage: combinat = mupad.combinat + sage: three = mupad(3) + sage: type(three.combinat) - sage: tableaux = three.combinat.tableaux # optional - mupad-Combinat - sage: type(tableaux) # optional - mupad-Combinat + sage: tableaux = three.combinat.tableaux + sage: type(tableaux) """ P = self._obj.parent() @@ -528,13 +532,14 @@ def __call__(self, *args): """ EXAMPLES:: - sage: mupad.package('"MuPAD-Combinat"') # optional - mupad-Combinat - sage: combinat = mupad.combinat # optional - mupad-Combinat - sage: examples = mupad.examples # optional - mupad-Combinat - sage: S = examples.SymmetricFunctions() # optional - mupad-Combinat - sage: type(S.omega) # optional - mupad-Combinat + sage: # optional - mupad + sage: mupad.package('"MuPAD-Combinat"') + sage: combinat = mupad.combinat + sage: examples = mupad.examples + sage: S = examples.SymmetricFunctions() + sage: type(S.omega) - sage: S.omega(S.s[3]) # optional - mupad-Combinat + sage: S.omega(S.s[3]) s[1, 1, 1] """ P = self._obj.parent() @@ -551,11 +556,12 @@ def __getattr__(self, attrname): """ EXAMPLES:: - sage: mupad.package('"MuPAD-Combinat"') # optional - mupad-Combinat - sage: S = mupad.examples.SymmetricFunctions() # optional - mupad-Combinat - sage: type(S) # optional - mupad-Combinat + sage: # optional - mupad + sage: mupad.package('"MuPAD-Combinat"') + sage: S = mupad.examples.SymmetricFunctions() + sage: type(S) - sage: S.s # optional - mupad-Combinat + sage: S.s (examples::SymmetricFunctions(Dom::ExpressionField()))::s sage: x = mupad('x') # optional - mupad-Combinat diff --git a/src/sage/interfaces/octave.py b/src/sage/interfaces/octave.py index d0f5694c8bc..10e8457aa0f 100644 --- a/src/sage/interfaces/octave.py +++ b/src/sage/interfaces/octave.py @@ -60,31 +60,32 @@ :: - sage: octave("airy(3,2)") # optional - octave + sage: # optional - octave + sage: octave("airy(3,2)") 4.10068 - sage: octave("beta(2,2)") # optional - octave + sage: octave("beta(2,2)") 0.166667 - sage: octave("betainc(0.2,2,2)") # optional - octave + sage: octave("betainc(0.2,2,2)") 0.104 - sage: octave("besselh(0,2)") # optional - octave + sage: octave("besselh(0,2)") (0.223891,0.510376) - sage: octave("besselh(0,1)") # optional - octave + sage: octave("besselh(0,1)") (0.765198,0.088257) - sage: octave("besseli(1,2)") # optional - octave + sage: octave("besseli(1,2)") 1.59064 - sage: octave("besselj(1,2)") # optional - octave + sage: octave("besselj(1,2)") 0.576725 - sage: octave("besselk(1,2)") # optional - octave + sage: octave("besselk(1,2)") 0.139866 - sage: octave("erf(0)") # optional - octave + sage: octave("erf(0)") 0 - sage: octave("erf(1)") # optional - octave + sage: octave("erf(1)") 0.842701 - sage: octave("erfinv(0.842)") # optional - octave + sage: octave("erfinv(0.842)") 0.998315 - sage: octave("gamma(1.5)") # optional - octave + sage: octave("gamma(1.5)") 0.886227 - sage: octave("gammainc(1.5,1)") # optional - octave + sage: octave("gammainc(1.5,1)") 0.77687 Tutorial @@ -92,37 +93,39 @@ EXAMPLES:: - sage: octave('4+10') # optional - octave + sage: # optional - octave + sage: octave('4+10') 14 - sage: octave('date') # optional - octave; random output + sage: octave('date') 18-Oct-2007 - sage: octave('5*10 + 6') # optional - octave + sage: octave('5*10 + 6') 56 - sage: octave('(6+6)/3') # optional - octave + sage: octave('(6+6)/3') 4 - sage: octave('9')^2 # optional - octave + sage: octave('9')^2 81 - sage: a = octave(10); b = octave(20); c = octave(30) # optional - octave - sage: avg = (a+b+c)/3 # optional - octave - sage: avg # optional - octave + sage: a = octave(10); b = octave(20); c = octave(30) + sage: avg = (a+b+c)/3 + sage: avg 20 - sage: parent(avg) # optional - octave + sage: parent(avg) Octave :: - sage: my_scalar = octave('3.1415') # optional - octave - sage: my_scalar # optional - octave + sage: # optional - octave + sage: my_scalar = octave('3.1415') + sage: my_scalar 3.1415 - sage: my_vector1 = octave('[1,5,7]') # optional - octave - sage: my_vector1 # optional - octave + sage: my_vector1 = octave('[1,5,7]') + sage: my_vector1 1 5 7 - sage: my_vector2 = octave('[1;5;7]') # optional - octave - sage: my_vector2 # optional - octave + sage: my_vector2 = octave('[1;5;7]') + sage: my_vector2 1 5 7 - sage: my_vector1 * my_vector2 # optional - octave + sage: my_vector1 * my_vector2 75 """ @@ -356,11 +359,12 @@ def _start(self): EXAMPLES:: - sage: o = Octave() # optional - octave - sage: o.is_running() # optional - octave + sage: # optional - octave + sage: o = Octave() + sage: o.is_running() False - sage: o._start() # optional - octave - sage: o.is_running() # optional - octave + sage: o._start() + sage: o.is_running() True """ Expect._start(self) @@ -647,13 +651,14 @@ def __bool__(self): EXAMPLES:: - sage: bool(octave('0')) # optional - octave + sage: # optional - octave + sage: bool(octave('0')) False - sage: bool(octave('[]')) # optional - octave + sage: bool(octave('[]')) False - sage: bool(octave('[0,0]')) # optional - octave + sage: bool(octave('[0,0]')) False - sage: bool(octave('[0,0,0;0,0,0]')) # optional - octave + sage: bool(octave('[0,0,0;0,0,0]')) False sage: bool(octave('0.1')) # optional - octave @@ -685,12 +690,13 @@ def _matrix_(self, R=None): sage: _.base_ring() # optional - octave Complex Double Field - sage: A = octave('[1,2;3,4]') # optional - octave - sage: matrix(ZZ, A) # optional - octave + sage: # optional - octave + sage: A = octave('[1,2;3,4]') + sage: matrix(ZZ, A) [1 2] [3 4] - sage: A = octave('[1,2;3,4.5]') # optional - octave - sage: matrix(RR, A) # optional - octave + sage: A = octave('[1,2;3,4.5]') + sage: matrix(RR, A) [1.00000000000000 2.00000000000000] [3.00000000000000 4.50000000000000] """ @@ -716,14 +722,15 @@ def _vector_(self, R=None): EXAMPLES:: - sage: A = octave('[1,2,3,4]') # optional - octave - sage: vector(ZZ, A) # optional - octave + sage: # optional - octave + sage: A = octave('[1,2,3,4]') + sage: vector(ZZ, A) (1, 2, 3, 4) - sage: A = octave('[1,2.3,4.5]') # optional - octave - sage: vector(A) # optional - octave + sage: A = octave('[1,2.3,4.5]') + sage: vector(A) (1.0, 2.3, 4.5) - sage: A = octave('[1,I]') # optional - octave - sage: vector(A) # optional - octave + sage: A = octave('[1,I]') + sage: vector(A) (1.0, 1.0*I) """ from sage.modules.free_module import FreeModule @@ -780,23 +787,24 @@ def _sage_(self): EXAMPLES:: - sage: A = octave('2833') # optional - octave - sage: A.sage() # optional - octave + sage: # optional - octave + sage: A = octave('2833') + sage: A.sage() 2833.0 - sage: B = sqrt(A) # optional - octave - sage: B.sage() # optional - octave + sage: B = sqrt(A) + sage: B.sage() 53.2259 - sage: C = sqrt(-A) # optional - octave - sage: C.sage() # optional - octave + sage: C = sqrt(-A) + sage: C.sage() 53.2259*I - sage: A = octave('[1,2,3,4]') # optional - octave - sage: A.sage() # optional - octave + sage: A = octave('[1,2,3,4]') + sage: A.sage() (1.0, 2.0, 3.0, 4.0) - sage: A = octave('[1,2.3,4.5]') # optional - octave - sage: A.sage() # optional - octave + sage: A = octave('[1,2.3,4.5]') + sage: A.sage() (1.0, 2.3, 4.5) - sage: A = octave('[1,2.3+I,4.5]') # optional - octave - sage: A.sage() # optional - octave + sage: A = octave('[1,2.3+I,4.5]') + sage: A.sage() (1.0, 2.3 + 1.0*I, 4.5) """ if self.isscalar(): diff --git a/src/sage/interfaces/polymake.py b/src/sage/interfaces/polymake.py index 9161ebd5377..3875ff7962e 100644 --- a/src/sage/interfaces/polymake.py +++ b/src/sage/interfaces/polymake.py @@ -243,15 +243,16 @@ def _function_call_string(self, function, args, kwds): EXAMPLES:: - sage: polymake._function_call_string('cube', ['2','7','3'], ['group=>1']) # optional - jupymake + sage: # optional - jupymake + sage: polymake._function_call_string('cube', ['2','7','3'], ['group=>1']) 'cube(2,7,3, group=>1);' - sage: c = polymake('cube(2,7,3, group=>1)') # optional - jupymake - sage: c.VERTICES # optional - jupymake + sage: c = polymake('cube(2,7,3, group=>1)') + sage: c.VERTICES 1 3 3 1 7 3 1 3 7 1 7 7 - sage: c.GROUP # optional - jupymake + sage: c.GROUP full combinatorial group """ @@ -461,13 +462,14 @@ def clear(self, var): TESTS:: - sage: c = polymake.cube(15) # optional - jupymake - sage: polymake._available_vars = [] # optional - jupymake - sage: old = c._name # optional - jupymake - sage: del c # optional - jupymake # indirect doctest - sage: len(polymake._available_vars) # optional - jupymake + sage: # optional - jupymake + sage: c = polymake.cube(15) + sage: polymake._available_vars = [] + sage: old = c._name + sage: del c + sage: len(polymake._available_vars) 1 - sage: polymake._next_var_name() in old # optional - jupymake + sage: polymake._next_var_name() in old True """ @@ -500,13 +502,14 @@ def _create(self, value, name=None): EXAMPLES:: - sage: polymake._create("('foo', 'bar')", name="my_array") # optional - jupymake + sage: # optional - jupymake + sage: polymake._create("('foo', 'bar')", name="my_array") '@my_array' - sage: print(polymake.eval('print join(", ", @my_array);')) # optional - jupymake + sage: print(polymake.eval('print join(", ", @my_array);')) foo, bar - sage: polymake._create('"foobar"', name="my_string") # optional - jupymake + sage: polymake._create('"foobar"', name="my_string") '$my_string[0]' - sage: print(polymake.eval('print $my_string[0];')) # optional - jupymake + sage: print(polymake.eval('print $my_string[0];')) foobar """ @@ -743,20 +746,22 @@ def application(self, app): terms of inequalities. Polymake knows to compute the f- and h-vector and finds that the polytope is very ample:: - sage: q = polymake.new_object("Polytope", INEQUALITIES=[[5,-4,0,1],[-3,0,-4,1],[-2,1,0,0],[-4,4,4,-1],[0,0,1,0],[8,0,0,-1],[1,0,-1,0],[3,-1,0,0]]) # optional - jupymake - sage: q.H_VECTOR # optional - jupymake + sage: # optional - jupymake + sage: q = polymake.new_object("Polytope", INEQUALITIES=[[5,-4,0,1],[-3,0,-4,1],[-2,1,0,0],[-4,4,4,-1],[0,0,1,0],[8,0,0,-1],[1,0,-1,0],[3,-1,0,0]]) + sage: q.H_VECTOR 1 5 5 1 - sage: q.F_VECTOR # optional - jupymake + sage: q.F_VECTOR 8 14 8 - sage: q.VERY_AMPLE # optional - jupymake + sage: q.VERY_AMPLE true In the application 'fan', polymake can now compute the normal fan of `q` and its (primitive) rays:: - sage: polymake.application('fan') # optional - jupymake - sage: g = q.normal_fan() # optional - jupymake - sage: g.RAYS # optional - jupymake + sage: # optional - jupymake + sage: polymake.application('fan') + sage: g = q.normal_fan() + sage: g.RAYS -1 0 1/4 0 -1 1/4 1 0 0 @@ -765,7 +770,7 @@ def application(self, app): 0 0 -1 0 -1 0 -1 0 0 - sage: g.RAYS.primitive() # optional - jupymake + sage: g.RAYS.primitive() -4 0 1 0 -4 1 1 0 0 @@ -784,14 +789,15 @@ def application(self, app): but only in 'tropical', the following shows the effect of changing the application. :: - sage: polymake.application('polytope') # optional - jupymake - sage: 'trop_witness' in dir(polymake) # optional - jupymake + sage: # optional - jupymake + sage: polymake.application('polytope') + sage: 'trop_witness' in dir(polymake) False - sage: polymake.application('tropical') # optional - jupymake - sage: 'trop_witness' in dir(polymake) # optional - jupymake + sage: polymake.application('tropical') + sage: 'trop_witness' in dir(polymake) True - sage: polymake.application('polytope') # optional - jupymake - sage: 'trop_witness' in dir(polymake) # optional - jupymake + sage: polymake.application('polytope') + sage: 'trop_witness' in dir(polymake) False For completeness, we show what happens when asking for an application @@ -827,17 +833,18 @@ def new_object(self, name, *args, **kwds): EXAMPLES:: - sage: q = polymake.new_object("Polytope", INEQUALITIES=[[4,-4,0,1],[-4,0,-4,1],[-2,1,0,0],[-4,4,4,-1],[0,0,1,0],[8,0,0,-1]]) # optional - jupymake - sage: q.N_VERTICES # optional - jupymake + sage: # optional - jupymake + sage: q = polymake.new_object("Polytope", INEQUALITIES=[[4,-4,0,1],[-4,0,-4,1],[-2,1,0,0],[-4,4,4,-1],[0,0,1,0],[8,0,0,-1]]) + sage: q.N_VERTICES 4 - sage: q.BOUNDED # optional - jupymake + sage: q.BOUNDED true - sage: q.VERTICES # optional - jupymake + sage: q.VERTICES 1 2 0 4 1 3 0 8 1 2 1 8 1 3 1 8 - sage: q.full_typename() # optional - jupymake + sage: q.full_typename() 'Polytope' """ @@ -885,11 +892,12 @@ def _repr_(self): of the object that is not longer than single line, it is used for printing:: - sage: p = polymake.rand_sphere(3, 12, seed=15) # optional - jupymake - sage: p # optional - jupymake + sage: # optional - jupymake + sage: p = polymake.rand_sphere(3, 12, seed=15) + sage: p Random spherical polytope of dimension 3; seed=15... - sage: c = polymake.cube(4) # optional - jupymake - sage: c # optional - jupymake + sage: c = polymake.cube(4) + sage: c cube of dimension 4 We use the print representation of scalars to display scalars:: @@ -924,11 +932,12 @@ def _repr_(self): Similarly, polymake matrices and vectors are explicitly listed:: - sage: c.VERTICES.typename() # optional - jupymake + sage: # optional - jupymake + sage: c.VERTICES.typename() 'Matrix' - sage: c.VERTICES[0].typename() # optional - jupymake + sage: c.VERTICES[0].typename() 'Vector' - sage: c.VERTICES # optional - jupymake # random + sage: c.VERTICES 1 -1 -1 -1 -1 1 1 -1 -1 -1 1 -1 1 -1 -1 @@ -945,7 +954,7 @@ def _repr_(self): 1 1 -1 1 1 1 -1 1 1 1 1 1 1 1 1 - sage: c.VERTICES[0] # optional - jupymake + sage: c.VERTICES[0] 1 -1 -1 -1 -1 For other types, we simply use the print representation offered @@ -1225,34 +1234,37 @@ def __getattr__(self, attrname): A property:: - sage: c = polymake.cube(3) # optional - jupymake - sage: c.H_VECTOR # optional - jupymake + sage: # optional - jupymake + sage: c = polymake.cube(3) + sage: c.H_VECTOR 1 5 5 1 - sage: c.N_VERTICES # optional - jupymake + sage: c.N_VERTICES 8 - sage: d = polymake.cross(3) # optional - jupymake - sage: d.N_VERTICES # optional - jupymake + sage: d = polymake.cross(3) + sage: d.N_VERTICES 6 A function:: - sage: c.minkowski_sum_fukuda # optional - jupymake + sage: # optional - jupymake + sage: c.minkowski_sum_fukuda minkowski_sum_fukuda (bound to Polymake::polytope::Polytope__Rational object) - sage: s = c.minkowski_sum_fukuda(d) # optional - jupymake - sage: s.N_VERTICES # optional - jupymake + sage: s = c.minkowski_sum_fukuda(d) + sage: s.N_VERTICES 24 - sage: s # optional - jupymake + sage: s Polytope[SAGE...] A member function:: - sage: c = polymake.cube(2) # optional - jupymake - sage: V = polymake.new_object('Vector', [1,0,0]) # optional - jupymake - sage: V # optional - jupymake + sage: # optional - jupymake + sage: c = polymake.cube(2) + sage: V = polymake.new_object('Vector', [1,0,0]) + sage: V 1 0 0 - sage: c.contains # optional - jupymake + sage: c.contains Member function 'contains' of Polymake::polytope::Polytope__Rational object - sage: c.contains(V) # optional - jupymake + sage: c.contains(V) true """ @@ -1281,13 +1293,14 @@ def get_member_function(self, attrname): EXAMPLES:: - sage: c = polymake.cube(2) # optional - jupymake - sage: c.contains # optional - jupymake + sage: # optional - jupymake + sage: c = polymake.cube(2) + sage: c.contains Member function 'contains' of Polymake::polytope::Polytope__Rational object - sage: V = polymake.new_object('Vector', [1,0,0]) # optional - jupymake - sage: V # optional - jupymake + sage: V = polymake.new_object('Vector', [1,0,0]) + sage: V 1 0 0 - sage: c.contains(V) # optional - jupymake + sage: c.contains(V) true Whether a member function of the given name actually exists for that @@ -1438,12 +1451,13 @@ def typeof(self): EXAMPLES:: - sage: p = polymake.rand_sphere(3, 13, seed=12) # optional - jupymake - sage: p.typeof() # optional - jupymake + sage: # optional - jupymake + sage: p = polymake.rand_sphere(3, 13, seed=12) + sage: p.typeof() ('Polymake::polytope::Polytope__Rational', 'ARRAY') - sage: p.VERTICES.typeof() # optional - jupymake + sage: p.VERTICES.typeof() ('Polymake::common::Matrix_A_Rational_I_NonSymmetric_Z', 'ARRAY') - sage: p.get_schedule('"F_VECTOR"').typeof() # optional - jupymake + sage: p.get_schedule('"F_VECTOR"').typeof() ('Polymake::Core::Scheduler::RuleChain', 'ARRAY') On "small" objects, it just returns empty strings:: @@ -1666,13 +1680,14 @@ class PolymakeFunctionElement(InterfaceFunctionElement): EXAMPLES:: - sage: c = polymake.cube(2) # optional - jupymake - sage: V = polymake.new_object('Vector', [1,0,0]) # optional - jupymake - sage: V # optional - jupymake + sage: # optional - jupymake + sage: c = polymake.cube(2) + sage: V = polymake.new_object('Vector', [1,0,0]) + sage: V 1 0 0 - sage: c.contains # optional - jupymake + sage: c.contains Member function 'contains' of Polymake::polytope::Polytope__Rational object - sage: c.contains(V) # optional - jupymake + sage: c.contains(V) true """ @@ -1840,16 +1855,17 @@ class PolymakeJuPyMake(PolymakeAbstract): :: - sage: L = polymake.db_query({'"_id"': '"F.4D.0047"'}, # long time, optional - jupymake internet perl_mongodb + sage: # long time, optional - internet jupymake perl_mongodb + sage: L = polymake.db_query({'"_id"': '"F.4D.0047"'}, ....: db='"LatticePolytopes"', ....: collection='"SmoothReflexive"'); L BigObjectArray - sage: len(L) # long time, optional - jupymake internet perl_mongodb + sage: len(L) 1 - sage: P = L[0] # long time, optional - jupymake internet perl_mongodb - sage: sorted(P.list_properties(), key=str) # long time, optional - jupymake internet perl_mongodb + sage: P = L[0] + sage: sorted(P.list_properties(), key=str) [..., LATTICE_POINTS_GENERATORS, ..., POINTED, ...] - sage: P.F_VECTOR # long time, optional - jupymake internet perl_mongodb + sage: P.F_VECTOR 20 40 29 9 """ diff --git a/src/sage/interfaces/qepcad.py b/src/sage/interfaces/qepcad.py index b6b657515bc..5a69861eec8 100644 --- a/src/sage/interfaces/qepcad.py +++ b/src/sage/interfaces/qepcad.py @@ -404,13 +404,14 @@ A :class:`QepcadCell` has accessor methods for the important state held within a cell. For instance:: - sage: c.level() # optional - qepcad + sage: # optional - qepcad + sage: c.level() 2 - sage: c.index() # optional - qepcad + sage: c.index() (3, 4) - sage: qe.cell(3).number_of_children() # optional - qepcad + sage: qe.cell(3).number_of_children() 5 - sage: len(qe.cell(3)) # optional - qepcad + sage: len(qe.cell(3)) 5 One particularly useful thing we can get from a cell is its sample point, @@ -574,19 +575,20 @@ sage: _qepcad_atoms(qepcad(F, solution='extended')) # optional - qepcad {'x > _root_1 2 x^2 - 3', 'x^2 - 3 <= 0'} - sage: qe = qepcad(qf.and_(ellipse == 0, circle == 0), interact=True) # optional - qepcad - sage: qe.go(); qe.go(); qe.go() # optional - qepcad + sage: # optional - qepcad + sage: qe = qepcad(qf.and_(ellipse == 0, circle == 0), interact=True) + sage: qe.go(); qe.go(); qe.go() QEPCAD object has moved to phase 'Before Projection (y)' QEPCAD object has moved to phase 'Before Choice' QEPCAD object has moved to phase 'Before Solution' - sage: for c in qe.cell(): # optional - qepcad + sage: for c in qe.cell(): ....: count_ellipse = 0 ....: count_circle = 0 ....: for c2 in c: ....: count_ellipse += (c2.signs()[1][0] == 0) ....: count_circle += (c2.signs()[1][1] == 0) ....: c.set_truth(count_ellipse == 2 and count_circle == 2) - sage: _qepcad_atoms(qe.solution_extension('G')) # optional - qepcad + sage: _qepcad_atoms(qe.solution_extension('G')) {'8 x^2 - 8 x - 29 < 0', 'x^2 - 3 < 0'} @@ -1044,24 +1046,25 @@ def phase(self): EXAMPLES:: - sage: qe = qepcad(x > 2/3, interact=True) # optional - qepcad - sage: qe.phase() # optional - qepcad + sage: # optional - qepcad + sage: qe = qepcad(x > 2/3, interact=True) + sage: qe.phase() 'Before Normalization' - sage: qe.go() # optional - qepcad + sage: qe.go() QEPCAD object has moved to phase 'At the end of projection phase' - sage: qe.phase() # optional - qepcad + sage: qe.phase() 'At the end of projection phase' - sage: qe.go() # optional - qepcad + sage: qe.go() QEPCAD object has moved to phase 'Before Choice' - sage: qe.phase() # optional - qepcad + sage: qe.phase() 'Before Choice' - sage: qe.go() # optional - qepcad + sage: qe.go() QEPCAD object has moved to phase 'Before Solution' - sage: qe.phase() # optional - qepcad + sage: qe.phase() 'Before Solution' - sage: qe.go() # optional - qepcad + sage: qe.go() 3 x - 2 > 0 - sage: qe.phase() # optional - qepcad + sage: qe.phase() 'EXITED' """ match = self._qex.expect().match @@ -1079,13 +1082,14 @@ def _parse_answer_stats(self): EXAMPLES:: - sage: qe = qepcad(x^2 > 2, interact=True) # optional - qepcad - sage: qe.finish() # optional - qepcad + sage: # optional - qepcad + sage: qe = qepcad(x^2 > 2, interact=True) + sage: qe.finish() x^2 - 2 > 0 - sage: (ans, stats) = qe._parse_answer_stats() # optional - qepcad - sage: ans # optional - qepcad + sage: (ans, stats) = qe._parse_answer_stats() + sage: ans 'x^2 - 2 > 0' - sage: stats # random, optional - qepcad + sage: stats '-----------------------------------------------------------------------------\r\n0 Garbage collections, 0 Cells and 0 Arrays reclaimed, in 0 milliseconds.\r\n492514 Cells in AVAIL, 500000 Cells in SPACE.\r\n\r\nSystem time: 16 milliseconds.\r\nSystem time after the initialization: 4 milliseconds.\r\n-----------------------------------------------------------------------------\r\n' """ if self.phase() != 'EXITED': @@ -1168,14 +1172,15 @@ def cell(self, *index): EXAMPLES:: - sage: qe = qepcad(x + 3 == 42, interact=True) # optional - qepcad - sage: qe.go(); qe.go(); qe.go() # optional - qepcad + sage: # optional - qepcad + sage: qe = qepcad(x + 3 == 42, interact=True) + sage: qe.go(); qe.go(); qe.go() QEPCAD object has moved to phase 'At the end of projection phase' QEPCAD object has moved to phase 'Before Choice' QEPCAD object has moved to phase 'Before Solution' - sage: qe.cell(2) # optional - qepcad + sage: qe.cell(2) QEPCAD cell (2) - sage: qe.cell(2) is qe.cell(2) # optional - qepcad + sage: qe.cell(2) is qe.cell(2) True """ index_str = _format_cell_index(index) @@ -2696,16 +2701,17 @@ def sample_point(self): EXAMPLES:: - sage: qe = qepcad(x^2 - x - 1 == 0, interact=True) # optional - qepcad - sage: qe.go(); qe.go(); qe.go() # optional - qepcad + sage: # optional - qepcad + sage: qe = qepcad(x^2 - x - 1 == 0, interact=True) + sage: qe.go(); qe.go(); qe.go() QEPCAD object has moved to phase 'At the end of projection phase' QEPCAD object has moved to phase 'Before Choice' QEPCAD object has moved to phase 'Before Solution' - sage: v1 = qe.cell(2).sample_point()[0]; v1 # optional - qepcad + sage: v1 = qe.cell(2).sample_point()[0]; v1 -0.618033988749895? - sage: v2 = qe.cell(4).sample_point()[0]; v2 # optional - qepcad + sage: v2 = qe.cell(4).sample_point()[0]; v2 1.618033988749895? - sage: v1 + v2 == 1 # optional - qepcad + sage: v1 + v2 == 1 True """ try: diff --git a/src/sage/interfaces/rubik.py b/src/sage/interfaces/rubik.py index 109a2623c95..767c440715d 100644 --- a/src/sage/interfaces/rubik.py +++ b/src/sage/interfaces/rubik.py @@ -137,19 +137,20 @@ def solve(self, facets): EXAMPLES:: - sage: from sage.interfaces.rubik import * # optional - rubiks - sage: solver = DikSolver() # optional - rubiks - sage: solver = OptimalSolver() # optional - rubiks # long time (28s on sage.math, 2012) + sage: # optional - rubiks + sage: from sage.interfaces.rubik import * + sage: solver = DikSolver() + sage: solver = OptimalSolver() # long time (28s on sage.math, 2012) Initializing tables... Done. - sage: C = RubiksCube("R U") # optional - rubiks - sage: solver.solve(C.facets()) # optional - rubiks + sage: C = RubiksCube("R U") + sage: solver.solve(C.facets()) 'R U' - sage: C = RubiksCube("R U F L B D") # optional - rubiks - sage: solver.solve(C.facets()) # optional - rubiks + sage: C = RubiksCube("R U F L B D") + sage: solver.solve(C.facets()) 'R U F L B D' - sage: C = RubiksCube("R2 D2") # optional - rubiks - sage: solver.solve(C.facets()) # optional - rubiks + sage: C = RubiksCube("R2 D2") + sage: solver.solve(C.facets()) 'R2 D2' """ self.ready() @@ -193,21 +194,22 @@ def solve(self, facets): """ EXAMPLES:: - sage: from sage.interfaces.rubik import * # optional - rubiks - sage: C = RubiksCube("R U") # optional - rubiks - sage: CubexSolver().solve(C.facets()) # optional - rubiks + sage: # optional - rubiks + sage: from sage.interfaces.rubik import * + sage: C = RubiksCube("R U") + sage: CubexSolver().solve(C.facets()) 'R U' - sage: C = RubiksCube("R U F L B D") # optional - rubiks - sage: sol = CubexSolver().solve(C.facets()); sol # optional - rubiks + sage: C = RubiksCube("R U F L B D") + sage: sol = CubexSolver().solve(C.facets()); sol "U' L' L' U L U' L U D L L D' L' D L' D' L D L' U' L D' L' U L' B' U' L' U B L D L D' U' L' U L B L B' L' U L U' L' F' L' F L' F L F' L' D' L' D D L D' B L B' L B' L B F' L F F B' L F' B D' D' L D B' B' L' D' B U' U' L' B' D' F' F' L D F'" - sage: RubiksCube(sol) == C # optional - rubiks + sage: RubiksCube(sol) == C True - sage: C = RubiksCube("R2 F'") # optional - rubiks - sage: CubexSolver().solve(C.facets()) # optional - rubiks + sage: C = RubiksCube("R2 F'") + sage: CubexSolver().solve(C.facets()) "R' R' F'" - sage: C = RubiksCube().scramble() # optional - rubiks - sage: sol = CubexSolver().solve(C.facets()) # optional - rubiks - sage: C == RubiksCube(sol) # optional - rubiks + sage: C = RubiksCube().scramble() + sage: sol = CubexSolver().solve(C.facets()) + sage: C == RubiksCube(sol) True """ s = self.format_cube(facets) @@ -245,15 +247,16 @@ def solve(self, facets, timeout=10, extra_time=2): """ EXAMPLES:: - sage: from sage.interfaces.rubik import * # optional - rubiks - sage: C = RubiksCube().move("R U") # optional - rubiks - sage: DikSolver().solve(C.facets()) # optional - rubiks + sage: # optional - rubiks + sage: from sage.interfaces.rubik import * + sage: C = RubiksCube().move("R U") + sage: DikSolver().solve(C.facets()) 'R U' - sage: C = RubiksCube().move("R U F L B D") # optional - rubiks - sage: DikSolver().solve(C.facets()) # optional - rubiks + sage: C = RubiksCube().move("R U F L B D") + sage: DikSolver().solve(C.facets()) 'R U F L B D' - sage: C = RubiksCube().move("R2 F'") # optional - rubiks - sage: DikSolver().solve(C.facets()) # optional - rubiks + sage: C = RubiksCube().move("R2 F'") + sage: DikSolver().solve(C.facets()) "R2 F'" """ cube_str = self.format_cube(facets) diff --git a/src/sage/interfaces/scilab.py b/src/sage/interfaces/scilab.py index 54c28f55598..b1fd5c1d983 100644 --- a/src/sage/interfaces/scilab.py +++ b/src/sage/interfaces/scilab.py @@ -15,60 +15,65 @@ EXAMPLES:: - sage: scilab.eval('2+2') # optional - scilab + sage: # optional - scilab + sage: scilab.eval('2+2') 'ans =\n \n 4.' - sage: scilab('2+2') # optional - scilab + sage: scilab('2+2') 4. - sage: a = scilab(10) # optional - scilab - sage: a**10 # optional - scilab + sage: a = scilab(10) + sage: a**10 1.000D+10 Tutorial based the MATLAB interface tutorial: EXAMPLES:: - sage: scilab('4+10') # optional - scilab + sage: # optional - scilab + sage: scilab('4+10') 14. - sage: scilab('date') # optional - scilab; random output + sage: scilab('date') 15-Feb-2010 - sage: scilab('5*10 + 6') # optional - scilab + sage: scilab('5*10 + 6') 56. - sage: scilab('(6+6)/3') # optional - scilab + sage: scilab('(6+6)/3') 4. - sage: scilab('9')^2 # optional - scilab + sage: scilab('9')^2 81. - sage: a = scilab(10); b = scilab(20); c = scilab(30) # optional - scilab - sage: avg = (a+b+c)/3 # optional - scilab - sage: avg # optional - scilab + sage: a = scilab(10); b = scilab(20); c = scilab(30) + sage: avg = (a+b+c)/3 + sage: avg 20. - sage: parent(avg) # optional - scilab + sage: parent(avg) Scilab - sage: my_scalar = scilab('3.1415') # optional - scilab - sage: my_scalar # optional - scilab + sage: # optional - scilab + sage: my_scalar = scilab('3.1415') + sage: my_scalar 3.1415 - sage: my_vector1 = scilab('[1,5,7]') # optional - scilab - sage: my_vector1 # optional - scilab + sage: my_vector1 = scilab('[1,5,7]') + sage: my_vector1 1. 5. 7. - sage: my_vector2 = scilab('[1;5;7]') # optional - scilab - sage: my_vector2 # optional - scilab + sage: my_vector2 = scilab('[1;5;7]') + sage: my_vector2 1. 5. 7. - sage: my_vector1 * my_vector2 # optional - scilab + sage: my_vector1 * my_vector2 75. - sage: row_vector1 = scilab('[1 2 3]') # optional - scilab - sage: row_vector2 = scilab('[3 2 1]') # optional - scilab - sage: matrix_from_row_vec = scilab('[%s; %s]'%(row_vector1.name(), row_vector2.name())) # optional - scilab - sage: matrix_from_row_vec # optional - scilab + sage: # optional - scilab + sage: row_vector1 = scilab('[1 2 3]') + sage: row_vector2 = scilab('[3 2 1]') + sage: matrix_from_row_vec = scilab('[%s; %s]'%(row_vector1.name(), row_vector2.name())) + sage: matrix_from_row_vec 1. 2. 3. 3. 2. 1. - sage: column_vector1 = scilab('[1;3]') # optional - scilab - sage: column_vector2 = scilab('[2;8]') # optional - scilab - sage: matrix_from_col_vec = scilab('[%s %s]'%(column_vector1.name(), column_vector2.name())) # optional - scilab - sage: matrix_from_col_vec # optional - scilab + sage: # optional - scilab + sage: column_vector1 = scilab('[1;3]') + sage: column_vector2 = scilab('[2;8]') + sage: matrix_from_col_vec = scilab('[%s %s]'%(column_vector1.name(), column_vector2.name())) + sage: matrix_from_col_vec 1. 2. 3. 8. @@ -90,12 +95,13 @@ sage: tm # optional - scilab 0.5 2.5 4.5 6.5 8.5 - sage: my_vector1 = scilab('[1,5,7]') # optional - scilab - sage: my_vector1(1) # optional - scilab + sage: # optional - scilab + sage: my_vector1 = scilab('[1,5,7]') + sage: my_vector1(1) 1. - sage: my_vector1(2) # optional - scilab + sage: my_vector1(2) 5. - sage: my_vector1(3) # optional - scilab + sage: my_vector1(3) 7. Matrix indexing works as follows:: @@ -113,15 +119,16 @@ Setting using parenthesis cannot work (because of how the Python language works). Use square brackets or the set function:: - sage: my_matrix = scilab('[8, 12, 19; 7, 3, 2; 12, 4, 23; 8, 1, 1]') # optional - scilab - sage: my_matrix.set(2,3, 1999) # optional - scilab - sage: my_matrix # optional - scilab + sage: # optional - scilab + sage: my_matrix = scilab('[8, 12, 19; 7, 3, 2; 12, 4, 23; 8, 1, 1]') + sage: my_matrix.set(2,3, 1999) + sage: my_matrix 8. 12. 19. 7. 3. 1999. 12. 4. 23. 8. 1. 1. - sage: my_matrix[2,3] = -126 # optional - scilab - sage: my_matrix # optional - scilab + sage: my_matrix[2,3] = -126 + sage: my_matrix 8. 12. 19. 7. 3. - 126. 12. 4. 23. @@ -129,39 +136,40 @@ TESTS:: - sage: M = scilab(x) # optional - scilab + sage: # optional - scilab + sage: M = scilab(x) Traceback (most recent call last): ... TypeError: ..._interface_init_() takes exactly one argument (0 given) - sage: M = scilab(matrix(3,range(9))); M # optional - scilab + sage: M = scilab(matrix(3,range(9))); M 0. 1. 2. 3. 4. 5. 6. 7. 8. - sage: M(10) # optional - scilab + sage: M(10) Traceback (most recent call last): ... TypeError: Error executing code in Scilab ... Invalid index. - sage: M[10] # optional - scilab + sage: M[10] Traceback (most recent call last): ... TypeError: Error executing code in Scilab ... Invalid index. - sage: M(4,2) # optional - scilab + sage: M(4,2) Traceback (most recent call last): ... TypeError: Error executing code in Scilab ... Invalid index. - sage: M[2,4] # optional - scilab + sage: M[2,4] Traceback (most recent call last): ... TypeError: Error executing code in Scilab ... Invalid index. - sage: M(9) = x # optional - scilab + sage: M(9) = x Traceback (most recent call last): ... SyntaxError: can...t assign to function call (..., line 1) @@ -199,10 +207,11 @@ class Scilab(Expect): EXAMPLES:: - sage: a = scilab('[ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]') # optional - scilab - sage: b = scilab('[ 1; 3; 13]') # optional - scilab - sage: c = a * b # optional - scilab - sage: print(c) # optional - scilab + sage: # optional - scilab + sage: a = scilab('[ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]') + sage: b = scilab('[ 1; 3; 13]') + sage: c = a * b + sage: print(c) 30. 122. 505. @@ -433,12 +442,13 @@ def __getitem__(self, n): EXAMPLES:: - sage: M = scilab('[1,2,3;4,5,6;7,8,9]') # optional - scilab - sage: M[1] # optional - scilab + sage: # optional - scilab + sage: M = scilab('[1,2,3;4,5,6;7,8,9]') + sage: M[1] 1. - sage: M[7] # optional - scilab + sage: M[7] 3. - sage: M[3,2] # optional - scilab + sage: M[3,2] 8. """ if isinstance(n, tuple): @@ -453,14 +463,15 @@ def __setitem__(self, n, value): EXAMPLES:: - sage: M = scilab('[1,2,3;4,5,6;7,8,9]') # optional - scilab - sage: M[6] = 0 # optional - scilab - sage: M # optional - scilab + sage: # optional - scilab + sage: M = scilab('[1,2,3;4,5,6;7,8,9]') + sage: M[6] = 0 + sage: M 1. 2. 3. 4. 5. 6. 7. 0. 9. - sage: M[3,2] = 10 # optional - scilab - sage: M # optional - scilab + sage: M[3,2] = 10 + sage: M 1. 2. 3. 4. 5. 6. 7. 10. 9. @@ -477,12 +488,13 @@ def _matrix_(self, R): EXAMPLES:: - sage: A = scilab('[1,2;3,4]') # optional - scilab - sage: matrix(ZZ, A) # optional - scilab + sage: # optional - scilab + sage: A = scilab('[1,2;3,4]') + sage: matrix(ZZ, A) [1 2] [3 4] - sage: A = scilab('[1,2;3,4.5]') # optional - scilab - sage: matrix(RR, A) # optional - scilab + sage: A = scilab('[1,2;3,4.5]') + sage: matrix(RR, A) [1.00000000000000 2.00000000000000] [3.00000000000000 4.50000000000000] """ From 0bff9f67fb2edf548df86b5b2c3c8474be73c045 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 3 Sep 2023 15:31:22 -0700 Subject: [PATCH 333/463] Fix # needs for sagemath-pari --- src/sage/interfaces/gp.py | 24 +++++++++++++----------- src/sage/interfaces/macaulay2.py | 8 -------- src/sage/interfaces/maple.py | 16 ---------------- 3 files changed, 13 insertions(+), 35 deletions(-) diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index 6e12504e829..cfea368fc02 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -789,26 +789,27 @@ def new_with_bits_prec(self, s, precision=0): EXAMPLES:: - sage: pi_def = gp(pi); pi_def # needs sage.symbolic + sage: # needs sage.symbolic + sage: pi_def = gp(pi); pi_def 3.141592653589793238462643383 # 32-bit 3.1415926535897932384626433832795028842 # 64-bit - sage: pi_def.precision() # needs sage.symbolic + sage: pi_def.precision() 28 # 32-bit 38 # 64-bit - sage: pi_150 = gp.new_with_bits_prec(pi, 150) # needs sage.symbolic - sage: new_prec = pi_150.precision(); new_prec # needs sage.symbolic + sage: pi_150 = gp.new_with_bits_prec(pi, 150) + sage: new_prec = pi_150.precision(); new_prec 48 # 32-bit 57 # 64-bit - sage: old_prec = gp.set_precision(new_prec); old_prec # needs sage.symbolic + sage: old_prec = gp.set_precision(new_prec); old_prec 28 # 32-bit 38 # 64-bit - sage: pi_150 # needs sage.symbolic + sage: pi_150 3.14159265358979323846264338327950288419716939938 # 32-bit 3.14159265358979323846264338327950288419716939937510582098 # 64-bit - sage: gp.set_precision(old_prec) # needs sage.symbolic + sage: gp.set_precision(old_prec) 48 # 32-bit 57 # 64-bit - sage: gp.get_precision() # needs sage.symbolic + sage: gp.get_precision() 28 # 32-bit 38 # 64-bit """ @@ -957,11 +958,12 @@ def _complex_mpfr_field_(self, CC): EXAMPLES:: - sage: z = gp(SR(1+15*I)); z # needs sage.symbolic + sage: # needs sage.symbolic + sage: z = gp(SR(1+15*I)); z 1 + 15*I - sage: z._complex_mpfr_field_(CC) # needs sage.symbolic + sage: z._complex_mpfr_field_(CC) 1.00000000000000 + 15.0000000000000*I - sage: CC(z) # CC(gp(1+15*I)) # needs sage.symbolic + sage: CC(z) # CC(gp(1+15*I)) 1.00000000000000 + 15.0000000000000*I sage: CC(gp(11243.9812+15*I)) 11243.9812000000 + 15.0000000000000*I diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index e8a4d94d2dc..9b11f02a85f 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -496,11 +496,7 @@ def _contains(self, v1, v2): sage: 0 in a, 2 in a, 3 in a (True, True, False) sage: b = macaulay2('hashTable {"x" => 1, "y" => 2}') -<<<<<<< HEAD sage: 'x' in b, '"x"' in b # indirect doctest -======= - sage: 'x' in b, '"x"' in b ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) (False, True) """ return self.eval("%s#?%s" % (v2, v1)) == self._true_symbol() @@ -649,11 +645,7 @@ def cputime(self, t=None): sage: R = macaulay2("QQ[x,y]") sage: x,y = R.gens() sage: a = (x+y+1)^20 -<<<<<<< HEAD sage: macaulay2.cputime() # random -======= - sage: macaulay2.cputime() ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.48393700000000001 """ _t = float(self.cpuTime()._sage_()) diff --git a/src/sage/interfaces/maple.py b/src/sage/interfaces/maple.py index 1f4f209f127..7ba21a66cf6 100644 --- a/src/sage/interfaces/maple.py +++ b/src/sage/interfaces/maple.py @@ -605,20 +605,12 @@ def cputime(self, t=None): sage: # optional - maple sage: t = maple.cputime() -<<<<<<< HEAD sage: t # random -======= - sage: t ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.02 sage: x = maple('x') sage: maple.diff(x^2, x) 2*x -<<<<<<< HEAD sage: maple.cputime(t) # random -======= - sage: maple.cputime(t) ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 0.0 """ if t is None: @@ -818,11 +810,7 @@ def with_package(self, package): :: sage: # optional - maple -<<<<<<< HEAD sage: maple.quit() # reset maple -======= - sage: maple.quit() ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) sage: maple('partition(10)') partition(10) sage: maple('bell(10)') @@ -959,11 +947,7 @@ def __hash__(self): sage: # optional - maple sage: m = maple('x^2+y^2') -<<<<<<< HEAD sage: m.__hash__() # random -======= - sage: m.__hash__() ->>>>>>> a24a77aaaa1 (src/sage/interfaces: sage -fixdoctests --only-tags) 188724254834261060184983038723355865733 sage: hash(m) # random 5035731711831192733 From 20b960d3f1146954aee3d35eb2ccfd5b5364d67c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 3 Sep 2023 23:46:22 -0700 Subject: [PATCH 334/463] Add # needs --- src/sage/interfaces/sympy_wrapper.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/interfaces/sympy_wrapper.py b/src/sage/interfaces/sympy_wrapper.py index 792d1eaee99..5ad6095a787 100644 --- a/src/sage/interfaces/sympy_wrapper.py +++ b/src/sage/interfaces/sympy_wrapper.py @@ -97,6 +97,7 @@ def is_finite_set(self): EXAMPLES:: + sage: # needs sage.graphs sage: W = WeylGroup(["A",1,1]) sage: sW = W._sympy_(); sW SageSet(Weyl Group of type ['A', 1, 1] (as a matrix group acting on the root space)) @@ -112,6 +113,7 @@ def is_iterable(self): EXAMPLES:: + sage: # needs sage.graphs sage: W = WeylGroup(["A",1,1]) sage: sW = W._sympy_(); sW SageSet(Weyl Group of type ['A', 1, 1] (as a matrix group acting on the root space)) @@ -168,6 +170,7 @@ def __len__(self): EXAMPLES:: + sage: # needs sage.graphs sage: sB3 = WeylGroup(["B", 3])._sympy_(); sB3 SageSet(Weyl Group of type ['B', 3] (as a matrix group acting on the ambient space)) sage: len(sB3) From cd3543c487bad25aeed09b1141d10a64cfcb3302 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 11:21:51 -0700 Subject: [PATCH 335/463] Update # needs --- src/sage/interfaces/gp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index cfea368fc02..4cff85207e2 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -887,6 +887,7 @@ def _sage_(self): :: + sage: # needs sage.modules sage: M = Matrix(ZZ,2,2,[1,2,3,4]); M [1 2] [3 4] From f4999b0d69f1f64d8974cbbf624398ae8409cdcd Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 26 Jun 2023 12:41:10 +0100 Subject: [PATCH 336/463] more distros for fricas --- build/pkgs/fricas/distros/debian.txt | 1 + build/pkgs/fricas/distros/freebsd.txt | 1 + build/pkgs/fricas/distros/gentoo.txt | 1 + build/pkgs/fricas/distros/opensuse.txt | 1 + 4 files changed, 4 insertions(+) create mode 100644 build/pkgs/fricas/distros/debian.txt create mode 100644 build/pkgs/fricas/distros/freebsd.txt create mode 100644 build/pkgs/fricas/distros/gentoo.txt create mode 100644 build/pkgs/fricas/distros/opensuse.txt diff --git a/build/pkgs/fricas/distros/debian.txt b/build/pkgs/fricas/distros/debian.txt new file mode 100644 index 00000000000..ab59e032f00 --- /dev/null +++ b/build/pkgs/fricas/distros/debian.txt @@ -0,0 +1 @@ +fricas diff --git a/build/pkgs/fricas/distros/freebsd.txt b/build/pkgs/fricas/distros/freebsd.txt new file mode 100644 index 00000000000..75e565427a2 --- /dev/null +++ b/build/pkgs/fricas/distros/freebsd.txt @@ -0,0 +1 @@ +math/fricas diff --git a/build/pkgs/fricas/distros/gentoo.txt b/build/pkgs/fricas/distros/gentoo.txt new file mode 100644 index 00000000000..ce3f503e6db --- /dev/null +++ b/build/pkgs/fricas/distros/gentoo.txt @@ -0,0 +1 @@ +sci-mathematics/fricas[sbcl] diff --git a/build/pkgs/fricas/distros/opensuse.txt b/build/pkgs/fricas/distros/opensuse.txt new file mode 100644 index 00000000000..ab59e032f00 --- /dev/null +++ b/build/pkgs/fricas/distros/opensuse.txt @@ -0,0 +1 @@ +fricas From 21ab2c7e083308736386ddf302e7618f8c623a57 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 26 Jun 2023 16:48:23 +0100 Subject: [PATCH 337/463] spkg-configure for fricas --- build/pkgs/fricas/spkg-configure.m4 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 build/pkgs/fricas/spkg-configure.m4 diff --git a/build/pkgs/fricas/spkg-configure.m4 b/build/pkgs/fricas/spkg-configure.m4 new file mode 100644 index 00000000000..0c26e9ab71a --- /dev/null +++ b/build/pkgs/fricas/spkg-configure.m4 @@ -0,0 +1,17 @@ +SAGE_SPKG_CONFIGURE( + [fricas], [ + AC_CACHE_CHECK([for FriCAS >= 1.3.8], [ac_cv_path_FRICAS], [ + AC_PATH_PROGS_FEATURE_CHECK([FRICAS], [fricas], [ + fricas_version=`$ac_path_FRICAS -nox -noclef -eval ")quit" | grep Version | tail -1 2>&1 \ + | $SED -n -e 's/.* Version: FriCAS //p'` + echo "$fricas_version" + AS_IF([test -n "$fricas_version"], [ + AX_COMPARE_VERSION([$fricas_version], [ge], [1.3.8], [ + ac_cv_path_FRICAS="$ac_path_FRICAS" + ac_path_FRICAS_found=: + ]) + ]) + ]) + ]) + AS_IF([test -z "$ac_cv_path_FRICAS"], [sage_spkg_install_fricas=yes]) +]) From 467eff91d7d826c722069fc0b50be73dba33794a Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Tue, 27 Jun 2023 12:59:31 +0100 Subject: [PATCH 338/463] remove debugging echo --- build/pkgs/fricas/spkg-configure.m4 | 1 - 1 file changed, 1 deletion(-) diff --git a/build/pkgs/fricas/spkg-configure.m4 b/build/pkgs/fricas/spkg-configure.m4 index 0c26e9ab71a..2eaf39af158 100644 --- a/build/pkgs/fricas/spkg-configure.m4 +++ b/build/pkgs/fricas/spkg-configure.m4 @@ -4,7 +4,6 @@ SAGE_SPKG_CONFIGURE( AC_PATH_PROGS_FEATURE_CHECK([FRICAS], [fricas], [ fricas_version=`$ac_path_FRICAS -nox -noclef -eval ")quit" | grep Version | tail -1 2>&1 \ | $SED -n -e 's/.* Version: FriCAS //p'` - echo "$fricas_version" AS_IF([test -n "$fricas_version"], [ AX_COMPARE_VERSION([$fricas_version], [ge], [1.3.8], [ ac_cv_path_FRICAS="$ac_path_FRICAS" From 6ed8cb040b47344dcbe1a2a5eb19426142299952 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 30 Jun 2023 10:48:50 +0100 Subject: [PATCH 339/463] do not insist on sbcl --- build/pkgs/fricas/distros/gentoo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/fricas/distros/gentoo.txt b/build/pkgs/fricas/distros/gentoo.txt index ce3f503e6db..e6cab7611fc 100644 --- a/build/pkgs/fricas/distros/gentoo.txt +++ b/build/pkgs/fricas/distros/gentoo.txt @@ -1 +1 @@ -sci-mathematics/fricas[sbcl] +sci-mathematics/fricas From 2fd6098f974393c7cacfe4f7ba3f2067703e05ed Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 30 Jun 2023 16:20:19 +0100 Subject: [PATCH 340/463] modify the way to send )quit to fricas This is needed as SBCL-built FriCAS does not output anything if )quit is passed via -eval option, as opposed to ECL-built FriCAS. --- build/pkgs/fricas/spkg-configure.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/fricas/spkg-configure.m4 b/build/pkgs/fricas/spkg-configure.m4 index 2eaf39af158..905859f6a95 100644 --- a/build/pkgs/fricas/spkg-configure.m4 +++ b/build/pkgs/fricas/spkg-configure.m4 @@ -2,7 +2,7 @@ SAGE_SPKG_CONFIGURE( [fricas], [ AC_CACHE_CHECK([for FriCAS >= 1.3.8], [ac_cv_path_FRICAS], [ AC_PATH_PROGS_FEATURE_CHECK([FRICAS], [fricas], [ - fricas_version=`$ac_path_FRICAS -nox -noclef -eval ")quit" | grep Version | tail -1 2>&1 \ + fricas_version=`echo ")quit" | $ac_path_FRICAS -nox -noclef | grep Version | tail -1 2>&1 \ | $SED -n -e 's/.* Version: FriCAS //p'` AS_IF([test -n "$fricas_version"], [ AX_COMPARE_VERSION([$fricas_version], [ge], [1.3.8], [ From ba633413ef0d40e52a63ab1cb52c98f75896a581 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 1 Jul 2023 17:52:07 +0100 Subject: [PATCH 341/463] updated design of feature --- src/sage/features/fricas.py | 65 +++++++++++++++++++++++++++++++++++ src/sage/interfaces/fricas.py | 10 ++++-- 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/sage/features/fricas.py diff --git a/src/sage/features/fricas.py b/src/sage/features/fricas.py new file mode 100644 index 00000000000..0d22073ae73 --- /dev/null +++ b/src/sage/features/fricas.py @@ -0,0 +1,65 @@ +r""" +Features for testing the presence of ``fricas`` +""" + +# ***************************************************************************** +# Copyright (C) 2023 Dima Pasechnik +# +# 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/ +# ***************************************************************************** + +import os +import subprocess +from . import Executable, FeatureTestResult + +class FriCAS(Executable): + r""" + A :class:`~sage.features.Feature` which checks for the :ref:`fricas ` binary. + + EXAMPLES:: + + sage: from sage.features.fricas import FriCAS + sage: FriCAS().is_present() # optional - fricas + FeatureTestResult('fricas', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.fricas import FriCAS + sage: isinstance(FriCAS(), FriCAS) + True + """ + Executable.__init__(self, name="fricas", spkg="fricas", + executable="fricas", + url="https://fricas.github.io") + + def is_functional(self): + r""" + Check whether ``fricas`` works on trivial input. + + EXAMPLES:: + + sage: from sage.features.fricas import FriCAS + sage: FriCAS().is_functional() # optional - fricas + FeatureTestResult('fricas', True) + """ + command = ['fricas -nosman -eval ")quit"'] + try: + lines = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) + except subprocess.CalledProcessError as e: + return FeatureTestResult(self, False, + reason="Call `{command}` failed with exit code {e.returncode}".format(command=" ".join(command), e=e)) + + expected = b"Checking" + if lines.find(expected) == -1: + return FeatureTestResult(self, False, + reason="Call `{command}` did not produce output which contains `{expected}`".format(command=" ".join(command), expected=expected)) + + return FeatureTestResult(self, True) + +def all_features(): + return [FriCAS()] diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index c19feb3a7e5..10384b496b1 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -264,9 +264,9 @@ class FriCAS(ExtraTabCompletion, Expect): """ Interface to a FriCAS interpreter. """ - def __init__(self, name='fricas', command='fricas -nosman', + def __init__(self, name='fricas', command=None, script_subdirectory=None, logfile=None, - server=None, server_tmpdir=None): + server=None, server_tmpdir=None, options=""): """ Create an instance of the FriCAS interpreter. @@ -289,6 +289,12 @@ def __init__(self, name='fricas', command='fricas -nosman', sage: fricas(I*x).sage() # optional - fricas I*x """ + from sage.features.fricas import FriCAS + FriCAS().require() + options =" -nosman" + options + import shlex + command = '{} {}'.format(shlex.quote(FriCAS().absolute_filename()), options) + eval_using_file_cutoff = 4096 - 5 # magic number from Expect._eval_line (there might be a bug) assert max(len(c) for c in FRICAS_INIT_CODE) < eval_using_file_cutoff self.__eval_using_file_cutoff = eval_using_file_cutoff From 77b1e7ace17892843df4644be9ebe99be89a1699 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 1 Jul 2023 22:45:10 +0100 Subject: [PATCH 342/463] better string to match (for various lisps) --- src/sage/features/fricas.py | 2 +- src/sage/interfaces/fricas.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/features/fricas.py b/src/sage/features/fricas.py index 0d22073ae73..a52e082d114 100644 --- a/src/sage/features/fricas.py +++ b/src/sage/features/fricas.py @@ -54,7 +54,7 @@ def is_functional(self): return FeatureTestResult(self, False, reason="Call `{command}` failed with exit code {e.returncode}".format(command=" ".join(command), e=e)) - expected = b"Checking" + expected = b"FriCAS" if lines.find(expected) == -1: return FeatureTestResult(self, False, reason="Call `{command}` did not produce output which contains `{expected}`".format(command=" ".join(command), expected=expected)) diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index 10384b496b1..f568dd6e53f 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -291,7 +291,7 @@ def __init__(self, name='fricas', command=None, """ from sage.features.fricas import FriCAS FriCAS().require() - options =" -nosman" + options + options ="-nosman" + options import shlex command = '{} {}'.format(shlex.quote(FriCAS().absolute_filename()), options) From 43c85c8381881f9c4cbb52d36c49ba06890921e9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 13:59:51 -0800 Subject: [PATCH 343/463] src/sage/interfaces/fricas.py: Use file-level doctest tag --- src/sage/interfaces/fricas.py | 354 +++++++++++++++++----------------- 1 file changed, 172 insertions(+), 182 deletions(-) diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index f568dd6e53f..ab03a7e0b19 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - fricas r""" Interface to FriCAS @@ -21,62 +22,62 @@ EXAMPLES:: - sage: fricas('3 * 5') # optional - fricas + sage: fricas('3 * 5') 15 - sage: a = fricas(3) * fricas(5); a # optional - fricas + sage: a = fricas(3) * fricas(5); a 15 The type of a is :class:`FriCASElement`, i.e., an element of the FriCAS interpreter:: - sage: type(a) # optional - fricas + sage: type(a) - sage: a.parent() # optional - fricas + sage: a.parent() FriCAS The underlying FriCAS type of a is also available, via the type method:: - sage: a.typeOf() # optional - fricas + sage: a.typeOf() PositiveInteger FriCAS objects are normally displayed using "ASCII art":: - sage: fricas(2/3) # optional - fricas + sage: fricas(2/3) 2 - 3 - sage: fricas('x^2 + 3/7') # optional - fricas + sage: fricas('x^2 + 3/7') 2 3 x + - 7 Functions defined in FriCAS are available as methods of the :class:`fricas` object:: - sage: F = fricas.factor('x^5 - y^5'); F # optional - fricas + sage: F = fricas.factor('x^5 - y^5'); F 4 3 2 2 3 4 - (y - x)(y + x y + x y + x y + x ) - sage: type(F) # optional - fricas + sage: type(F) - sage: F.typeOf() # optional - fricas + sage: F.typeOf() Factored(Polynomial(Integer)) We can also create a FriCAS polynomial and apply the function ``factor`` from FriCAS. The notation ``f.factor()`` is consistent with how the rest of SageMath works:: - sage: f = fricas('x^5 - y^5') # optional - fricas - sage: f^2 # optional - fricas + sage: f = fricas('x^5 - y^5') + sage: f^2 10 5 5 10 y - 2 x y + x - sage: f.factor() # optional - fricas + sage: f.factor() 4 3 2 2 3 4 - (y - x)(y + x y + x y + x y + x ) For many FriCAS types, translation to an appropriate SageMath type is available:: - sage: f.factor().sage() # optional - fricas + sage: f.factor().sage() (y - x) * (y^4 + y^3*x + y^2*x^2 + y*x^3 + x^4) Control-C interruption works well with the FriCAS interface. For @@ -92,7 +93,7 @@ differential equation for the generating function for integer partitions:: - sage: fricas("guessADE([partition n for n in 0..40], homogeneous==4)") # optional - fricas + sage: fricas("guessADE([partition n for n in 0..40], homogeneous==4)") [ [ n @@ -121,9 +122,9 @@ FriCAS can solve linear ordinary differential equations:: - sage: fricas.set("y", "operator y") # optional - fricas - sage: fricas.set("deq", "x^3*D(y x, x, 3) + x^2*D(y x, x, 2) - 2*x*D(y x, x) + 2*y x - 2*x^4") # optional - fricas - sage: fricas.set("sol", "solve(deq, y, x)"); fricas("sol") # optional - fricas + sage: fricas.set("y", "operator y") + sage: fricas.set("deq", "x^3*D(y x, x, 3) + x^2*D(y x, x, 2) - 2*x*D(y x, x) + 2*y x - 2*x^4") + sage: fricas.set("sol", "solve(deq, y, x)"); fricas("sol") 5 3 2 x - 10 x + 20 x + 4 [particular = ----------------------, @@ -133,36 +134,36 @@ basis = [---------------, ------, -------------]] x x x - sage: fricas("sol.particular").sage() # optional - fricas + sage: fricas("sol.particular").sage() 1/15*(x^5 - 10*x^3 + 20*x^2 + 4)/x - sage: fricas("sol.basis").sage() # optional - fricas + sage: fricas("sol.basis").sage() [(2*x^3 - 3*x^2 + 1)/x, (x^3 - 1)/x, (x^3 - 3*x^2 - 1)/x] - sage: fricas.eval(")clear values y deq sol") # optional - fricas + sage: fricas.eval(")clear values y deq sol") '' FriCAS can expand expressions into series:: - sage: x = var('x'); ex = sqrt(cos(x)); a = fricas(ex).series(x=0); a # optional - fricas + sage: x = var('x'); ex = sqrt(cos(x)); a = fricas(ex).series(x=0); a 1 2 1 4 19 6 559 8 29161 10 11 1 - - x - -- x - ---- x - ------ x - --------- x + O(x ) 4 96 5760 645120 116121600 - sage: a.coefficients()[38].sage() # optional - fricas + sage: a.coefficients()[38].sage() -29472026335337227150423659490832640468979/274214482066329363682430667508979749984665600000000 - sage: ex = sqrt(atan(x)); a = fricas(ex).series(x=0); a # optional - fricas + sage: ex = sqrt(atan(x)); a = fricas(ex).series(x=0); a 1 5 9 - - - 2 1 2 31 2 6 x - - x + --- x + O(x ) 6 360 - sage: a.coefficient(9/2).sage() # optional - fricas + sage: a.coefficient(9/2).sage() 31/360 - sage: x = fricas("x::TaylorSeries Fraction Integer") # optional - fricas - sage: y = fricas("y::TaylorSeries Fraction Integer") # optional - fricas - sage: 2*(1+2*x+sqrt(1-4*x)-2*x*y).recip() # optional - fricas + sage: x = fricas("x::TaylorSeries Fraction Integer") + sage: y = fricas("y::TaylorSeries Fraction Integer") + sage: 2*(1+2*x+sqrt(1-4*x)-2*x*y).recip() 2 3 2 2 3 4 4 5 1 + (x y + x ) + 2 x + (x y + 2 x y + 6 x ) + (4 x y + 18 x ) + @@ -180,7 +181,7 @@ FriCAS does some limits right:: - sage: x = var('x'); ex = x^2*exp(-x)*Ei(x) - x; fricas(ex).limit(x=oo) # optional - fricas + sage: x = var('x'); ex = x^2*exp(-x)*Ei(x) - x; fricas(ex).limit(x=oo) 1 """ @@ -272,21 +273,21 @@ def __init__(self, name='fricas', command=None, TESTS:: - sage: fricas == loads(dumps(fricas)) # optional - fricas + sage: fricas == loads(dumps(fricas)) True Check that :trac:`25174` is fixed:: - sage: fricas(I) # optional - fricas + sage: fricas(I) %i - sage: integrate(sin(x)*exp(I*x), x, -pi, 0, algorithm="fricas") # optional - fricas + sage: integrate(sin(x)*exp(I*x), x, -pi, 0, algorithm="fricas") 1/2*I*pi - sage: fricas(I*sin(x)).sage() # optional - fricas + sage: fricas(I*sin(x)).sage() I*sin(x) - sage: fricas(I*x).sage() # optional - fricas + sage: fricas(I*x).sage() I*x """ from sage.features.fricas import FriCAS @@ -319,7 +320,6 @@ def _start(self): EXAMPLES:: - sage: # optional - fricas sage: a = FriCAS() sage: a.is_running() False @@ -363,7 +363,6 @@ def _quit_string(self): EXAMPLES:: - sage: # optional - fricas sage: fricas._quit_string() ')quit' sage: a = FriCAS() @@ -380,9 +379,9 @@ def _quit_string(self): Ensure that a new process is started after ``quit()``:: - sage: p = fricas.pid() # optional - fricas - sage: fricas.quit() # optional - fricas - sage: fricas.pid() == p # optional - fricas + sage: p = fricas.pid() + sage: fricas.quit() + sage: fricas.pid() == p False """ @@ -395,7 +394,6 @@ def _commands(self): EXAMPLES:: - sage: # optional - fricas sage: cmds = fricas._commands() sage: len(cmds) > 100 True @@ -417,7 +415,6 @@ def _tab_completion(self, verbose=True, use_disk_cache=True): EXAMPLES:: - sage: # optional - fricas sage: c = fricas._tab_completion(use_disk_cache=False, verbose=False) sage: len(c) > 100 True @@ -479,7 +476,7 @@ def _read_in_file_command(self, filename): Evaluate a rather long line:: - sage: len(fricas([i for i in range(600)])) # optional - fricas, indirect doctest + sage: len(fricas([i for i in range(600)])) # indirect doctest 600 """ @@ -531,7 +528,7 @@ def _check_errors(self, line, output): TESTS:: - sage: fricas.set("x", "[i fo83r i in 0..17]") # optional - fricas, indirect doctest + sage: fricas.set("x", "[i fo83r i in 0..17]") # indirect doctest Traceback (most recent call last): ... RuntimeError: An error occurred when FriCAS evaluated '[i fo83r i in 0..17]': @@ -542,7 +539,7 @@ def _check_errors(self, line, output): Error B: Possibly missing a ] 3 error(s) parsing - sage: fricas.set("x", "something stupid") # optional - fricas, indirect doctest + sage: fricas.set("x", "something stupid") # indirect doctest Traceback (most recent call last): ... RuntimeError: An error occurred when FriCAS evaluated 'something stupid': @@ -668,8 +665,8 @@ def set(self, var, value): EXAMPLES:: - sage: fricas.set('xx', '2') # optional - fricas - sage: fricas.get('xx') # optional - fricas + sage: fricas.set('xx', '2') + sage: fricas.get('xx') '2' """ @@ -686,7 +683,6 @@ def get(self, var): EXAMPLES:: - sage: # optional - fricas sage: fricas.set('xx', '2') sage: fricas.get('xx') '2' @@ -721,25 +717,24 @@ def get_string(self, var): We test that strings are returned properly:: - sage: r = fricas.get_string('concat([concat(string(i)," ") for i in 0..299])') # optional - fricas - sage: r == " ".join(str(i) for i in range(300)) + ' ' # optional - fricas + sage: r = fricas.get_string('concat([concat(string(i)," ") for i in 0..299])') + sage: r == " ".join(str(i) for i in range(300)) + ' ' True - sage: fricas.get_string('concat([string(1) for i in 1..5])') == "1"*5 # optional - fricas + sage: fricas.get_string('concat([string(1) for i in 1..5])') == "1"*5 True - sage: fricas.get_string('concat([string(1) for i in 1..10000])') == "1"*10000 # optional - fricas + sage: fricas.get_string('concat([string(1) for i in 1..10000])') == "1"*10000 True A problem with leading space:: sage: s = "unparse((-1234567890123456789012345678901234567890123456789012345678901234567890*n::EXPR INT)::INFORM)" - sage: fricas.get_string(s) # optional - fricas + sage: fricas.get_string(s) '(-1234567890123456789012345678901234567890123456789012345678901234567890)*n' Check that :trac:`25628` is fixed:: - sage: # optional - fricas sage: var("a b"); f = 1/(1+a*cos(x)) (a, b) sage: lF = integrate(f, x, algorithm="fricas") @@ -768,7 +763,7 @@ def get_integer(self, var): TESTS:: - sage: fricas.get_integer('factorial 1111') == factorial(1111) # optional - fricas + sage: fricas.get_integer('factorial 1111') == factorial(1111) True """ @@ -781,10 +776,10 @@ def get_boolean(self, var): TESTS:: - sage: fricas.get_boolean('(1=1)::Boolean') == True # optional - fricas + sage: fricas.get_boolean('(1=1)::Boolean') == True True - sage: fricas.get_boolean('(1=2)::Boolean') == False # optional - fricas + sage: fricas.get_boolean('(1=2)::Boolean') == False True """ return self.get(str(var)).replace("\n", "") == "true" @@ -805,7 +800,7 @@ def get_unparsed_InputForm(self, var): TESTS:: - sage: fricas.get_unparsed_InputForm('1..3') # optional - fricas + sage: fricas.get_unparsed_InputForm('1..3') '(1..3)$Segment(PositiveInteger())' """ @@ -817,7 +812,7 @@ def get_InputForm(self, var): TESTS:: - sage: fricas.get_InputForm('1..3') # optional - fricas + sage: fricas.get_InputForm('1..3') '(($elt (Segment (PositiveInteger)) SEGMENT) 1 3)' """ @@ -829,10 +824,10 @@ def _assign_symbol(self): EXAMPLES:: - sage: fricas.set("x", "1"); # optional - fricas, indirect doctest - sage: fricas.get("x") # optional - fricas + sage: fricas.set("x", "1"); # indirect doctest + sage: fricas.get("x") '1' - sage: fricas.eval(")cl val x") # optional - fricas + sage: fricas.eval(")cl val x") '' """ return ":=" @@ -843,15 +838,15 @@ def _equality_symbol(self): EXAMPLES:: - sage: a = fricas(x==6); a # optional - fricas, indirect doctest + sage: a = fricas(x==6); a # indirect doctest x = 6 A warning:: - sage: fricas.set("x", 2); # optional - fricas - sage: a = fricas(x==6); a # optional - fricas + sage: fricas.set("x", 2); + sage: a = fricas(x==6); a 2 = 6 - sage: fricas.eval(")cl val x") # optional - fricas + sage: fricas.eval(")cl val x") '' """ return "=" @@ -862,7 +857,7 @@ def _true_symbol(self): EXAMPLES:: - sage: str(fricas("(1=1)@Boolean")) == fricas._true_symbol() # optional - fricas + sage: str(fricas("(1=1)@Boolean")) == fricas._true_symbol() True """ return "true" @@ -873,7 +868,7 @@ def _false_symbol(self): EXAMPLES:: - sage: str(fricas("(1~=1)@Boolean")) == fricas._false_symbol() # optional - fricas + sage: str(fricas("(1~=1)@Boolean")) == fricas._false_symbol() True """ return "false" @@ -884,7 +879,7 @@ def _inequality_symbol(self): EXAMPLES:: - sage: fricas(x!=0) # optional - fricas, indirect doctest + sage: fricas(x!=0) # indirect doctest true """ return '~=' @@ -893,7 +888,7 @@ def _repr_(self): """ EXAMPLES:: - sage: fricas # indirect doctest + sage: fricas # indirect doctest FriCAS """ return "FriCAS" @@ -926,11 +921,11 @@ def eval(self, code, strip=True, synchronize=False, locals=None, allow_use_file= EXAMPLES:: - sage: fricas.set("x", "1783"); fricas("x") # optional - fricas + sage: fricas.set("x", "1783"); fricas("x") 1783 - sage: fricas.eval(")cl val x"); # optional - fricas + sage: fricas.eval(")cl val x"); '' - sage: fricas("x") # optional - fricas + sage: fricas("x") x """ @@ -958,9 +953,9 @@ def _function_class(self): EXAMPLES:: - sage: fricas._function_class() # optional - fricas + sage: fricas._function_class() - sage: type(fricas.gcd) # optional - fricas + sage: type(fricas.gcd) """ return FriCASExpectFunction @@ -969,9 +964,9 @@ def _object_class(self): """ EXAMPLES:: - sage: fricas._object_class() # optional - fricas + sage: fricas._object_class() - sage: type(fricas(2)) # optional - fricas + sage: type(fricas(2)) """ return FriCASElement @@ -982,9 +977,9 @@ def _function_element_class(self): EXAMPLES:: - sage: fricas._function_element_class() # optional - fricas + sage: fricas._function_element_class() - sage: type(fricas(2).gcd) # optional - fricas + sage: type(fricas(2).gcd) """ return FriCASFunctionElement @@ -1024,16 +1019,16 @@ def __len__(self): EXAMPLES:: - sage: v = fricas('[x^i for i in 0..5]') # optional - fricas - sage: len(v) # optional - fricas + sage: v = fricas('[x^i for i in 0..5]') + sage: len(v) 6 TESTS: Streams are not handled yet:: - sage: oh = fricas('[i for i in 1..]') # optional - fricas - sage: len(oh) # optional - fricas + sage: oh = fricas('[i for i in 1..]') + sage: len(oh) Traceback (most recent call last): ... TypeError: ... @@ -1048,15 +1043,15 @@ def __iter__(self): EXAMPLES:: - sage: L = fricas([4,5,6]) # optional - fricas - sage: list(L) # optional - fricas + sage: L = fricas([4,5,6]) + sage: list(L) [4, 5, 6] TESTS: Streams are not handled yet:: - sage: oh = fricas('[i for i in 1..]') # optional - fricas + sage: oh = fricas('[i for i in 1..]') sage: next(iter(oh)) # known bug """ for i in range(len(self)): @@ -1071,20 +1066,20 @@ def __getitem__(self, n): TESTS:: - sage: fricas("[1,2,3]")[0] # optional - fricas + sage: fricas("[1,2,3]")[0] 1 Negative indices do work:: - sage: fricas("[1,2,3]")[-1] # optional - fricas + sage: fricas("[1,2,3]")[-1] 3 - sage: fricas("[1,2,3]")[-2] # optional - fricas + sage: fricas("[1,2,3]")[-2] 2 Invalid indices raise exceptions:: - sage: fricas("[1,2,3]")[3] # optional - fricas + sage: fricas("[1,2,3]")[3] Traceback (most recent call last): ... TypeError: An error occurred when FriCAS evaluated 'elt(...,...)': @@ -1094,8 +1089,8 @@ def __getitem__(self, n): And streams are ok too:: - sage: oh = fricas('[i for i in 1..]') # optional - fricas - sage: oh[4] # optional - fricas + sage: oh = fricas('[i for i in 1..]') + sage: oh[4] 5 """ n = int(n) @@ -1119,7 +1114,7 @@ def __int__(self): """ TESTS:: - sage: int(fricas(2)) # optional - fricas + sage: int(fricas(2)) 2 """ return int(self.sage()) @@ -1130,9 +1125,9 @@ def bool(self): EXAMPLES:: - sage: fricas("1=1").bool() # optional - fricas + sage: fricas("1=1").bool() True - sage: fricas("1~=1").bool() # optional - fricas + sage: fricas("1~=1").bool() False """ P = self._check_valid() @@ -1144,7 +1139,7 @@ def __bool__(self): EXAMPLES:: - sage: fricas(0).is_zero() # optional - fricas, indirect doctest + sage: fricas(0).is_zero() # indirect doctest True """ P = self._check_valid() @@ -1154,7 +1149,7 @@ def __float__(self): """ TESTS:: - sage: float(fricas(2)) # optional - fricas + sage: float(fricas(2)) 2.0 """ return float(self.sage()) @@ -1163,7 +1158,7 @@ def _integer_(self, ZZ=None): """ EXAMPLES:: - sage: ZZ(fricas('1')) # optional - fricas + sage: ZZ(fricas('1')) 1 """ return ZZ(self.sage()) @@ -1172,7 +1167,7 @@ def _rational_(self): """ EXAMPLES:: - sage: QQ(fricas('-1/2')) # optional - fricas + sage: QQ(fricas('-1/2')) -1/2 """ return QQ(self.sage()) @@ -1187,13 +1182,13 @@ def _latex_(self): r""" EXAMPLES:: - sage: latex(fricas("sin(x+y)/exp(z)*log(1+%e)")) # optional - fricas + sage: latex(fricas("sin(x+y)/exp(z)*log(1+%e)")) \frac{{{\log \left( {{e+1}} \right)} \ {\sin \left( {{y+x}} \right)}}}{{{e} ^{z}}} - sage: latex(fricas("matrix([[1,2],[3,4]])")) # optional - fricas + sage: latex(fricas("matrix([[1,2],[3,4]])")) \left[ \begin{array}{cc} 1 & 2 \\ 3 & 4\end{array} \right] - sage: latex(fricas("integrate(sin(x+1/x),x)")) # optional - fricas + sage: latex(fricas("integrate(sin(x+1/x),x)")) \int ^{\displaystyle x} {{\sin \left( {{\frac{{{{ \%...} ^{2}}+1}}{ \%...}}} \right)} \ {d \%...}} """ replacements = [(r'\sp ', '^'), @@ -1218,14 +1213,14 @@ def _get_sage_type(self, domain): EXAMPLES:: - sage: m = fricas("dom(1/2)::Any") # optional - fricas - sage: fricas(0)._get_sage_type(m) # optional - fricas + sage: m = fricas("dom(1/2)::Any") + sage: fricas(0)._get_sage_type(m) Rational Field TESTS:: - sage: m = fricas("UP(y, UP(x, AN))::INFORM") # optional - fricas - sage: fricas(0)._get_sage_type(m) # optional - fricas + sage: m = fricas("UP(y, UP(x, AN))::INFORM") + sage: fricas(0)._get_sage_type(m) Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Algebraic Field """ from sage.rings.qqbar import QQbar @@ -1309,7 +1304,7 @@ def _parse_and_eval(s, start=0): sage: FriCASElement._parse_and_eval("(asin c)") (arcsin(c), 7) - sage: N(FriCASElement._parse_and_eval("(pi)")[0]) # optional - fricas + sage: N(FriCASElement._parse_and_eval("(pi)")[0]) 3.14159265358979 sage: FriCASElement._parse_and_eval('(a "(b c)")') @@ -1413,7 +1408,7 @@ def _parse_other(s, start=0, make_fun=False): sage: var("D") D - sage: integrate(D/x, x, algorithm="fricas") # optional - fricas + sage: integrate(D/x, x, algorithm="fricas") D*log(x) However, it does have to check for constants, for example @@ -1503,7 +1498,7 @@ def _sage_expression(fricas_InputForm): TESTS:: - sage: f = fricas('integrate(sin(x^2), x)'); f # optional - fricas + sage: f = fricas('integrate(sin(x^2), x)'); f +---+ | 2 fresnelS(x |--- ) @@ -1513,16 +1508,16 @@ def _sage_expression(fricas_InputForm): | 2 |--- \|%pi - sage: s = fricas.get_InputForm(f._name); s # optional - fricas + sage: s = fricas.get_InputForm(f._name); s '(/ (fresnelS (* x (^ (/ 2 (pi)) (/ 1 2)))) (^ (/ 2 (pi)) (/ 1 2)))' sage: from sage.interfaces.fricas import FriCASElement - sage: FriCASElement._sage_expression(s) # optional - fricas + sage: FriCASElement._sage_expression(s) 1/2*sqrt(2)*sqrt(pi)*fresnel_sin(sqrt(2)*x/sqrt(pi)) Check that :trac:`22525` is fixed:: sage: l = [sin, cos, sec, csc, cot, tan, asin, acos, atan, acot, acsc, asec, arcsin, arccos, arctan, arccot, arccsc, arcsec] - sage: [f(x)._fricas_().sage().subs(x=0.9) for f in l] # optional - fricas + sage: [f(x)._fricas_().sage().subs(x=0.9) for f in l] [0.783326909627483, 0.621609968270664, 1.60872581046605, @@ -1542,7 +1537,7 @@ def _sage_expression(fricas_InputForm): 1.57079632679490 - 0.467145308103262*I, 0.467145308103262*I] sage: l = [tanh, sinh, cosh, coth, sech, csch, asinh, acosh, atanh, acoth, asech, acsch, arcsinh, arccosh, arctanh, arccoth, arcsech, arccsch] - sage: [f(x)._fricas_().sage().subs(x=0.9) for f in l] # optional - fricas + sage: [f(x)._fricas_().sage().subs(x=0.9) for f in l] [0.716297870199024, 1.02651672570818, 1.43308638544877, @@ -1565,67 +1560,66 @@ def _sage_expression(fricas_InputForm): Check that :trac:`23782` is fixed:: sage: s = '((3*n^10-25*n^9+50*n^8+62*n^7-229*n^6-25*n^5+320*n^4-12*n^3-144*n^2)/11520)::EXPR INT' - sage: fricas(s).sage() # optional - fricas + sage: fricas(s).sage() 1/3840*n^10 - 5/2304*n^9 + 5/1152*n^8 + 31/5760*n^7 - 229/11520*n^6 - 5/2304*n^5 + 1/36*n^4 - 1/960*n^3 - 1/80*n^2 Some checks for digamma and polygamma (:trac:`31853`):: - sage: fricas.digamma(1.0) # optional - fricas + sage: fricas.digamma(1.0) - 0.5772156649_0153286061 sage: psi(1.0) -0.577215664901533 - sage: fricas.polygamma(1, 1.0) # optional - fricas + sage: fricas.polygamma(1, 1.0) 1.644934066848226... sage: psi(1, 1).n() 1.64493406684823 sage: var("w") w - sage: fricas.laplace(log(x), x, w).sage() # optional - fricas + sage: fricas.laplace(log(x), x, w).sage() -(euler_gamma + log(w))/w - sage: fricas(laplace(log(x), x, w)).sage() # optional - fricas + sage: fricas(laplace(log(x), x, w)).sage() -(euler_gamma + log(w))/w Check that :trac:`25224` is fixed:: - sage: integrate(log(x)/(1-x),x,algorithm='fricas') # optional - fricas + sage: integrate(log(x)/(1-x),x,algorithm='fricas') dilog(-x + 1) - sage: fricas(dilog(-x + 1)) # optional - fricas + sage: fricas(dilog(-x + 1)) dilog(x) - sage: dilog._fricas_()(1.0) # optional - fricas + sage: dilog._fricas_()(1.0) 1.6449340668_4822643647_24152 sage: dilog(1.0) 1.64493406684823 Check that :trac:`25987` is fixed:: - sage: integrate(lambert_w(x), x, algorithm="fricas") # optional - fricas + sage: integrate(lambert_w(x), x, algorithm="fricas") (x*lambert_w(x)^2 - x*lambert_w(x) + x)/lambert_w(x) Check that :trac:`25838` is fixed:: sage: F = function('f'); f = SR.var('f') - sage: FF = fricas(F(f)); FF # optional - fricas + sage: FF = fricas(F(f)); FF f(f) - sage: FF.D(f).sage() # optional - fricas + sage: FF.D(f).sage() diff(f(f), f) - sage: bool(FF.D(f).integrate(f).sage() == F(f)) # optional - fricas + sage: bool(FF.D(f).integrate(f).sage() == F(f)) True Check that :trac:`25602` is fixed:: - sage: r = fricas.integrate(72000/(1+x^5),x).sage() # optional - fricas - sage: n(r.subs(x=5)-r.subs(x=3)) # optional - fricas tol 0.1 + sage: r = fricas.integrate(72000/(1+x^5), x).sage() + sage: n(r.subs(x=5) - r.subs(x=3)) # tol 0.1 193.020947266210 - sage: var("a"); r = fricas.integrate(72000*a^8/(a^5+x^5),x).sage() # optional - fricas + sage: var("a"); r = fricas.integrate(72000*a^8/(a^5+x^5), x).sage() a - sage: n(r.subs(a=1, x=5)-r.subs(a=1, x=3)) # optional - fricas tol 0.1 + sage: n(r.subs(a=1, x=5) - r.subs(a=1, x=3)) # tol 0.1 193.020947266268 - 8.73114913702011e-11*I Check conversions of sums and products:: - sage: # optional - fricas sage: var("k, m, n") (k, m, n) sage: fricas("sum(1/factorial(k), k=1..n)").sage() @@ -1635,7 +1629,7 @@ def _sage_expression(fricas_InputForm): sage: fricas("product(1/factorial(k), k=1..n)").sage() 1/product(factorial(_...), _..., 1, n) - sage: f = fricas.guess([sum(1/k, k,1,n) for n in range(10)])[0]; f # optional - fricas + sage: f = fricas.guess([sum(1/k, k,1,n) for n in range(10)])[0]; f n - 1 --+ 1 > ------- @@ -1643,10 +1637,10 @@ def _sage_expression(fricas_InputForm): s = 0 10 10 - sage: f.sage() # optional - fricas + sage: f.sage() harmonic_number(n) - sage: f = fricas.guess([0, 1, 3, 9, 33])[0]; f # optional - fricas + sage: f = fricas.guess([0, 1, 3, 9, 33])[0]; f s - 1 n - 1 5 --+ ++-++ @@ -1655,53 +1649,53 @@ def _sage_expression(fricas_InputForm): s = 0 p = 0 5 4 - sage: f.sage() # optional - fricas + sage: f.sage() sum(factorial(_... + 1), _..., 0, n - 1) Check that :trac:`26746` is fixed:: sage: _ = var('x, y, z') sage: f = sin(x^2) + y^z - sage: f.integrate(x, algorithm='fricas') # optional - fricas + sage: f.integrate(x, algorithm='fricas') 1/2*sqrt(2)*sqrt(pi)*(sqrt(2)*x*y^z/sqrt(pi) + fresnel_sin(sqrt(2)*x/sqrt(pi))) - sage: fricas(fresnel_sin(1)) # optional - fricas + sage: fricas(fresnel_sin(1)) fresnelS(1) - sage: fricas("fresnelS(1.0)") # optional - fricas + sage: fricas("fresnelS(1.0)") 0.4382591473_9035476607_676 - sage: fricas(fresnel_cos(1)) # optional - fricas + sage: fricas(fresnel_cos(1)) fresnelC(1) - sage: fricas("fresnelC(1.0)") # optional - fricas + sage: fricas("fresnelC(1.0)") 0.7798934003_7682282947_42 Check that :trac:`17908` is fixed:: - sage: fricas(abs(x)).sage().subs(x=-1783) # optional - fricas + sage: fricas(abs(x)).sage().subs(x=-1783) 1783 Check that :trac:`27310` is fixed:: - sage: fricas.set("F", "operator 'f") # optional - fricas - sage: fricas("eval(D(F(x,y), [x, y], [2, 1]), x=x+y)").sage() # optional - fricas + sage: fricas.set("F", "operator 'f") + sage: fricas("eval(D(F(x,y), [x, y], [2, 1]), x=x+y)").sage() D[0, 0, 1](f)(x + y, y) Conversion of hypergeometric functions (:trac:`31298`):: sage: a,b,c = var("a b c") sage: A = hypergeometric([a, b], [c], x) - sage: fricas(A).sage() - A # optional - fricas + sage: fricas(A).sage() - A 0 - sage: fricas(A).D(x).sage() - diff(A, x) # optional - fricas + sage: fricas(A).D(x).sage() - diff(A, x) 0 Check that :trac:`31858` is fixed:: - sage: fricas.Gamma(3/2).sage() # optional - fricas + sage: fricas.Gamma(3/2).sage() 1/2*sqrt(pi) - sage: fricas.Gamma(3/4).sage() # optional - fricas + sage: fricas.Gamma(3/4).sage() gamma(3/4) - sage: fricas.Gamma(3, 2).sage() # optional - fricas + sage: fricas.Gamma(3, 2).sage() gamma(3, 2) @@ -1709,7 +1703,7 @@ def _sage_expression(fricas_InputForm): sage: var("y") y - sage: f = fricas.zerosOf(y^4 + y + 1, y); f # optional - fricas + sage: f = fricas.zerosOf(y^4 + y + 1, y); f +-----------------------------+ | 2 2 \|- 3 %y1 - 2 %y0 %y1 - 3 %y0 - %y1 - %y0 @@ -1721,7 +1715,7 @@ def _sage_expression(fricas_InputForm): ----------------------------------------------] 2 - sage: f[1].sage() # optional - fricas + sage: f[1].sage() -1/2*sqrt(1/3)*sqrt((3*(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(2/3) + 4)/(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(1/3)) + 1/2*sqrt(-(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(1/3) + 6*sqrt(1/3)/sqrt((3*(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(2/3) + 4)/(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(1/3)) - 4/3/(1/18*I*sqrt(229)*sqrt(3) + 1/2)^(1/3)) """ @@ -1785,7 +1779,6 @@ def _sage_(self): Floats:: - sage: # optional - fricas sage: fricas(2.1234).sage() 2.12340000000000 sage: _.parent() @@ -1804,27 +1797,26 @@ def _sage_(self): Algebraic numbers:: - sage: a = fricas('(1 + sqrt(2))^5'); a # optional - fricas + sage: a = fricas('(1 + sqrt(2))^5'); a +-+ 29 \|2 + 41 - sage: b = a.sage(); b # optional - fricas + sage: b = a.sage(); b 82.0121933088198? - sage: b.radical_expression() # optional - fricas + sage: b.radical_expression() 29*sqrt(2) + 41 Integers modulo n:: - sage: fricas("((42^17)^1783)::IntegerMod(5^(5^5))").sage() == Integers(5^(5^5))((42^17)^1783) # optional - fricas + sage: fricas("((42^17)^1783)::IntegerMod(5^(5^5))").sage() == Integers(5^(5^5))((42^17)^1783) True Matrices over a prime field:: - sage: fricas("matrix [[1::PF 3, 2],[2, 0]]").sage().parent() # optional - fricas + sage: fricas("matrix [[1::PF 3, 2],[2, 0]]").sage().parent() Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 We can also convert FriCAS's polynomials to Sage polynomials:: - sage: # optional - fricas sage: a = fricas("x^2 + 1"); a.typeOf() Polynomial(Integer) sage: a.sage() @@ -1836,52 +1828,52 @@ def _sage_(self): sage: _.parent() Multivariate Polynomial Ring in y, x over Rational Field - sage: fricas("1$Polynomial Integer").sage() # optional - fricas + sage: fricas("1$Polynomial Integer").sage() 1 - sage: fricas("x^2/2").sage() # optional - fricas + sage: fricas("x^2/2").sage() 1/2*x^2 sage: x = polygen(QQ, 'x') - sage: fricas(x+3).sage() # optional - fricas + sage: fricas(x+3).sage() x + 3 - sage: fricas(x+3).domainOf() # optional - fricas + sage: fricas(x+3).domainOf() Polynomial(Integer()) - sage: fricas(matrix([[2,3],[4,x+5]])).diagonal().sage() # optional - fricas + sage: fricas(matrix([[2,3],[4,x+5]])).diagonal().sage() (2, x + 5) - sage: f = fricas("(y^2+3)::UP(y, INT)").sage(); f # optional - fricas + sage: f = fricas("(y^2+3)::UP(y, INT)").sage(); f y^2 + 3 - sage: f.parent() # optional - fricas + sage: f.parent() Univariate Polynomial Ring in y over Integer Ring - sage: fricas("(y^2+sqrt 3)::UP(y, AN)").sage() # optional - fricas + sage: fricas("(y^2+sqrt 3)::UP(y, AN)").sage() y^2 + 1.732050807568878? Rational functions:: - sage: fricas("x^2 + 1/z").sage() # optional - fricas + sage: fricas("x^2 + 1/z").sage() x^2 + 1/z Expressions:: - sage: fricas(pi).sage() # optional - fricas + sage: fricas(pi).sage() pi - sage: fricas("sin(x+y)/exp(z)*log(1+%e)").sage() # optional - fricas + sage: fricas("sin(x+y)/exp(z)*log(1+%e)").sage() e^(-z)*log(e + 1)*sin(x + y) - sage: fricas("factorial(n)").sage() # optional - fricas + sage: fricas("factorial(n)").sage() factorial(n) - sage: fricas("integrate(sin(x+y), x=0..1)").sage() # optional - fricas + sage: fricas("integrate(sin(x+y), x=0..1)").sage() -cos(y + 1) + cos(y) - sage: fricas("integrate(x*sin(1/x), x=0..1)").sage() # optional - fricas + sage: fricas("integrate(x*sin(1/x), x=0..1)").sage() 'failed' - sage: fricas("integrate(sin((x^2+1)/x),x)").sage() # optional - fricas + sage: fricas("integrate(sin((x^2+1)/x),x)").sage() integral(sin((x^2 + 1)/x), x) .. TODO:: @@ -1890,7 +1882,7 @@ def _sage_(self): Matrices:: - sage: fricas("matrix [[x^n/2^m for n in 0..5] for m in 0..3]").sage() # optional - fricas, long time + sage: fricas("matrix [[x^n/2^m for n in 0..5] for m in 0..3]").sage() # long time [ 1 x x^2 x^3 x^4 x^5] [ 1/2 1/2*x 1/2*x^2 1/2*x^3 1/2*x^4 1/2*x^5] [ 1/4 1/4*x 1/4*x^2 1/4*x^3 1/4*x^4 1/4*x^5] @@ -1898,25 +1890,25 @@ def _sage_(self): Lists:: - sage: fricas("[2^n/x^n for n in 0..5]").sage() # optional - fricas, long time + sage: fricas("[2^n/x^n for n in 0..5]").sage() # long time [1, 2/x, 4/x^2, 8/x^3, 16/x^4, 32/x^5] - sage: fricas("[matrix [[i for i in 1..n]] for n in 0..5]").sage() # optional - fricas, long time + sage: fricas("[matrix [[i for i in 1..n]] for n in 0..5]").sage() # long time [[], [1], [1 2], [1 2 3], [1 2 3 4], [1 2 3 4 5]] Error handling:: - sage: s = fricas.guessPade("[fibonacci i for i in 0..10]"); s # optional - fricas + sage: s = fricas.guessPade("[fibonacci i for i in 0..10]"); s n x [[[x ]- ----------]] 2 x + x - 1 - sage: s.sage() # optional - fricas + sage: s.sage() Traceback (most recent call last): ... NotImplementedError: the translation of the FriCAS Expression 'rootOfADE' to sage is not yet implemented - sage: s = fricas("series(sqrt(1+x), x=0)"); s # optional - fricas + sage: s = fricas("series(sqrt(1+x), x=0)"); s 1 1 2 1 3 5 4 7 5 21 6 33 7 429 8 1 + - x - - x + -- x - --- x + --- x - ---- x + ---- x - ----- x 2 8 16 128 256 1024 2048 32768 @@ -1925,7 +1917,7 @@ def _sage_(self): ----- x - ------ x + O(x ) 65536 262144 - sage: s.sage() # optional - fricas + sage: s.sage() Traceback (most recent call last): ... NotImplementedError: the translation of the FriCAS object @@ -2082,7 +2074,6 @@ def __init__(self, object, name): TESTS:: - sage: # optional - fricas sage: a = fricas('"Hello"') sage: a.upperCase_q upperCase? @@ -2108,9 +2099,9 @@ def __init__(self, parent, name): TESTS:: - sage: fricas.upperCase_q # optional - fricas + sage: fricas.upperCase_q upperCase? - sage: fricas.upperCase_e # optional - fricas + sage: fricas.upperCase_e upperCase! """ @@ -2132,7 +2123,7 @@ def is_FriCASElement(x): doctest:...: DeprecationWarning: the function is_FriCASElement is deprecated; use isinstance(x, sage.interfaces.abc.FriCASElement) instead See https://github.com/sagemath/sage/issues/34804 for details. False - sage: is_FriCASElement(fricas(2)) # optional - fricas + sage: is_FriCASElement(fricas(2)) True """ from sage.misc.superseded import deprecation @@ -2183,7 +2174,6 @@ def __doctest_cleanup(): """ EXAMPLES:: - sage: # optional - fricas sage: from sage.interfaces.fricas import __doctest_cleanup sage: a = FriCAS() sage: two = a(2) From 9ec6b944651a32f3561847b7af7b34b245249e07 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 15:32:45 -0800 Subject: [PATCH 344/463] sage.interfaces.expect: Delay construction of command to first use, handle Executable --- src/sage/interfaces/expect.py | 58 +++++++++++++++++++++++++---------- src/sage/interfaces/fricas.py | 2 +- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index a5ba8f09f4e..6aacafca9cb 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -40,6 +40,7 @@ import io import os import re +import shlex import signal import sys import weakref @@ -137,11 +138,10 @@ def __init__(self, name, prompt, command=None, env={}, server=None, server = os.getenv(env_name.format('SERVER')) if server_tmpdir is None: server_tmpdir = os.getenv(env_name.format('TMPDIR')) - if command is None: - command = os.getenv(env_name.format('COMMAND')) if script_subdirectory is None: script_subdirectory = os.getenv(env_name.format('SCRIPT_SUBDIRECTORY')) self.__is_remote = False + self.__remote_ulimit = None self.__remote_cleaner = remote_cleaner self._expect = None self._eval_using_file_cutoff = eval_using_file_cutoff @@ -179,11 +179,23 @@ def __init__(self, name, prompt, command=None, env={}, server=None, def set_server_and_command(self, server=None, command=None, server_tmpdir=None, ulimit=None): """ Changes the server and the command to use for this interface. - This raises a Runtime error if the interface is already started. + + This raises a :class:`RuntimeError` if the interface is already started. + + INPUT: + + - ``server`` -- string or ``None`` (default); name of a remote host to connect to using ``ssh``. + + - ``command`` -- one of: + + - a string; command line passed to the shell + + - a sequence of an :class:`~sage.features.Executable` and strings, arguments to + pass to the executable. EXAMPLES:: - sage: magma.set_server_and_command(server = 'remote', command = 'mymagma') # indirect doctest + sage: magma.set_server_and_command(server='remote', command='mymagma') # indirect doctest No remote temporary directory (option server_tmpdir) specified, using /tmp/ on remote sage: magma.server() 'remote' @@ -192,19 +204,13 @@ def set_server_and_command(self, server=None, command=None, server_tmpdir=None, """ if self._expect: raise RuntimeError("interface has already started") - if command is None: - command = self.name() self._server = server + self.__remote_ulimit = ulimit if server is not None: - if ulimit: - command = "ssh -t %s 'ulimit %s; %s'" % (server, ulimit, command) - else: - command = "ssh -t %s '%s'" % (server, command) self.__is_remote = True self._eval_using_file_cutoff = 0 # don't allow this! if self.__verbose_start: print("Using remote server") - print(command) if server_tmpdir is None: # TO DO: Why default to /tmp/? Might be better to use the expect process itself to get a tmp folder print("No remote temporary directory (option server_tmpdir) specified, using /tmp/ on " + server) @@ -221,7 +227,7 @@ def server(self): EXAMPLES:: - sage: magma.set_server_and_command(server = 'remote') + sage: magma.set_server_and_command(server='remote') No remote temporary directory (option server_tmpdir) specified, using /tmp/ on remote sage: magma.server() # indirect doctest 'remote' @@ -230,15 +236,33 @@ def server(self): def command(self): """ - Return the command used in this interface. + Return the command used in this interface as a string. EXAMPLES:: - sage: magma.set_server_and_command(command = 'magma-2.19') - sage: magma.command() # indirect doctest + sage: magma.set_server_and_command(command='magma-2.19') + sage: magma.command() # indirect doctest 'magma-2.19' """ - return self.__command + command = self.__command + server = self.server() + if command is None: + env_name = 'SAGE_%s_{}' % self.name().upper() # same as in __init__ + command = os.getenv(env_name.format('COMMAND'), self.name()) + elif not isinstance(command, str): + executable = self.command[0] + if server: + executable = executable.name + else: + executable = executable.absolute_filename() + command = ' '.join([shlex.quote(executable)] + + [shlex.quote(arg) for arg in self.__command[1:]]) + if server: + if self.__ulimit: + command = f"ulimit {ulimit}; {command}" + command = f"ssh -t {shlex.quote(server)} {shlex.quote(command)}" + + return command def _get(self, wait=0.1, alternate_prompt=None): if self._expect is None: @@ -460,7 +484,7 @@ def _start(self, alt_message=None, block_during_init=True): if self.__logfilename is not None: self.__logfile = open(self.__logfilename, 'wb') - cmd = self.__command + cmd = self.command() if self.__verbose_start: print(cmd) diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index ab03a7e0b19..878d5b821e6 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -84,7 +84,7 @@ example, try the following sum but with a much bigger range, and hit control-C:: - sage: f = fricas('(x^5 - y^5)^10000') # not tested - fricas + sage: f = fricas('(x^5 - y^5)^10000') # not tested Interrupting FriCAS... ... KeyboardInterrupt: Ctrl-c pressed while running FriCAS From 26e2e580c3a58f27bd234dad2dd6697d89507bb3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 15:53:53 -0800 Subject: [PATCH 345/463] src/sage/interfaces/fricas.py: Use the FriCAS feature less eagerly --- src/sage/interfaces/expect.py | 4 ++-- src/sage/interfaces/fricas.py | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 6aacafca9cb..0aa0125aeaf 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -250,13 +250,13 @@ def command(self): env_name = 'SAGE_%s_{}' % self.name().upper() # same as in __init__ command = os.getenv(env_name.format('COMMAND'), self.name()) elif not isinstance(command, str): - executable = self.command[0] + executable = command[0] if server: executable = executable.name else: executable = executable.absolute_filename() command = ' '.join([shlex.quote(executable)] - + [shlex.quote(arg) for arg in self.__command[1:]]) + + [shlex.quote(arg) for arg in command[1:]]) if server: if self.__ulimit: command = f"ulimit {ulimit}; {command}" diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index 878d5b821e6..3df9ec9fc92 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -267,7 +267,7 @@ class FriCAS(ExtraTabCompletion, Expect): """ def __init__(self, name='fricas', command=None, script_subdirectory=None, logfile=None, - server=None, server_tmpdir=None, options=""): + server=None, server_tmpdir=None): """ Create an instance of the FriCAS interpreter. @@ -290,11 +290,9 @@ def __init__(self, name='fricas', command=None, sage: fricas(I*x).sage() I*x """ - from sage.features.fricas import FriCAS - FriCAS().require() - options ="-nosman" + options - import shlex - command = '{} {}'.format(shlex.quote(FriCAS().absolute_filename()), options) + if command is None: + from sage.features.fricas import FriCAS + command = [FriCAS(), "-nosman"] eval_using_file_cutoff = 4096 - 5 # magic number from Expect._eval_line (there might be a bug) assert max(len(c) for c in FRICAS_INIT_CODE) < eval_using_file_cutoff From b474f0ef9f990efa7042517df14bb5b8accb590d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 20:02:19 -0800 Subject: [PATCH 346/463] sage.interfaces.expect: Fix up ulimit --- src/sage/interfaces/expect.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 0aa0125aeaf..ab3f68bd188 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -258,8 +258,8 @@ def command(self): command = ' '.join([shlex.quote(executable)] + [shlex.quote(arg) for arg in command[1:]]) if server: - if self.__ulimit: - command = f"ulimit {ulimit}; {command}" + if self.__remote_ulimit: + command = f"ulimit {self.__remote_ulimit}; {command}" command = f"ssh -t {shlex.quote(server)} {shlex.quote(command)}" return command From 256bb8c111b6531ca07bd61be418b51fd727efa2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Nov 2023 20:05:35 -0800 Subject: [PATCH 347/463] sage.interfaces.expect: Update doctest output --- src/sage/interfaces/expect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index ab3f68bd188..cf331f53fd0 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -200,7 +200,7 @@ def set_server_and_command(self, server=None, command=None, server_tmpdir=None, sage: magma.server() 'remote' sage: magma.command() - "ssh -t remote 'mymagma'" + 'ssh -t remote mymagma' """ if self._expect: raise RuntimeError("interface has already started") From ace41e4b2adf2c6b6e8c5d33957351ce685207b7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 18 Nov 2023 07:22:19 -0800 Subject: [PATCH 348/463] src/sage/interfaces/fricas.py: Do not rely on '# tol' for complex tolerances; cf. #36631 --- src/sage/interfaces/fricas.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index 3df9ec9fc92..75a277bcd05 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -1608,13 +1608,13 @@ def _sage_expression(fricas_InputForm): Check that :trac:`25602` is fixed:: sage: r = fricas.integrate(72000/(1+x^5), x).sage() - sage: n(r.subs(x=5) - r.subs(x=3)) # tol 0.1 - 193.020947266210 + sage: abs(n(r.subs(x=5) - r.subs(x=3)) - 193.020947266210) <= 0.1 + True sage: var("a"); r = fricas.integrate(72000*a^8/(a^5+x^5), x).sage() a - sage: n(r.subs(a=1, x=5) - r.subs(a=1, x=3)) # tol 0.1 - 193.020947266268 - 8.73114913702011e-11*I + sage: abs(n(r.subs(a=1, x=5) - r.subs(a=1, x=3)) - 193.020947266268) <= 0.1 + True Check conversions of sums and products:: From 870fa228fcd96e1724820a6d29ce2c8d6c43289f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 18 Nov 2023 12:05:36 -0800 Subject: [PATCH 349/463] src/sage/functions/special.py: Use 'abs tol' instead of 'tol' in two examples --- src/sage/functions/special.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index 93e032d0677..9348b921685 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -511,7 +511,7 @@ def __init__(self): Check that :trac:`34085` is fixed:: sage: _ = var("x y") # needs sage.symbolic - sage: fricas(elliptic_e(x, y)) # optional - fricas, needs sage.symbolic + sage: fricas(elliptic_e(x, y)) # optional - fricas, needs sage.symbolic ellipticE(sin(x),y) However, the conversion is only correct in the interval @@ -525,7 +525,7 @@ def __init__(self): sage: f = lambda x, y: elliptic_e(arcsin(x), y).subs(x=x, y=y) sage: g = lambda x, y: fricas.ellipticE(x, y).sage() sage: d = lambda x, y: f(x, y) - g(x, y) - sage: [d(N(-pi/2 + x), y) # tol 1e-8 # optional - fricas, needs sage.symbolic + sage: [d(N(-pi/2 + x), y) # abs tol 1e-8 # optional - fricas, needs sage.symbolic ....: for x in range(1, 3) for y in range(-2, 2)] [0.000000000000000, 0.000000000000000, @@ -877,7 +877,7 @@ def __init__(self): Check that :trac:`34186` is fixed:: sage: _ = var("x y") # needs sage.symbolic - sage: fricas(elliptic_f(x, y)) # optional - fricas, needs sage.symbolic + sage: fricas(elliptic_f(x, y)) # optional - fricas, needs sage.symbolic ellipticF(sin(x),y) However, the conversion is only correct in the interval @@ -891,7 +891,7 @@ def __init__(self): sage: f = lambda x, y: elliptic_f(arcsin(x), y).subs(x=x, y=y) sage: g = lambda x, y: fricas.ellipticF(x, y).sage() sage: d = lambda x, y: f(x, y) - g(x, y) - sage: [d(N(-pi/2 + x), y) # tol 1e-8 # optional - fricas, needs sage.symbolic + sage: [d(N(-pi/2 + x), y) # abs tol 1e-8 # optional - fricas, needs sage.symbolic ....: for x in range(1, 3) for y in range(-2,2)] [0.000000000000000, 0.000000000000000, From 0bd2a93f84e43f1190714991767ce8cbdf039443 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 22 Nov 2023 12:08:31 -0800 Subject: [PATCH 350/463] src/sage/geometry/lattice_polytope.py: Add test --- src/sage/geometry/lattice_polytope.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 5874d2d7e9a..cdf2c374e9f 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -3184,6 +3184,13 @@ def normal_form(self, algorithm="palp_native", permutation=False): 10 loops, best of 3: 0.137 s per loop sage: %timeit P.normal_form.clear_cache(); P.normal_form("palp_modified") # not tested 10 loops, best of 3: 22.2 s per loop + + TESTS:: + + sage: d.normal_form("palp_fiction") + Traceback (most recent call last): + ... + ValueError: algorithm must be 'palp', 'palp_native', or 'palp_modified' """ if self.dim() < self.lattice_dim(): raise ValueError("normal form is not defined for %s" % self) From d5a6d83a032a4b5e72352502288f9d639dcd311e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 17:57:01 -0700 Subject: [PATCH 351/463] build/pkgs/notebook: Update to 7.0.2 --- build/pkgs/notebook/SPKG.rst | 10 ++++++++++ build/pkgs/notebook/checksums.ini | 10 +++++----- build/pkgs/notebook/dependencies | 2 +- build/pkgs/notebook/package-version.txt | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/build/pkgs/notebook/SPKG.rst b/build/pkgs/notebook/SPKG.rst index 7dfdc5ee1c8..9cbb9b2463c 100644 --- a/build/pkgs/notebook/SPKG.rst +++ b/build/pkgs/notebook/SPKG.rst @@ -6,3 +6,13 @@ Description The Jupyter HTML notebook is a web-based notebook environment for interactive computing. + +License +------- + +BSD 3-Clause License + +Upstream Contact +---------------- + +https://pypi.org/project/notebook/ diff --git a/build/pkgs/notebook/checksums.ini b/build/pkgs/notebook/checksums.ini index 16bbe6de420..c93f3f3c1a3 100644 --- a/build/pkgs/notebook/checksums.ini +++ b/build/pkgs/notebook/checksums.ini @@ -1,5 +1,5 @@ -tarball=notebook-VERSION.tar.gz -sha1=d715730ac48bca8739ce8faf5329841d147163cd -md5=90a5b998e496ed4c18975d3a42960df0 -cksum=577775576 -upstream_url=https://pypi.io/packages/source/n/notebook/notebook-VERSION.tar.gz +tarball=notebook-VERSION-py3-none-any.whl +sha1=072def379a2015bc7295065330e83a6f878965dc +md5=741fa46d8ac2df863bad53e375a114ef +cksum=116542382 +upstream_url=https://pypi.io/packages/py3/n/notebook/notebook-VERSION-py3-none-any.whl diff --git a/build/pkgs/notebook/dependencies b/build/pkgs/notebook/dependencies index 9e6cbf4b36d..97d97af24c5 100644 --- a/build/pkgs/notebook/dependencies +++ b/build/pkgs/notebook/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) ipython jupyter_client ipykernel nbconvert nbformat jinja2 tornado terminado send2trash prometheus_client argon2_cffi $(PYTHON) +jupyter_server | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/notebook/package-version.txt b/build/pkgs/notebook/package-version.txt index d613169e889..a8907c025d5 100644 --- a/build/pkgs/notebook/package-version.txt +++ b/build/pkgs/notebook/package-version.txt @@ -1 +1 @@ -6.4.12 +7.0.2 From e64906c93859fdccf117f7649656734313dfe320 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 22:26:28 -0700 Subject: [PATCH 352/463] build/pkgs/jupyter_server: New (notebook 7 dependency) --- build/pkgs/jupyter_server/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/jupyter_server/checksums.ini | 5 +++++ build/pkgs/jupyter_server/dependencies | 4 ++++ build/pkgs/jupyter_server/install-requires.txt | 1 + build/pkgs/jupyter_server/package-version.txt | 1 + build/pkgs/jupyter_server/type | 1 + 6 files changed, 30 insertions(+) create mode 100644 build/pkgs/jupyter_server/SPKG.rst create mode 100644 build/pkgs/jupyter_server/checksums.ini create mode 100644 build/pkgs/jupyter_server/dependencies create mode 100644 build/pkgs/jupyter_server/install-requires.txt create mode 100644 build/pkgs/jupyter_server/package-version.txt create mode 100644 build/pkgs/jupyter_server/type diff --git a/build/pkgs/jupyter_server/SPKG.rst b/build/pkgs/jupyter_server/SPKG.rst new file mode 100644 index 00000000000..6a9b87f36ad --- /dev/null +++ b/build/pkgs/jupyter_server/SPKG.rst @@ -0,0 +1,18 @@ +jupyter_server: The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications. +===================================================================================================== + +Description +----------- + +The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications. + +License +------- + +BSD 3-Clause License - Copyright (c) 2001-2015, IPython Development Team - Copyright (c) 2015-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Upstream Contact +---------------- + +https://pypi.org/project/jupyter-server/ + diff --git a/build/pkgs/jupyter_server/checksums.ini b/build/pkgs/jupyter_server/checksums.ini new file mode 100644 index 00000000000..5ff8fec7b23 --- /dev/null +++ b/build/pkgs/jupyter_server/checksums.ini @@ -0,0 +1,5 @@ +tarball=jupyter_server-VERSION-py3-none-any.whl +sha1=17dc2fb6998e00d25979342673f030f9aad7ae83 +md5=71d3d41c11faa3e9f3cd39f9da594a86 +cksum=354373153 +upstream_url=https://pypi.io/packages/py3/j/jupyter_server/jupyter_server-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_server/dependencies b/build/pkgs/jupyter_server/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/jupyter_server/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_server/install-requires.txt b/build/pkgs/jupyter_server/install-requires.txt new file mode 100644 index 00000000000..72a770c947c --- /dev/null +++ b/build/pkgs/jupyter_server/install-requires.txt @@ -0,0 +1 @@ +jupyter-server diff --git a/build/pkgs/jupyter_server/package-version.txt b/build/pkgs/jupyter_server/package-version.txt new file mode 100644 index 00000000000..37c2961c243 --- /dev/null +++ b/build/pkgs/jupyter_server/package-version.txt @@ -0,0 +1 @@ +2.7.2 diff --git a/build/pkgs/jupyter_server/type b/build/pkgs/jupyter_server/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/jupyter_server/type @@ -0,0 +1 @@ +standard From 6c4a73fe28ff65de19199537596b929b3c390fa0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 22:35:13 -0700 Subject: [PATCH 353/463] build/pkgs/anyio: New (jupyter_server dependency) --- build/pkgs/anyio/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/anyio/checksums.ini | 5 +++++ build/pkgs/anyio/dependencies | 4 ++++ build/pkgs/anyio/install-requires.txt | 1 + build/pkgs/anyio/package-version.txt | 1 + build/pkgs/anyio/type | 1 + 6 files changed, 30 insertions(+) create mode 100644 build/pkgs/anyio/SPKG.rst create mode 100644 build/pkgs/anyio/checksums.ini create mode 100644 build/pkgs/anyio/dependencies create mode 100644 build/pkgs/anyio/install-requires.txt create mode 100644 build/pkgs/anyio/package-version.txt create mode 100644 build/pkgs/anyio/type diff --git a/build/pkgs/anyio/SPKG.rst b/build/pkgs/anyio/SPKG.rst new file mode 100644 index 00000000000..bf455f06bdb --- /dev/null +++ b/build/pkgs/anyio/SPKG.rst @@ -0,0 +1,18 @@ +anyio: High level compatibility layer for multiple asynchronous event loop implementations +========================================================================================== + +Description +----------- + +High level compatibility layer for multiple asynchronous event loop implementations + +License +------- + +MIT + +Upstream Contact +---------------- + +https://pypi.org/project/anyio/ + diff --git a/build/pkgs/anyio/checksums.ini b/build/pkgs/anyio/checksums.ini new file mode 100644 index 00000000000..9e9041163a8 --- /dev/null +++ b/build/pkgs/anyio/checksums.ini @@ -0,0 +1,5 @@ +tarball=anyio-VERSION-py3-none-any.whl +sha1=bed42cf64ff0753ea0062689b533727745470f68 +md5=1e50429e671f536b3a41ed6a94e94c9f +cksum=1692872471 +upstream_url=https://pypi.io/packages/py3/a/anyio/anyio-VERSION-py3-none-any.whl diff --git a/build/pkgs/anyio/dependencies b/build/pkgs/anyio/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/anyio/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/anyio/install-requires.txt b/build/pkgs/anyio/install-requires.txt new file mode 100644 index 00000000000..c77c069ecc9 --- /dev/null +++ b/build/pkgs/anyio/install-requires.txt @@ -0,0 +1 @@ +anyio diff --git a/build/pkgs/anyio/package-version.txt b/build/pkgs/anyio/package-version.txt new file mode 100644 index 00000000000..a76ccff2a6e --- /dev/null +++ b/build/pkgs/anyio/package-version.txt @@ -0,0 +1 @@ +3.7.1 diff --git a/build/pkgs/anyio/type b/build/pkgs/anyio/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/anyio/type @@ -0,0 +1 @@ +standard From 182a36b348e7fb65b47fb7404262c8e831f99137 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 22:41:14 -0700 Subject: [PATCH 354/463] build/pkgs/sniffio: New (anyio dependency) --- build/pkgs/anyio/dependencies | 2 +- build/pkgs/jupyter_server/dependencies | 2 +- build/pkgs/sniffio/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/sniffio/checksums.ini | 5 +++++ build/pkgs/sniffio/dependencies | 4 ++++ build/pkgs/sniffio/install-requires.txt | 1 + build/pkgs/sniffio/package-version.txt | 1 + build/pkgs/sniffio/type | 1 + 8 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 build/pkgs/sniffio/SPKG.rst create mode 100644 build/pkgs/sniffio/checksums.ini create mode 100644 build/pkgs/sniffio/dependencies create mode 100644 build/pkgs/sniffio/install-requires.txt create mode 100644 build/pkgs/sniffio/package-version.txt create mode 100644 build/pkgs/sniffio/type diff --git a/build/pkgs/anyio/dependencies b/build/pkgs/anyio/dependencies index 0738c2d7777..654e350b35c 100644 --- a/build/pkgs/anyio/dependencies +++ b/build/pkgs/anyio/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) idna sniffio | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_server/dependencies b/build/pkgs/jupyter_server/dependencies index 0738c2d7777..ebedc8ea498 100644 --- a/build/pkgs/jupyter_server/dependencies +++ b/build/pkgs/jupyter_server/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) anyio | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/sniffio/SPKG.rst b/build/pkgs/sniffio/SPKG.rst new file mode 100644 index 00000000000..238aeec12b3 --- /dev/null +++ b/build/pkgs/sniffio/SPKG.rst @@ -0,0 +1,18 @@ +sniffio: Sniff out which async library your code is running under +================================================================= + +Description +----------- + +Sniff out which async library your code is running under + +License +------- + +MIT OR Apache-2.0 + +Upstream Contact +---------------- + +https://pypi.org/project/sniffio/ + diff --git a/build/pkgs/sniffio/checksums.ini b/build/pkgs/sniffio/checksums.ini new file mode 100644 index 00000000000..d8475bc91d3 --- /dev/null +++ b/build/pkgs/sniffio/checksums.ini @@ -0,0 +1,5 @@ +tarball=sniffio-VERSION-py3-none-any.whl +sha1=16f883fd7e31aa383df8901002f9ce5cec7606e5 +md5=7890655ffc549d04087bbc2f93332034 +cksum=2528943486 +upstream_url=https://pypi.io/packages/py3/s/sniffio/sniffio-VERSION-py3-none-any.whl diff --git a/build/pkgs/sniffio/dependencies b/build/pkgs/sniffio/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/sniffio/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/sniffio/install-requires.txt b/build/pkgs/sniffio/install-requires.txt new file mode 100644 index 00000000000..01c650244d0 --- /dev/null +++ b/build/pkgs/sniffio/install-requires.txt @@ -0,0 +1 @@ +sniffio diff --git a/build/pkgs/sniffio/package-version.txt b/build/pkgs/sniffio/package-version.txt new file mode 100644 index 00000000000..f0bb29e7638 --- /dev/null +++ b/build/pkgs/sniffio/package-version.txt @@ -0,0 +1 @@ +1.3.0 diff --git a/build/pkgs/sniffio/type b/build/pkgs/sniffio/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/sniffio/type @@ -0,0 +1 @@ +standard From 1599d6851774f3c0c7935b4b6535b49eb945d0e7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 22:51:03 -0700 Subject: [PATCH 355/463] build/pkgs/jupyter_server_terminals: New (jupyter_server dependency) --- build/pkgs/jupyter_server_terminals/SPKG.rst | 18 ++++++++++++++++++ .../jupyter_server_terminals/checksums.ini | 5 +++++ .../pkgs/jupyter_server_terminals/dependencies | 4 ++++ .../install-requires.txt | 1 + .../package-version.txt | 1 + build/pkgs/jupyter_server_terminals/type | 1 + 6 files changed, 30 insertions(+) create mode 100644 build/pkgs/jupyter_server_terminals/SPKG.rst create mode 100644 build/pkgs/jupyter_server_terminals/checksums.ini create mode 100644 build/pkgs/jupyter_server_terminals/dependencies create mode 100644 build/pkgs/jupyter_server_terminals/install-requires.txt create mode 100644 build/pkgs/jupyter_server_terminals/package-version.txt create mode 100644 build/pkgs/jupyter_server_terminals/type diff --git a/build/pkgs/jupyter_server_terminals/SPKG.rst b/build/pkgs/jupyter_server_terminals/SPKG.rst new file mode 100644 index 00000000000..a739e9edcc0 --- /dev/null +++ b/build/pkgs/jupyter_server_terminals/SPKG.rst @@ -0,0 +1,18 @@ +jupyter_server_terminals: A Jupyter Server Extension Providing Terminals. +========================================================================= + +Description +----------- + +A Jupyter Server Extension Providing Terminals. + +License +------- + +# Licensing terms This project is licensed under the terms of the Modified BSD License (also known as New or Revised or 3-Clause BSD), as follows: - Copyright (c) 2021-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Jupyter Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## About the Jupyter Development Team The Jupyter Development Team is the set of all contributors to the Jupyter project. This includes all of the Jupyter subprojects. The core team that coordinates development on GitHub can be found here: https://github.com/jupyter/. ## Our Copyright Policy Jupyter uses a shared copyright model. Each contributor maintains copyright over their contributions to Jupyter. But, it is important to note that these contributions are typically only changes to the repositories. Thus, the Jupyter source code, in its entirety is not the copyright of any single person or institution. Instead, it is the collective copyright of the entire Jupyter Development Team. If individual contributors want to maintain a record of what changes/contributions they have specific copyright on, they should indicate their copyright in the commit message of the change, when they commit the change to one of the Jupyter repositories. With this in mind, the following banner should be used in any source code file to indicate the copyright and license terms: # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. + +Upstream Contact +---------------- + +https://pypi.org/project/jupyter-server-terminals/ + diff --git a/build/pkgs/jupyter_server_terminals/checksums.ini b/build/pkgs/jupyter_server_terminals/checksums.ini new file mode 100644 index 00000000000..99f9ede51e0 --- /dev/null +++ b/build/pkgs/jupyter_server_terminals/checksums.ini @@ -0,0 +1,5 @@ +tarball=jupyter_server_terminals-VERSION-py3-none-any.whl +sha1=fd1201e9f0064b2a5a05ed7346dfe52546f13b0b +md5=6312ef2342aa944aaa59619249d7248b +cksum=2312769383 +upstream_url=https://pypi.io/packages/py3/j/jupyter_server_terminals/jupyter_server_terminals-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_server_terminals/dependencies b/build/pkgs/jupyter_server_terminals/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/jupyter_server_terminals/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_server_terminals/install-requires.txt b/build/pkgs/jupyter_server_terminals/install-requires.txt new file mode 100644 index 00000000000..7841d7c9a9b --- /dev/null +++ b/build/pkgs/jupyter_server_terminals/install-requires.txt @@ -0,0 +1 @@ +jupyter-server-terminals diff --git a/build/pkgs/jupyter_server_terminals/package-version.txt b/build/pkgs/jupyter_server_terminals/package-version.txt new file mode 100644 index 00000000000..6f2743d65dc --- /dev/null +++ b/build/pkgs/jupyter_server_terminals/package-version.txt @@ -0,0 +1 @@ +0.4.4 diff --git a/build/pkgs/jupyter_server_terminals/type b/build/pkgs/jupyter_server_terminals/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/jupyter_server_terminals/type @@ -0,0 +1 @@ +standard From 198091d72f7cb7257bde469372484484a32ada42 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 22:52:50 -0700 Subject: [PATCH 356/463] build/pkgs/jupyter_events: New (jupyter_server dependency) --- build/pkgs/jupyter_events/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/jupyter_events/checksums.ini | 5 +++++ build/pkgs/jupyter_events/dependencies | 4 ++++ build/pkgs/jupyter_events/install-requires.txt | 1 + build/pkgs/jupyter_events/package-version.txt | 1 + build/pkgs/jupyter_events/type | 1 + 6 files changed, 30 insertions(+) create mode 100644 build/pkgs/jupyter_events/SPKG.rst create mode 100644 build/pkgs/jupyter_events/checksums.ini create mode 100644 build/pkgs/jupyter_events/dependencies create mode 100644 build/pkgs/jupyter_events/install-requires.txt create mode 100644 build/pkgs/jupyter_events/package-version.txt create mode 100644 build/pkgs/jupyter_events/type diff --git a/build/pkgs/jupyter_events/SPKG.rst b/build/pkgs/jupyter_events/SPKG.rst new file mode 100644 index 00000000000..4a685b647c6 --- /dev/null +++ b/build/pkgs/jupyter_events/SPKG.rst @@ -0,0 +1,18 @@ +jupyter_events: Jupyter Event System library +============================================ + +Description +----------- + +Jupyter Event System library + +License +------- + +BSD 3-Clause License Copyright (c) 2022-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Upstream Contact +---------------- + +https://pypi.org/project/jupyter-events/ + diff --git a/build/pkgs/jupyter_events/checksums.ini b/build/pkgs/jupyter_events/checksums.ini new file mode 100644 index 00000000000..01f690c0fcf --- /dev/null +++ b/build/pkgs/jupyter_events/checksums.ini @@ -0,0 +1,5 @@ +tarball=jupyter_events-VERSION-py3-none-any.whl +sha1=a6cb6e7619559191dde24719b2ceef734fc9a5bd +md5=48ea0cdb47c3b27d02544f2a912666ee +cksum=3827567899 +upstream_url=https://pypi.io/packages/py3/j/jupyter_events/jupyter_events-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_events/dependencies b/build/pkgs/jupyter_events/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/jupyter_events/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_events/install-requires.txt b/build/pkgs/jupyter_events/install-requires.txt new file mode 100644 index 00000000000..e31af18cf10 --- /dev/null +++ b/build/pkgs/jupyter_events/install-requires.txt @@ -0,0 +1 @@ +jupyter-events diff --git a/build/pkgs/jupyter_events/package-version.txt b/build/pkgs/jupyter_events/package-version.txt new file mode 100644 index 00000000000..faef31a4357 --- /dev/null +++ b/build/pkgs/jupyter_events/package-version.txt @@ -0,0 +1 @@ +0.7.0 diff --git a/build/pkgs/jupyter_events/type b/build/pkgs/jupyter_events/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/jupyter_events/type @@ -0,0 +1 @@ +standard From 3891a3cbb47b0f3f4f4e860b5904bada687fd7be Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 22:54:01 -0700 Subject: [PATCH 357/463] build/pkgs/overrides: New (jupyter_server dependency) --- build/pkgs/overrides/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/overrides/checksums.ini | 5 +++++ build/pkgs/overrides/dependencies | 4 ++++ build/pkgs/overrides/install-requires.txt | 1 + build/pkgs/overrides/package-version.txt | 1 + build/pkgs/overrides/type | 1 + 6 files changed, 30 insertions(+) create mode 100644 build/pkgs/overrides/SPKG.rst create mode 100644 build/pkgs/overrides/checksums.ini create mode 100644 build/pkgs/overrides/dependencies create mode 100644 build/pkgs/overrides/install-requires.txt create mode 100644 build/pkgs/overrides/package-version.txt create mode 100644 build/pkgs/overrides/type diff --git a/build/pkgs/overrides/SPKG.rst b/build/pkgs/overrides/SPKG.rst new file mode 100644 index 00000000000..bc6dcdbfdd6 --- /dev/null +++ b/build/pkgs/overrides/SPKG.rst @@ -0,0 +1,18 @@ +overrides: A decorator to automatically detect mismatch when overriding a method. +================================================================================= + +Description +----------- + +A decorator to automatically detect mismatch when overriding a method. + +License +------- + +Apache License, Version 2.0 + +Upstream Contact +---------------- + +https://pypi.org/project/overrides/ + diff --git a/build/pkgs/overrides/checksums.ini b/build/pkgs/overrides/checksums.ini new file mode 100644 index 00000000000..cd313073a39 --- /dev/null +++ b/build/pkgs/overrides/checksums.ini @@ -0,0 +1,5 @@ +tarball=overrides-VERSION-py3-none-any.whl +sha1=740e9e607a9e4f78dea7a1b82bcb27f285bc5f48 +md5=ed4ab0bd43112d05105576f0a50f5aa7 +cksum=3865068538 +upstream_url=https://pypi.io/packages/py3/o/overrides/overrides-VERSION-py3-none-any.whl diff --git a/build/pkgs/overrides/dependencies b/build/pkgs/overrides/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/overrides/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/overrides/install-requires.txt b/build/pkgs/overrides/install-requires.txt new file mode 100644 index 00000000000..6113455c332 --- /dev/null +++ b/build/pkgs/overrides/install-requires.txt @@ -0,0 +1 @@ +overrides diff --git a/build/pkgs/overrides/package-version.txt b/build/pkgs/overrides/package-version.txt new file mode 100644 index 00000000000..ba7f754d0c3 --- /dev/null +++ b/build/pkgs/overrides/package-version.txt @@ -0,0 +1 @@ +7.4.0 diff --git a/build/pkgs/overrides/type b/build/pkgs/overrides/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/overrides/type @@ -0,0 +1 @@ +standard From cabf77e5cfe267216a085874e31779f8b89e4f24 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 22:56:12 -0700 Subject: [PATCH 358/463] build/pkgs/websocket_client: New (jupyter_server dependency) --- build/pkgs/websocket_client/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/websocket_client/checksums.ini | 5 +++++ build/pkgs/websocket_client/dependencies | 4 ++++ .../pkgs/websocket_client/install-requires.txt | 1 + .../pkgs/websocket_client/package-version.txt | 1 + build/pkgs/websocket_client/type | 1 + 6 files changed, 30 insertions(+) create mode 100644 build/pkgs/websocket_client/SPKG.rst create mode 100644 build/pkgs/websocket_client/checksums.ini create mode 100644 build/pkgs/websocket_client/dependencies create mode 100644 build/pkgs/websocket_client/install-requires.txt create mode 100644 build/pkgs/websocket_client/package-version.txt create mode 100644 build/pkgs/websocket_client/type diff --git a/build/pkgs/websocket_client/SPKG.rst b/build/pkgs/websocket_client/SPKG.rst new file mode 100644 index 00000000000..31b54420fd0 --- /dev/null +++ b/build/pkgs/websocket_client/SPKG.rst @@ -0,0 +1,18 @@ +websocket_client: WebSocket client for Python with low level API options +======================================================================== + +Description +----------- + +WebSocket client for Python with low level API options + +License +------- + +Apache-2.0 + +Upstream Contact +---------------- + +https://pypi.org/project/websocket-client/ + diff --git a/build/pkgs/websocket_client/checksums.ini b/build/pkgs/websocket_client/checksums.ini new file mode 100644 index 00000000000..916f8ae6a45 --- /dev/null +++ b/build/pkgs/websocket_client/checksums.ini @@ -0,0 +1,5 @@ +tarball=websocket_client-VERSION-py3-none-any.whl +sha1=4e387c09ed3ec0c15eb6bd3dcd343cf18f028f95 +md5=02d92a8221cc6d8fd2d22c370aa05ef3 +cksum=3728437026 +upstream_url=https://pypi.io/packages/py3/w/websocket_client/websocket_client-VERSION-py3-none-any.whl diff --git a/build/pkgs/websocket_client/dependencies b/build/pkgs/websocket_client/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/websocket_client/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/websocket_client/install-requires.txt b/build/pkgs/websocket_client/install-requires.txt new file mode 100644 index 00000000000..db0afb87c14 --- /dev/null +++ b/build/pkgs/websocket_client/install-requires.txt @@ -0,0 +1 @@ +websocket-client diff --git a/build/pkgs/websocket_client/package-version.txt b/build/pkgs/websocket_client/package-version.txt new file mode 100644 index 00000000000..fdd3be6df54 --- /dev/null +++ b/build/pkgs/websocket_client/package-version.txt @@ -0,0 +1 @@ +1.6.2 diff --git a/build/pkgs/websocket_client/type b/build/pkgs/websocket_client/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/websocket_client/type @@ -0,0 +1 @@ +standard From 07ce76e41d7d386f7b5ebcc5a2320b1f3c1ba803 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 28 Aug 2023 10:16:36 -0700 Subject: [PATCH 359/463] build/pkgs/jupyter_core: Update to 5.3.1 --- build/pkgs/jupyter_core/checksums.ini | 6 +++--- build/pkgs/jupyter_core/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyter_core/checksums.ini b/build/pkgs/jupyter_core/checksums.ini index 3e45d122068..cf968d4a511 100644 --- a/build/pkgs/jupyter_core/checksums.ini +++ b/build/pkgs/jupyter_core/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyter_core-VERSION.tar.gz -sha1=2a0a14c4c1624826100d59169636bb588465deb9 -md5=7586526dd4ca9d1bc820a4a5429df48b -cksum=1776144013 +sha1=bd666ad6cb0484e1704fc73a828f6671a8bb9641 +md5=b9b8f90ee76509fba4c63f90c9d39d8b +cksum=2599933228 upstream_url=https://pypi.io/packages/source/j/jupyter_core/jupyter_core-VERSION.tar.gz diff --git a/build/pkgs/jupyter_core/package-version.txt b/build/pkgs/jupyter_core/package-version.txt index 815588ef140..c7cb1311a64 100644 --- a/build/pkgs/jupyter_core/package-version.txt +++ b/build/pkgs/jupyter_core/package-version.txt @@ -1 +1 @@ -4.12.0 +5.3.1 From ccdad3baad621ced2afb2470d61b4367d9a67f67 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 23:07:15 -0700 Subject: [PATCH 360/463] build/pkgs/nbconvert: Update to 7.7.4 --- build/pkgs/nbconvert/checksums.ini | 6 +++--- build/pkgs/nbconvert/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/nbconvert/checksums.ini b/build/pkgs/nbconvert/checksums.ini index 1c3926c6ce3..3ba9564f206 100644 --- a/build/pkgs/nbconvert/checksums.ini +++ b/build/pkgs/nbconvert/checksums.ini @@ -1,5 +1,5 @@ tarball=nbconvert-VERSION-py3-none-any.whl -sha1=de3dd5e475d84c2d143c03dfc22bfc490c03092f -md5=942dd716bd6976c58fdbcfec97bfbe20 -cksum=610202196 +sha1=561265d271f3024ed072cb9a203dfaa8d7addf43 +md5=5e0b48c5f0483ff4ef5ef7bd4858fa95 +cksum=126073822 upstream_url=https://pypi.io/packages/py3/n/nbconvert/nbconvert-VERSION-py3-none-any.whl diff --git a/build/pkgs/nbconvert/package-version.txt b/build/pkgs/nbconvert/package-version.txt index 429dc57af3a..2de5f33fb8c 100644 --- a/build/pkgs/nbconvert/package-version.txt +++ b/build/pkgs/nbconvert/package-version.txt @@ -1 +1 @@ -7.2.3 +7.7.4 From eeb45090ece7779c769b3d1b8dcf27e60f9d92a1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 23:12:55 -0700 Subject: [PATCH 361/463] build/pkgs/nbclient: Update to 0.8.0 --- build/pkgs/nbclient/checksums.ini | 6 +++--- build/pkgs/nbclient/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/nbclient/checksums.ini b/build/pkgs/nbclient/checksums.ini index 459341ff20e..0de2ad1f91d 100644 --- a/build/pkgs/nbclient/checksums.ini +++ b/build/pkgs/nbclient/checksums.ini @@ -1,5 +1,5 @@ tarball=nbclient-VERSION.tar.gz -sha1=8f6309bc37fb2c5b49fcdfe835b6ef9762fa583c -md5=6a59800791be74079cf2ade421526289 -cksum=1870577652 +sha1=1976f9f340cac979ba49ce9d270a1f1fda5063b9 +md5=57ad77589339fb970fe67c0d1a8e3f5c +cksum=3517283210 upstream_url=https://pypi.io/packages/source/n/nbclient/nbclient-VERSION.tar.gz diff --git a/build/pkgs/nbclient/package-version.txt b/build/pkgs/nbclient/package-version.txt index faef31a4357..a3df0a6959e 100644 --- a/build/pkgs/nbclient/package-version.txt +++ b/build/pkgs/nbclient/package-version.txt @@ -1 +1 @@ -0.7.0 +0.8.0 From 3ff79369703b56c4586bea3c69c3aa377afab02d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 23:13:15 -0700 Subject: [PATCH 362/463] build/pkgs/pygments: Update to 2.16.1 --- build/pkgs/pygments/checksums.ini | 6 +++--- build/pkgs/pygments/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/pygments/checksums.ini b/build/pkgs/pygments/checksums.ini index 14fc1c04cdb..5bd874eaaf6 100644 --- a/build/pkgs/pygments/checksums.ini +++ b/build/pkgs/pygments/checksums.ini @@ -1,5 +1,5 @@ tarball=Pygments-VERSION.tar.gz -sha1=adaf31bf13a7bcc210568537138e0984ecdea626 -md5=6ccae578d28d18968b30a4711652fd9a -cksum=613387624 +sha1=7d9a2dcf63799c011033529b326ba3d1b2900c38 +md5=20cb967029c23389253326cf515dec8a +cksum=601328323 upstream_url=https://pypi.io/packages/source/p/pygments/Pygments-VERSION.tar.gz diff --git a/build/pkgs/pygments/package-version.txt b/build/pkgs/pygments/package-version.txt index fb2c0766b7c..0e7079b6911 100644 --- a/build/pkgs/pygments/package-version.txt +++ b/build/pkgs/pygments/package-version.txt @@ -1 +1 @@ -2.13.0 +2.16.1 From 4573fb82609ce4dea198ecfa5e8d925fcf07fbb9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 23:15:02 -0700 Subject: [PATCH 363/463] build/pkgs/nest_asyncio: Update to 1.5.7 --- build/pkgs/nest_asyncio/checksums.ini | 6 +++--- build/pkgs/nest_asyncio/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/nest_asyncio/checksums.ini b/build/pkgs/nest_asyncio/checksums.ini index 1a11eb5178b..498f877da48 100644 --- a/build/pkgs/nest_asyncio/checksums.ini +++ b/build/pkgs/nest_asyncio/checksums.ini @@ -1,5 +1,5 @@ tarball=nest_asyncio-VERSION.tar.gz -sha1=1e862862afe4c2e057065212eefe7203ccee4927 -md5=7c7108921a64e7abbb6993803343819b -cksum=982689987 +sha1=cba134c03c8a01f798de46f62755e0813b6b4556 +md5=577ade8444e1429c62b63854e5e67c3d +cksum=334638127 upstream_url=https://pypi.io/packages/source/n/nest_asyncio/nest_asyncio-VERSION.tar.gz diff --git a/build/pkgs/nest_asyncio/package-version.txt b/build/pkgs/nest_asyncio/package-version.txt index eac1e0ada6d..f01291b87fd 100644 --- a/build/pkgs/nest_asyncio/package-version.txt +++ b/build/pkgs/nest_asyncio/package-version.txt @@ -1 +1 @@ -1.5.6 +1.5.7 From 574d18a8d5a7b9c8cd58332fa749994fe315dee9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 23:15:40 -0700 Subject: [PATCH 364/463] build/pkgs/tornado: Update to 6.3.3 --- build/pkgs/tornado/checksums.ini | 6 +++--- build/pkgs/tornado/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/tornado/checksums.ini b/build/pkgs/tornado/checksums.ini index 9f69d85d5dc..46e14d34d98 100644 --- a/build/pkgs/tornado/checksums.ini +++ b/build/pkgs/tornado/checksums.ini @@ -1,5 +1,5 @@ tarball=tornado-VERSION.tar.gz -sha1=2fa6cbd83ebafad83f49e89fbd5bbd20c42bbdc9 -md5=32fbad606b439c3e1bf4e79d4e872741 -cksum=3183867326 +sha1=de0ef2eb77e7ca1ba1210bd02d56d9494b413cd7 +md5=e5fca0b30397bbdfe1f5e8e49e6cacf9 +cksum=327419258 upstream_url=https://pypi.io/packages/source/t/tornado/tornado-VERSION.tar.gz diff --git a/build/pkgs/tornado/package-version.txt b/build/pkgs/tornado/package-version.txt index 0cda48ac61e..7849b73dc74 100644 --- a/build/pkgs/tornado/package-version.txt +++ b/build/pkgs/tornado/package-version.txt @@ -1 +1 @@ -6.2 +6.3.3 From 3ccb36ea3e914ef8b9f4dfcbd190e714749504ba Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 23:15:47 -0700 Subject: [PATCH 365/463] build/pkgs/terminado: Update to 0.17.1 --- build/pkgs/terminado/checksums.ini | 6 +++--- build/pkgs/terminado/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/terminado/checksums.ini b/build/pkgs/terminado/checksums.ini index 27333946973..be9b273fa2b 100644 --- a/build/pkgs/terminado/checksums.ini +++ b/build/pkgs/terminado/checksums.ini @@ -1,5 +1,5 @@ tarball=terminado-VERSION.tar.gz -sha1=e2e37fe16c03d5bb6ab035c78e99a89bc742384c -md5=cf5f5f7dd1ece772f16013ad355b75e1 -cksum=2626848318 +sha1=608fcc44b845e1fb783e361d59e79fba83126e14 +md5=aafcc42623986e42469712786edb127c +cksum=3344744872 upstream_url=https://pypi.io/packages/source/t/terminado/terminado-VERSION.tar.gz diff --git a/build/pkgs/terminado/package-version.txt b/build/pkgs/terminado/package-version.txt index c5523bd09b1..7cca7711a0d 100644 --- a/build/pkgs/terminado/package-version.txt +++ b/build/pkgs/terminado/package-version.txt @@ -1 +1 @@ -0.17.0 +0.17.1 From c1818d5c4afb993764db6076a50a79f708fee92c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 23:16:27 -0700 Subject: [PATCH 366/463] build/pkgs/nbformat: Update to 5.9.2 --- build/pkgs/nbformat/checksums.ini | 6 +++--- build/pkgs/nbformat/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/nbformat/checksums.ini b/build/pkgs/nbformat/checksums.ini index af04e4f35aa..2de2adc25d0 100644 --- a/build/pkgs/nbformat/checksums.ini +++ b/build/pkgs/nbformat/checksums.ini @@ -1,5 +1,5 @@ tarball=nbformat-VERSION.tar.gz -sha1=ecad83c07bdc475f6fd88d28485cf8fe31fbba41 -md5=5e11cc3240d4b1410610786309cc6076 -cksum=767940068 +sha1=cead65d27023c88f202b863f8c06451036cd0d2b +md5=091fcdb13305ad00e92f5bb3fb86d2fd +cksum=3366926154 upstream_url=https://pypi.io/packages/source/n/nbformat/nbformat-VERSION.tar.gz diff --git a/build/pkgs/nbformat/package-version.txt b/build/pkgs/nbformat/package-version.txt index 42cdd0b540f..da902181863 100644 --- a/build/pkgs/nbformat/package-version.txt +++ b/build/pkgs/nbformat/package-version.txt @@ -1 +1 @@ -5.7.0 +5.9.2 From 270fad133518942dd8d0dc13f10a50e11bb213ba Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 23:25:37 -0700 Subject: [PATCH 367/463] build/pkgs/jsonschema: Update to 4.19.0 --- build/pkgs/jsonschema/checksums.ini | 6 +++--- build/pkgs/jsonschema/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jsonschema/checksums.ini b/build/pkgs/jsonschema/checksums.ini index 5a214ae38fc..ef654eabc2f 100644 --- a/build/pkgs/jsonschema/checksums.ini +++ b/build/pkgs/jsonschema/checksums.ini @@ -1,5 +1,5 @@ tarball=jsonschema-VERSION.tar.gz -sha1=ccea159a8a0c453e6fbbcfd7bb681b1bc766500e -md5=527bc4d51d31e8d0b8a0d833b6a50002 -cksum=1885537635 +sha1=0a2d0389e93c688e841d3c84a9edda2d44e645a7 +md5=d24cdf4e2010efe22bd144a75661cece +cksum=1595590979 upstream_url=https://pypi.io/packages/source/j/jsonschema/jsonschema-VERSION.tar.gz diff --git a/build/pkgs/jsonschema/package-version.txt b/build/pkgs/jsonschema/package-version.txt index 1b0a87fdfc9..a69aa5a4289 100644 --- a/build/pkgs/jsonschema/package-version.txt +++ b/build/pkgs/jsonschema/package-version.txt @@ -1 +1 @@ -4.17.1 +4.19.0 From 96d6a2a9aa6212d3c27e9a39def58ce8cb6a572d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 23 Aug 2023 23:26:04 -0700 Subject: [PATCH 368/463] build/pkgs/jupyterlab_pygments: Update to 0.2.2 --- build/pkgs/jupyterlab_pygments/checksums.ini | 6 +++--- build/pkgs/jupyterlab_pygments/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyterlab_pygments/checksums.ini b/build/pkgs/jupyterlab_pygments/checksums.ini index dbcf15bf6fd..2735f74af42 100644 --- a/build/pkgs/jupyterlab_pygments/checksums.ini +++ b/build/pkgs/jupyterlab_pygments/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyterlab_pygments-VERSION.tar.gz -sha1=1c2b2ffc2d4a5fa2a7b5143f68b742758de39bd2 -md5=beb54b1cf0bd25b53549efc4824f7fea -cksum=3472265164 +sha1=6b40ef8867ec8e66d0712556a9f2a861efdcc748 +md5=7d2d54eb4e52513dd38eae8baac68d9b +cksum=1191389557 upstream_url=https://pypi.io/packages/source/j/jupyterlab_pygments/jupyterlab_pygments-VERSION.tar.gz diff --git a/build/pkgs/jupyterlab_pygments/package-version.txt b/build/pkgs/jupyterlab_pygments/package-version.txt index d917d3e26ad..ee1372d33a2 100644 --- a/build/pkgs/jupyterlab_pygments/package-version.txt +++ b/build/pkgs/jupyterlab_pygments/package-version.txt @@ -1 +1 @@ -0.1.2 +0.2.2 From bbd4a5523de25872c2079701deb99d1b76aae42d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:11:08 -0700 Subject: [PATCH 369/463] build/pkgs/jupyterlab_pygments: Change to wheel package --- build/pkgs/jupyter_core/dependencies | 2 +- build/pkgs/jupyter_events/dependencies | 2 +- build/pkgs/jupyter_server/dependencies | 2 +- build/pkgs/jupyter_server_terminals/dependencies | 2 +- build/pkgs/jupyterlab_pygments/checksums.ini | 10 +++++----- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/build/pkgs/jupyter_core/dependencies b/build/pkgs/jupyter_core/dependencies index a312196cbed..0e3bf021c04 100644 --- a/build/pkgs/jupyter_core/dependencies +++ b/build/pkgs/jupyter_core/dependencies @@ -1,4 +1,4 @@ - traitlets | $(PYTHON_TOOLCHAIN) hatchling $(PYTHON) +platformdirs traitlets | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_events/dependencies b/build/pkgs/jupyter_events/dependencies index 0738c2d7777..5188bfbe16e 100644 --- a/build/pkgs/jupyter_events/dependencies +++ b/build/pkgs/jupyter_events/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) jsonschema | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_server/dependencies b/build/pkgs/jupyter_server/dependencies index ebedc8ea498..2c70b9a3343 100644 --- a/build/pkgs/jupyter_server/dependencies +++ b/build/pkgs/jupyter_server/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) anyio | $(PYTHON_TOOLCHAIN) +$(PYTHON) anyio argon2_cffi jinja2 jupyter_client jupyter_core jupyter_events jupyter_server_terminals nbconvert nbformat overrides platformdirs prometheus_client pyzmq send2trash terminado tornado traitlets websocket_client | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_server_terminals/dependencies b/build/pkgs/jupyter_server_terminals/dependencies index 0738c2d7777..13b93d5c952 100644 --- a/build/pkgs/jupyter_server_terminals/dependencies +++ b/build/pkgs/jupyter_server_terminals/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) terminado | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyterlab_pygments/checksums.ini b/build/pkgs/jupyterlab_pygments/checksums.ini index 2735f74af42..6f5af4d8afd 100644 --- a/build/pkgs/jupyterlab_pygments/checksums.ini +++ b/build/pkgs/jupyterlab_pygments/checksums.ini @@ -1,5 +1,5 @@ -tarball=jupyterlab_pygments-VERSION.tar.gz -sha1=6b40ef8867ec8e66d0712556a9f2a861efdcc748 -md5=7d2d54eb4e52513dd38eae8baac68d9b -cksum=1191389557 -upstream_url=https://pypi.io/packages/source/j/jupyterlab_pygments/jupyterlab_pygments-VERSION.tar.gz +tarball=jupyterlab_pygments-VERSION-py2.py3-none-any.whl +sha1=601f547767fa867494ff0764891807904b8ebbd2 +md5=44194b8e643cf025ec3a91f0c751c7d7 +cksum=4169885263 +upstream_url=https://pypi.io/packages/py2.py3/j/jupyterlab_pygments/jupyterlab_pygments-VERSION-py2.py3-none-any.whl From c929fae7d470a44ccb74764786de21039ab166b3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:00:06 -0700 Subject: [PATCH 370/463] Fix deps --- build/pkgs/jupyter_events/dependencies | 2 +- build/pkgs/notebook/dependencies | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/pkgs/jupyter_events/dependencies b/build/pkgs/jupyter_events/dependencies index 5188bfbe16e..c531f1115dd 100644 --- a/build/pkgs/jupyter_events/dependencies +++ b/build/pkgs/jupyter_events/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) jsonschema | $(PYTHON_TOOLCHAIN) +$(PYTHON) jsonschema python_json_logger | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/notebook/dependencies b/build/pkgs/notebook/dependencies index 97d97af24c5..8e12e180efe 100644 --- a/build/pkgs/notebook/dependencies +++ b/build/pkgs/notebook/dependencies @@ -1,4 +1,4 @@ -jupyter_server | $(PYTHON_TOOLCHAIN) $(PYTHON) +jupyter_server jupyterlab_server | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. From 265bc2884161212aa4c980875946aee3a472360c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 10:57:29 -0700 Subject: [PATCH 371/463] build/pkgs/jupyterlab_server: New (notebook dep) --- build/pkgs/jupyterlab_server/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/jupyterlab_server/checksums.ini | 5 +++++ build/pkgs/jupyterlab_server/dependencies | 4 ++++ .../jupyterlab_server/install-requires.txt | 1 + .../pkgs/jupyterlab_server/package-version.txt | 1 + build/pkgs/jupyterlab_server/type | 1 + 6 files changed, 30 insertions(+) create mode 100644 build/pkgs/jupyterlab_server/SPKG.rst create mode 100644 build/pkgs/jupyterlab_server/checksums.ini create mode 100644 build/pkgs/jupyterlab_server/dependencies create mode 100644 build/pkgs/jupyterlab_server/install-requires.txt create mode 100644 build/pkgs/jupyterlab_server/package-version.txt create mode 100644 build/pkgs/jupyterlab_server/type diff --git a/build/pkgs/jupyterlab_server/SPKG.rst b/build/pkgs/jupyterlab_server/SPKG.rst new file mode 100644 index 00000000000..aca71f627ec --- /dev/null +++ b/build/pkgs/jupyterlab_server/SPKG.rst @@ -0,0 +1,18 @@ +jupyterlab_server: A set of server components for JupyterLab and JupyterLab like applications. +============================================================================================== + +Description +----------- + +A set of server components for JupyterLab and JupyterLab like applications. + +License +------- + +Copyright (c) 2015-2017, Project Jupyter Contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Upstream Contact +---------------- + +https://pypi.org/project/jupyterlab-server/ + diff --git a/build/pkgs/jupyterlab_server/checksums.ini b/build/pkgs/jupyterlab_server/checksums.ini new file mode 100644 index 00000000000..3bd8926fd7b --- /dev/null +++ b/build/pkgs/jupyterlab_server/checksums.ini @@ -0,0 +1,5 @@ +tarball=jupyterlab_server-VERSION-py3-none-any.whl +sha1=1fff8c8bc4c81b006cb83d4524dc8a6f3364e57c +md5=795bbf343ae17b75a31a50ef574d4b77 +cksum=696988100 +upstream_url=https://pypi.io/packages/py3/j/jupyterlab_server/jupyterlab_server-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab_server/dependencies b/build/pkgs/jupyterlab_server/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/jupyterlab_server/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyterlab_server/install-requires.txt b/build/pkgs/jupyterlab_server/install-requires.txt new file mode 100644 index 00000000000..06b850a61cc --- /dev/null +++ b/build/pkgs/jupyterlab_server/install-requires.txt @@ -0,0 +1 @@ +jupyterlab-server diff --git a/build/pkgs/jupyterlab_server/package-version.txt b/build/pkgs/jupyterlab_server/package-version.txt new file mode 100644 index 00000000000..ad2261920c0 --- /dev/null +++ b/build/pkgs/jupyterlab_server/package-version.txt @@ -0,0 +1 @@ +2.24.0 diff --git a/build/pkgs/jupyterlab_server/type b/build/pkgs/jupyterlab_server/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/jupyterlab_server/type @@ -0,0 +1 @@ +standard From 0d41b7aa65838ea7ec98a92c2d8a7103079f2455 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:00:46 -0700 Subject: [PATCH 372/463] build/pkgs/jupyterlab: Change to a wheel package --- build/pkgs/jupyterlab/SPKG.rst | 11 +++++------ build/pkgs/jupyterlab/checksums.ini | 5 +++++ build/pkgs/jupyterlab/dependencies | 2 +- build/pkgs/jupyterlab/install-requires.txt | 1 + build/pkgs/jupyterlab/package-version.txt | 1 + build/pkgs/jupyterlab/requirements.txt | 3 --- 6 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 build/pkgs/jupyterlab/checksums.ini create mode 100644 build/pkgs/jupyterlab/install-requires.txt create mode 100644 build/pkgs/jupyterlab/package-version.txt delete mode 100644 build/pkgs/jupyterlab/requirements.txt diff --git a/build/pkgs/jupyterlab/SPKG.rst b/build/pkgs/jupyterlab/SPKG.rst index f728314ffae..728448f7f71 100644 --- a/build/pkgs/jupyterlab/SPKG.rst +++ b/build/pkgs/jupyterlab/SPKG.rst @@ -1,19 +1,18 @@ -jupyterlab: An extensible environment for interactive and reproducible computing -================================================================================ +jupyterlab: JupyterLab computational environment +================================================ Description ----------- -An extensible environment for interactive and reproducible computing, -based on the Jupyter Notebook and Architecture. +JupyterLab computational environment License ------- -BSD License +Copyright (c) 2015-2022 Project Jupyter Contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Semver File License =================== The semver.py file is from https://github.com/podhmo/python-semver which is licensed under the "MIT" license. See the semver.py file for details. Upstream Contact ---------------- -Home page: https://jupyter.org/ +https://pypi.org/project/jupyterlab/ diff --git a/build/pkgs/jupyterlab/checksums.ini b/build/pkgs/jupyterlab/checksums.ini new file mode 100644 index 00000000000..8dba14bbe00 --- /dev/null +++ b/build/pkgs/jupyterlab/checksums.ini @@ -0,0 +1,5 @@ +tarball=jupyterlab-VERSION-py3-none-any.whl +sha1=eb08c6639c36d0a4ba39f123d352f9a04cb74a00 +md5=0f98f63b89302b61495454b346add431 +cksum=3453842466 +upstream_url=https://pypi.io/packages/py3/j/jupyterlab/jupyterlab-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab/dependencies b/build/pkgs/jupyterlab/dependencies index 059006650e1..47296a7bace 100644 --- a/build/pkgs/jupyterlab/dependencies +++ b/build/pkgs/jupyterlab/dependencies @@ -1,4 +1,4 @@ - vcversioner jupyter_core jupyter_client jinja2 tornado ipython packaging terminado traitlets nbconvert send2trash nbformat prometheus_client ipython_genutils argon2_cffi pyzmq idna requests jsonschema babel notebook | $(PYTHON_TOOLCHAIN) $(PYTHON) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyterlab/install-requires.txt b/build/pkgs/jupyterlab/install-requires.txt new file mode 100644 index 00000000000..c9356a72837 --- /dev/null +++ b/build/pkgs/jupyterlab/install-requires.txt @@ -0,0 +1 @@ +jupyterlab diff --git a/build/pkgs/jupyterlab/package-version.txt b/build/pkgs/jupyterlab/package-version.txt new file mode 100644 index 00000000000..7636e75650d --- /dev/null +++ b/build/pkgs/jupyterlab/package-version.txt @@ -0,0 +1 @@ +4.0.5 diff --git a/build/pkgs/jupyterlab/requirements.txt b/build/pkgs/jupyterlab/requirements.txt deleted file mode 100644 index f03a26674fd..00000000000 --- a/build/pkgs/jupyterlab/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -jupyterlab ~= 3.3 -# See https://github.com/sagemath/sage/issues/33607 -jupyterlab-server < 2.11 From 00796537c5a6e58b007b8b2f3180502e16388652 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:01:23 -0700 Subject: [PATCH 373/463] build/pkgs/{async_lru,jupyter_lsp,notebook_shim}: New (jupyterlab deps) --- build/pkgs/async_lru/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/async_lru/checksums.ini | 5 +++++ build/pkgs/async_lru/dependencies | 4 ++++ build/pkgs/async_lru/install-requires.txt | 1 + build/pkgs/async_lru/package-version.txt | 1 + build/pkgs/async_lru/type | 1 + build/pkgs/jupyter_lsp/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/jupyter_lsp/checksums.ini | 5 +++++ build/pkgs/jupyter_lsp/dependencies | 4 ++++ build/pkgs/jupyter_lsp/install-requires.txt | 1 + build/pkgs/jupyter_lsp/package-version.txt | 1 + build/pkgs/jupyter_lsp/type | 1 + build/pkgs/jupyterlab/dependencies | 2 +- build/pkgs/jupyterlab/type | 2 +- build/pkgs/jupyterlab_server/dependencies | 2 +- build/pkgs/notebook_shim/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/notebook_shim/checksums.ini | 5 +++++ build/pkgs/notebook_shim/dependencies | 4 ++++ build/pkgs/notebook_shim/install-requires.txt | 1 + build/pkgs/notebook_shim/package-version.txt | 1 + build/pkgs/notebook_shim/type | 1 + 21 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 build/pkgs/async_lru/SPKG.rst create mode 100644 build/pkgs/async_lru/checksums.ini create mode 100644 build/pkgs/async_lru/dependencies create mode 100644 build/pkgs/async_lru/install-requires.txt create mode 100644 build/pkgs/async_lru/package-version.txt create mode 100644 build/pkgs/async_lru/type create mode 100644 build/pkgs/jupyter_lsp/SPKG.rst create mode 100644 build/pkgs/jupyter_lsp/checksums.ini create mode 100644 build/pkgs/jupyter_lsp/dependencies create mode 100644 build/pkgs/jupyter_lsp/install-requires.txt create mode 100644 build/pkgs/jupyter_lsp/package-version.txt create mode 100644 build/pkgs/jupyter_lsp/type create mode 100644 build/pkgs/notebook_shim/SPKG.rst create mode 100644 build/pkgs/notebook_shim/checksums.ini create mode 100644 build/pkgs/notebook_shim/dependencies create mode 100644 build/pkgs/notebook_shim/install-requires.txt create mode 100644 build/pkgs/notebook_shim/package-version.txt create mode 100644 build/pkgs/notebook_shim/type diff --git a/build/pkgs/async_lru/SPKG.rst b/build/pkgs/async_lru/SPKG.rst new file mode 100644 index 00000000000..069608d47c6 --- /dev/null +++ b/build/pkgs/async_lru/SPKG.rst @@ -0,0 +1,18 @@ +async_lru: Simple LRU cache for asyncio +======================================= + +Description +----------- + +Simple LRU cache for asyncio + +License +------- + +MIT License + +Upstream Contact +---------------- + +https://pypi.org/project/async-lru/ + diff --git a/build/pkgs/async_lru/checksums.ini b/build/pkgs/async_lru/checksums.ini new file mode 100644 index 00000000000..1a289cb63c3 --- /dev/null +++ b/build/pkgs/async_lru/checksums.ini @@ -0,0 +1,5 @@ +tarball=async_lru-VERSION-py3-none-any.whl +sha1=99b2ea5d551cbad28e08e45f0d0b00827f9ff73d +md5=de1e9e7559810690de8b7084b372d9a2 +cksum=3326301475 +upstream_url=https://pypi.io/packages/py3/a/async_lru/async_lru-VERSION-py3-none-any.whl diff --git a/build/pkgs/async_lru/dependencies b/build/pkgs/async_lru/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/async_lru/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/async_lru/install-requires.txt b/build/pkgs/async_lru/install-requires.txt new file mode 100644 index 00000000000..c289e49b9fa --- /dev/null +++ b/build/pkgs/async_lru/install-requires.txt @@ -0,0 +1 @@ +async-lru diff --git a/build/pkgs/async_lru/package-version.txt b/build/pkgs/async_lru/package-version.txt new file mode 100644 index 00000000000..2165f8f9b6a --- /dev/null +++ b/build/pkgs/async_lru/package-version.txt @@ -0,0 +1 @@ +2.0.4 diff --git a/build/pkgs/async_lru/type b/build/pkgs/async_lru/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/async_lru/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/jupyter_lsp/SPKG.rst b/build/pkgs/jupyter_lsp/SPKG.rst new file mode 100644 index 00000000000..ec6e3bf4e03 --- /dev/null +++ b/build/pkgs/jupyter_lsp/SPKG.rst @@ -0,0 +1,18 @@ +jupyter_lsp: Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server +================================================================================== + +Description +----------- + +Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server + +License +------- + +BSD-3-Clause + +Upstream Contact +---------------- + +https://pypi.org/project/jupyter-lsp/ + diff --git a/build/pkgs/jupyter_lsp/checksums.ini b/build/pkgs/jupyter_lsp/checksums.ini new file mode 100644 index 00000000000..0e0a2cbf90e --- /dev/null +++ b/build/pkgs/jupyter_lsp/checksums.ini @@ -0,0 +1,5 @@ +tarball=jupyter_lsp-VERSION-py3-none-any.whl +sha1=0f7a63d99c5cf624315583099f00eafc4b996b59 +md5=9c17daaa4372bffca936c1b6977e713b +cksum=1933820697 +upstream_url=https://pypi.io/packages/py3/j/jupyter_lsp/jupyter_lsp-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_lsp/dependencies b/build/pkgs/jupyter_lsp/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/jupyter_lsp/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_lsp/install-requires.txt b/build/pkgs/jupyter_lsp/install-requires.txt new file mode 100644 index 00000000000..367c01e01a1 --- /dev/null +++ b/build/pkgs/jupyter_lsp/install-requires.txt @@ -0,0 +1 @@ +jupyter-lsp diff --git a/build/pkgs/jupyter_lsp/package-version.txt b/build/pkgs/jupyter_lsp/package-version.txt new file mode 100644 index 00000000000..ccbccc3dc62 --- /dev/null +++ b/build/pkgs/jupyter_lsp/package-version.txt @@ -0,0 +1 @@ +2.2.0 diff --git a/build/pkgs/jupyter_lsp/type b/build/pkgs/jupyter_lsp/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/jupyter_lsp/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/jupyterlab/dependencies b/build/pkgs/jupyterlab/dependencies index 47296a7bace..5d2f8f03d6a 100644 --- a/build/pkgs/jupyterlab/dependencies +++ b/build/pkgs/jupyterlab/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) +async_lru importlib_metadata ipykernel jinja2 jupyter_core jupyter_lsp jupyter_server jupyterlab_server notebook_shim packaging traitlets tornado tomli | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyterlab/type b/build/pkgs/jupyterlab/type index 134d9bc32d5..a6a7b9cd726 100644 --- a/build/pkgs/jupyterlab/type +++ b/build/pkgs/jupyterlab/type @@ -1 +1 @@ -optional +standard diff --git a/build/pkgs/jupyterlab_server/dependencies b/build/pkgs/jupyterlab_server/dependencies index 0738c2d7777..8b16f17f168 100644 --- a/build/pkgs/jupyterlab_server/dependencies +++ b/build/pkgs/jupyterlab_server/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) babel jupyterlab | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/notebook_shim/SPKG.rst b/build/pkgs/notebook_shim/SPKG.rst new file mode 100644 index 00000000000..3ed2cb01e0d --- /dev/null +++ b/build/pkgs/notebook_shim/SPKG.rst @@ -0,0 +1,18 @@ +notebook_shim: A shim layer for notebook traits and config +========================================================== + +Description +----------- + +A shim layer for notebook traits and config + +License +------- + +BSD 3-Clause License Copyright (c) 2022 Project Jupyter Contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Upstream Contact +---------------- + +https://pypi.org/project/notebook-shim/ + diff --git a/build/pkgs/notebook_shim/checksums.ini b/build/pkgs/notebook_shim/checksums.ini new file mode 100644 index 00000000000..c646e5c3ae9 --- /dev/null +++ b/build/pkgs/notebook_shim/checksums.ini @@ -0,0 +1,5 @@ +tarball=notebook_shim-VERSION-py3-none-any.whl +sha1=9bb3dce360ce69aec99f873d8e80c1e9fdf92fde +md5=f2207bef3d00f9b2dc14b0eeec63460d +cksum=2703250856 +upstream_url=https://pypi.io/packages/py3/n/notebook_shim/notebook_shim-VERSION-py3-none-any.whl diff --git a/build/pkgs/notebook_shim/dependencies b/build/pkgs/notebook_shim/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/notebook_shim/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/notebook_shim/install-requires.txt b/build/pkgs/notebook_shim/install-requires.txt new file mode 100644 index 00000000000..73d88bc8706 --- /dev/null +++ b/build/pkgs/notebook_shim/install-requires.txt @@ -0,0 +1 @@ +notebook-shim diff --git a/build/pkgs/notebook_shim/package-version.txt b/build/pkgs/notebook_shim/package-version.txt new file mode 100644 index 00000000000..7179039691c --- /dev/null +++ b/build/pkgs/notebook_shim/package-version.txt @@ -0,0 +1 @@ +0.2.3 diff --git a/build/pkgs/notebook_shim/type b/build/pkgs/notebook_shim/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/notebook_shim/type @@ -0,0 +1 @@ +standard From 082f8335bf0a1cfe5edd01e5462a990ee5582503 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:02:06 -0700 Subject: [PATCH 374/463] build/pkgs/{pyyaml,referencing,rfc3339_validator,rfc3986_validator,json5}: New (jupyterlab_server/notebook/jupyter_events deps) --- build/pkgs/json5/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/json5/checksums.ini | 5 +++++ build/pkgs/json5/dependencies | 4 ++++ build/pkgs/json5/install-requires.txt | 1 + build/pkgs/json5/package-version.txt | 1 + build/pkgs/json5/type | 1 + build/pkgs/jupyter_events/dependencies | 2 +- build/pkgs/jupyterlab_server/dependencies | 2 +- build/pkgs/notebook/dependencies | 2 +- build/pkgs/pyyaml/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/pyyaml/checksums.ini | 5 +++++ build/pkgs/pyyaml/dependencies | 4 ++++ build/pkgs/pyyaml/install-requires.txt | 1 + build/pkgs/pyyaml/package-version.txt | 1 + build/pkgs/pyyaml/spkg-install.in | 2 ++ build/pkgs/pyyaml/type | 1 + build/pkgs/referencing/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/referencing/checksums.ini | 5 +++++ build/pkgs/referencing/dependencies | 4 ++++ build/pkgs/referencing/install-requires.txt | 1 + build/pkgs/referencing/package-version.txt | 1 + build/pkgs/referencing/type | 1 + build/pkgs/rfc3339_validator/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/rfc3339_validator/checksums.ini | 5 +++++ build/pkgs/rfc3339_validator/dependencies | 4 ++++ .../rfc3339_validator/install-requires.txt | 1 + .../pkgs/rfc3339_validator/package-version.txt | 1 + build/pkgs/rfc3339_validator/type | 1 + build/pkgs/rfc3986_validator/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/rfc3986_validator/checksums.ini | 5 +++++ build/pkgs/rfc3986_validator/dependencies | 4 ++++ .../rfc3986_validator/install-requires.txt | 1 + .../pkgs/rfc3986_validator/package-version.txt | 1 + build/pkgs/rfc3986_validator/type | 1 + 34 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 build/pkgs/json5/SPKG.rst create mode 100644 build/pkgs/json5/checksums.ini create mode 100644 build/pkgs/json5/dependencies create mode 100644 build/pkgs/json5/install-requires.txt create mode 100644 build/pkgs/json5/package-version.txt create mode 100644 build/pkgs/json5/type create mode 100644 build/pkgs/pyyaml/SPKG.rst create mode 100644 build/pkgs/pyyaml/checksums.ini create mode 100644 build/pkgs/pyyaml/dependencies create mode 100644 build/pkgs/pyyaml/install-requires.txt create mode 100644 build/pkgs/pyyaml/package-version.txt create mode 100644 build/pkgs/pyyaml/spkg-install.in create mode 100644 build/pkgs/pyyaml/type create mode 100644 build/pkgs/referencing/SPKG.rst create mode 100644 build/pkgs/referencing/checksums.ini create mode 100644 build/pkgs/referencing/dependencies create mode 100644 build/pkgs/referencing/install-requires.txt create mode 100644 build/pkgs/referencing/package-version.txt create mode 100644 build/pkgs/referencing/type create mode 100644 build/pkgs/rfc3339_validator/SPKG.rst create mode 100644 build/pkgs/rfc3339_validator/checksums.ini create mode 100644 build/pkgs/rfc3339_validator/dependencies create mode 100644 build/pkgs/rfc3339_validator/install-requires.txt create mode 100644 build/pkgs/rfc3339_validator/package-version.txt create mode 100644 build/pkgs/rfc3339_validator/type create mode 100644 build/pkgs/rfc3986_validator/SPKG.rst create mode 100644 build/pkgs/rfc3986_validator/checksums.ini create mode 100644 build/pkgs/rfc3986_validator/dependencies create mode 100644 build/pkgs/rfc3986_validator/install-requires.txt create mode 100644 build/pkgs/rfc3986_validator/package-version.txt create mode 100644 build/pkgs/rfc3986_validator/type diff --git a/build/pkgs/json5/SPKG.rst b/build/pkgs/json5/SPKG.rst new file mode 100644 index 00000000000..5f85e534785 --- /dev/null +++ b/build/pkgs/json5/SPKG.rst @@ -0,0 +1,18 @@ +json5: A Python implementation of the JSON5 data format. +======================================================== + +Description +----------- + +A Python implementation of the JSON5 data format. + +License +------- + +Apache + +Upstream Contact +---------------- + +https://pypi.org/project/json5/ + diff --git a/build/pkgs/json5/checksums.ini b/build/pkgs/json5/checksums.ini new file mode 100644 index 00000000000..5e05994b435 --- /dev/null +++ b/build/pkgs/json5/checksums.ini @@ -0,0 +1,5 @@ +tarball=json5-VERSION-py2.py3-none-any.whl +sha1=54bf91b9c2812e82ccd212cefca5bc5607a538b4 +md5=aede9af2a42cc0cd928e4dc99e9a6a45 +cksum=134804175 +upstream_url=https://pypi.io/packages/py2.py3/j/json5/json5-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/json5/dependencies b/build/pkgs/json5/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/json5/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/json5/install-requires.txt b/build/pkgs/json5/install-requires.txt new file mode 100644 index 00000000000..8c1150297b3 --- /dev/null +++ b/build/pkgs/json5/install-requires.txt @@ -0,0 +1 @@ +json5 diff --git a/build/pkgs/json5/package-version.txt b/build/pkgs/json5/package-version.txt new file mode 100644 index 00000000000..6d44d227cf9 --- /dev/null +++ b/build/pkgs/json5/package-version.txt @@ -0,0 +1 @@ +0.9.14 diff --git a/build/pkgs/json5/type b/build/pkgs/json5/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/json5/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/jupyter_events/dependencies b/build/pkgs/jupyter_events/dependencies index c531f1115dd..62262a4456c 100644 --- a/build/pkgs/jupyter_events/dependencies +++ b/build/pkgs/jupyter_events/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) jsonschema python_json_logger | $(PYTHON_TOOLCHAIN) +$(PYTHON) jsonschema python_json_logger pyyaml referencing rfc3339_validator rfc3986_validator | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyterlab_server/dependencies b/build/pkgs/jupyterlab_server/dependencies index 8b16f17f168..91cf86c044f 100644 --- a/build/pkgs/jupyterlab_server/dependencies +++ b/build/pkgs/jupyterlab_server/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) babel jupyterlab | $(PYTHON_TOOLCHAIN) +$(PYTHON) babel jupyterlab json5 requests | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/notebook/dependencies b/build/pkgs/notebook/dependencies index 8e12e180efe..3d42b5cbcc8 100644 --- a/build/pkgs/notebook/dependencies +++ b/build/pkgs/notebook/dependencies @@ -1,4 +1,4 @@ -jupyter_server jupyterlab_server | $(PYTHON_TOOLCHAIN) $(PYTHON) +$(PYTHON) jupyter_server jupyterlab_server jupyterlab notebook_shim | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/pyyaml/SPKG.rst b/build/pkgs/pyyaml/SPKG.rst new file mode 100644 index 00000000000..34b6fdcd32c --- /dev/null +++ b/build/pkgs/pyyaml/SPKG.rst @@ -0,0 +1,18 @@ +pyyaml: YAML parser and emitter for Python +========================================== + +Description +----------- + +YAML parser and emitter for Python + +License +------- + +MIT + +Upstream Contact +---------------- + +https://pypi.org/project/PyYAML/ + diff --git a/build/pkgs/pyyaml/checksums.ini b/build/pkgs/pyyaml/checksums.ini new file mode 100644 index 00000000000..6918d8fda58 --- /dev/null +++ b/build/pkgs/pyyaml/checksums.ini @@ -0,0 +1,5 @@ +tarball=PyYAML-VERSION.tar.gz +sha1=a80d802ad8f693bed34c8fb5ee168a1872663c9a +md5=c9246277af2d9a13b7018af267a0831a +cksum=2585952669 +upstream_url=https://pypi.io/packages/source/p/pyyaml/PyYAML-VERSION.tar.gz diff --git a/build/pkgs/pyyaml/dependencies b/build/pkgs/pyyaml/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/pyyaml/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/pyyaml/install-requires.txt b/build/pkgs/pyyaml/install-requires.txt new file mode 100644 index 00000000000..5500f007d0b --- /dev/null +++ b/build/pkgs/pyyaml/install-requires.txt @@ -0,0 +1 @@ +PyYAML diff --git a/build/pkgs/pyyaml/package-version.txt b/build/pkgs/pyyaml/package-version.txt new file mode 100644 index 00000000000..5fe60723048 --- /dev/null +++ b/build/pkgs/pyyaml/package-version.txt @@ -0,0 +1 @@ +6.0.1 diff --git a/build/pkgs/pyyaml/spkg-install.in b/build/pkgs/pyyaml/spkg-install.in new file mode 100644 index 00000000000..37ac1a53437 --- /dev/null +++ b/build/pkgs/pyyaml/spkg-install.in @@ -0,0 +1,2 @@ +cd src +sdh_pip_install . diff --git a/build/pkgs/pyyaml/type b/build/pkgs/pyyaml/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/pyyaml/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/referencing/SPKG.rst b/build/pkgs/referencing/SPKG.rst new file mode 100644 index 00000000000..5b8c16c5cf5 --- /dev/null +++ b/build/pkgs/referencing/SPKG.rst @@ -0,0 +1,18 @@ +referencing: JSON Referencing + Python +====================================== + +Description +----------- + +JSON Referencing + Python + +License +------- + +MIT + +Upstream Contact +---------------- + +https://pypi.org/project/referencing/ + diff --git a/build/pkgs/referencing/checksums.ini b/build/pkgs/referencing/checksums.ini new file mode 100644 index 00000000000..248acf0fe20 --- /dev/null +++ b/build/pkgs/referencing/checksums.ini @@ -0,0 +1,5 @@ +tarball=referencing-VERSION-py3-none-any.whl +sha1=8158105b63abdf50dbb9b9e20f4407068528f7d5 +md5=2000702a1de04b64d66bf39f0d4e4b0d +cksum=3675706269 +upstream_url=https://pypi.io/packages/py3/r/referencing/referencing-VERSION-py3-none-any.whl diff --git a/build/pkgs/referencing/dependencies b/build/pkgs/referencing/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/referencing/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/referencing/install-requires.txt b/build/pkgs/referencing/install-requires.txt new file mode 100644 index 00000000000..953f1cdb0c7 --- /dev/null +++ b/build/pkgs/referencing/install-requires.txt @@ -0,0 +1 @@ +referencing diff --git a/build/pkgs/referencing/package-version.txt b/build/pkgs/referencing/package-version.txt new file mode 100644 index 00000000000..0f721773736 --- /dev/null +++ b/build/pkgs/referencing/package-version.txt @@ -0,0 +1 @@ +0.30.2 diff --git a/build/pkgs/referencing/type b/build/pkgs/referencing/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/referencing/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/rfc3339_validator/SPKG.rst b/build/pkgs/rfc3339_validator/SPKG.rst new file mode 100644 index 00000000000..1795adb3fef --- /dev/null +++ b/build/pkgs/rfc3339_validator/SPKG.rst @@ -0,0 +1,18 @@ +rfc3339_validator: A pure python RFC3339 validator +================================================== + +Description +----------- + +A pure python RFC3339 validator + +License +------- + +MIT license + +Upstream Contact +---------------- + +https://pypi.org/project/rfc3339-validator/ + diff --git a/build/pkgs/rfc3339_validator/checksums.ini b/build/pkgs/rfc3339_validator/checksums.ini new file mode 100644 index 00000000000..f91914fd5f7 --- /dev/null +++ b/build/pkgs/rfc3339_validator/checksums.ini @@ -0,0 +1,5 @@ +tarball=rfc3339_validator-VERSION-py2.py3-none-any.whl +sha1=daa86cb641dfd6ebfef4ece6dea1be8fd63dec00 +md5=e16fb743ff1c88d7c7de18890935b647 +cksum=2330309218 +upstream_url=https://pypi.io/packages/py2.py3/r/rfc3339_validator/rfc3339_validator-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/rfc3339_validator/dependencies b/build/pkgs/rfc3339_validator/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/rfc3339_validator/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/rfc3339_validator/install-requires.txt b/build/pkgs/rfc3339_validator/install-requires.txt new file mode 100644 index 00000000000..26ed401db35 --- /dev/null +++ b/build/pkgs/rfc3339_validator/install-requires.txt @@ -0,0 +1 @@ +rfc3339-validator diff --git a/build/pkgs/rfc3339_validator/package-version.txt b/build/pkgs/rfc3339_validator/package-version.txt new file mode 100644 index 00000000000..845639eef26 --- /dev/null +++ b/build/pkgs/rfc3339_validator/package-version.txt @@ -0,0 +1 @@ +0.1.4 diff --git a/build/pkgs/rfc3339_validator/type b/build/pkgs/rfc3339_validator/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/rfc3339_validator/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/rfc3986_validator/SPKG.rst b/build/pkgs/rfc3986_validator/SPKG.rst new file mode 100644 index 00000000000..f7abaad9edb --- /dev/null +++ b/build/pkgs/rfc3986_validator/SPKG.rst @@ -0,0 +1,18 @@ +rfc3986_validator: Pure python rfc3986 validator +================================================ + +Description +----------- + +Pure python rfc3986 validator + +License +------- + +MIT license + +Upstream Contact +---------------- + +https://pypi.org/project/rfc3986-validator/ + diff --git a/build/pkgs/rfc3986_validator/checksums.ini b/build/pkgs/rfc3986_validator/checksums.ini new file mode 100644 index 00000000000..c0ad30c07e7 --- /dev/null +++ b/build/pkgs/rfc3986_validator/checksums.ini @@ -0,0 +1,5 @@ +tarball=rfc3986_validator-VERSION-py2.py3-none-any.whl +sha1=c0fabd5c0568cc516f9258f3e5846a04a059dc31 +md5=41aef4395cd3d560c96a3992534dfd53 +cksum=1606077510 +upstream_url=https://pypi.io/packages/py2.py3/r/rfc3986_validator/rfc3986_validator-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/rfc3986_validator/dependencies b/build/pkgs/rfc3986_validator/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/rfc3986_validator/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/rfc3986_validator/install-requires.txt b/build/pkgs/rfc3986_validator/install-requires.txt new file mode 100644 index 00000000000..f7a1c754962 --- /dev/null +++ b/build/pkgs/rfc3986_validator/install-requires.txt @@ -0,0 +1 @@ +rfc3986-validator diff --git a/build/pkgs/rfc3986_validator/package-version.txt b/build/pkgs/rfc3986_validator/package-version.txt new file mode 100644 index 00000000000..17e51c385ea --- /dev/null +++ b/build/pkgs/rfc3986_validator/package-version.txt @@ -0,0 +1 @@ +0.1.1 diff --git a/build/pkgs/rfc3986_validator/type b/build/pkgs/rfc3986_validator/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/rfc3986_validator/type @@ -0,0 +1 @@ +standard From e92ea260ffac65e967a786bce48312dbb9a86d9c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 11:32:34 -0700 Subject: [PATCH 375/463] build/pkgs/{nodeenv,nodejs}: Remove; we no longer attempt to build JS packages --- build/pkgs/nodeenv/SPKG.rst | 21 ---------- build/pkgs/nodeenv/dependencies | 4 -- build/pkgs/nodeenv/distros/conda.txt | 1 - build/pkgs/nodeenv/distros/homebrew.txt | 1 - build/pkgs/nodeenv/distros/repology.txt | 2 - build/pkgs/nodeenv/requirements.txt | 1 - build/pkgs/nodeenv/type | 1 - build/pkgs/nodejs/SPKG.rst | 20 ---------- build/pkgs/nodejs/dependencies | 4 -- build/pkgs/nodejs/distros/conda.txt | 1 - build/pkgs/nodejs/distros/homebrew.txt | 1 - build/pkgs/nodejs/distros/opensuse.txt | 1 - build/pkgs/nodejs/distros/repology.txt | 1 - build/pkgs/nodejs/distros/void.txt | 1 - build/pkgs/nodejs/package-version.txt | 1 - build/pkgs/nodejs/spkg-install | 53 ------------------------- build/pkgs/nodejs/type | 1 - 17 files changed, 115 deletions(-) delete mode 100644 build/pkgs/nodeenv/SPKG.rst delete mode 100644 build/pkgs/nodeenv/dependencies delete mode 100644 build/pkgs/nodeenv/distros/conda.txt delete mode 100644 build/pkgs/nodeenv/distros/homebrew.txt delete mode 100644 build/pkgs/nodeenv/distros/repology.txt delete mode 100644 build/pkgs/nodeenv/requirements.txt delete mode 100644 build/pkgs/nodeenv/type delete mode 100644 build/pkgs/nodejs/SPKG.rst delete mode 100644 build/pkgs/nodejs/dependencies delete mode 100644 build/pkgs/nodejs/distros/conda.txt delete mode 100644 build/pkgs/nodejs/distros/homebrew.txt delete mode 100644 build/pkgs/nodejs/distros/opensuse.txt delete mode 100644 build/pkgs/nodejs/distros/repology.txt delete mode 100644 build/pkgs/nodejs/distros/void.txt delete mode 100644 build/pkgs/nodejs/package-version.txt delete mode 100755 build/pkgs/nodejs/spkg-install delete mode 100644 build/pkgs/nodejs/type diff --git a/build/pkgs/nodeenv/SPKG.rst b/build/pkgs/nodeenv/SPKG.rst deleted file mode 100644 index 397d909f16d..00000000000 --- a/build/pkgs/nodeenv/SPKG.rst +++ /dev/null @@ -1,21 +0,0 @@ -nodeenv: A tool to create isolated node.js environments -======================================================= - -Description ------------ - -nodeenv (node.js virtual environment) is a tool to create isolated node.js environments. - -It creates an environment that has its own installation directories, that doesn’t share -libraries with other node.js virtual environments. - -License -------- - -BSD License - -Upstream Contact ----------------- - -Home page: https://github.com/ekalinin/nodeenv - diff --git a/build/pkgs/nodeenv/dependencies b/build/pkgs/nodeenv/dependencies deleted file mode 100644 index 04eff0c842c..00000000000 --- a/build/pkgs/nodeenv/dependencies +++ /dev/null @@ -1,4 +0,0 @@ - | $(PYTHON_TOOLCHAIN) certifi $(PYTHON) - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/nodeenv/distros/conda.txt b/build/pkgs/nodeenv/distros/conda.txt deleted file mode 100644 index f69a126dec6..00000000000 --- a/build/pkgs/nodeenv/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -nodeenv diff --git a/build/pkgs/nodeenv/distros/homebrew.txt b/build/pkgs/nodeenv/distros/homebrew.txt deleted file mode 100644 index f69a126dec6..00000000000 --- a/build/pkgs/nodeenv/distros/homebrew.txt +++ /dev/null @@ -1 +0,0 @@ -nodeenv diff --git a/build/pkgs/nodeenv/distros/repology.txt b/build/pkgs/nodeenv/distros/repology.txt deleted file mode 100644 index a3202e13f17..00000000000 --- a/build/pkgs/nodeenv/distros/repology.txt +++ /dev/null @@ -1,2 +0,0 @@ -nodeenv -python:nodeenv diff --git a/build/pkgs/nodeenv/requirements.txt b/build/pkgs/nodeenv/requirements.txt deleted file mode 100644 index 926d31bf049..00000000000 --- a/build/pkgs/nodeenv/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -nodeenv ~= 1.4.0 diff --git a/build/pkgs/nodeenv/type b/build/pkgs/nodeenv/type deleted file mode 100644 index 134d9bc32d5..00000000000 --- a/build/pkgs/nodeenv/type +++ /dev/null @@ -1 +0,0 @@ -optional diff --git a/build/pkgs/nodejs/SPKG.rst b/build/pkgs/nodejs/SPKG.rst deleted file mode 100644 index 1176f4fea3b..00000000000 --- a/build/pkgs/nodejs/SPKG.rst +++ /dev/null @@ -1,20 +0,0 @@ -nodejs: A JavaScript runtime built on Chrome's V8 JavaScript engine -=================================================================== - -Description ------------ - -Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. - -It is installed into an isolated nodeenv. - -License -------- - -MIT License - -Upstream Contact ----------------- - -Home page: https://nodejs.org/ - diff --git a/build/pkgs/nodejs/dependencies b/build/pkgs/nodejs/dependencies deleted file mode 100644 index a8de0ed1559..00000000000 --- a/build/pkgs/nodejs/dependencies +++ /dev/null @@ -1,4 +0,0 @@ -nodeenv - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/nodejs/distros/conda.txt b/build/pkgs/nodejs/distros/conda.txt deleted file mode 100644 index e36de65c4cc..00000000000 --- a/build/pkgs/nodejs/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -nodejs diff --git a/build/pkgs/nodejs/distros/homebrew.txt b/build/pkgs/nodejs/distros/homebrew.txt deleted file mode 100644 index 64f5a0a6813..00000000000 --- a/build/pkgs/nodejs/distros/homebrew.txt +++ /dev/null @@ -1 +0,0 @@ -node diff --git a/build/pkgs/nodejs/distros/opensuse.txt b/build/pkgs/nodejs/distros/opensuse.txt deleted file mode 100644 index e36de65c4cc..00000000000 --- a/build/pkgs/nodejs/distros/opensuse.txt +++ /dev/null @@ -1 +0,0 @@ -nodejs diff --git a/build/pkgs/nodejs/distros/repology.txt b/build/pkgs/nodejs/distros/repology.txt deleted file mode 100644 index e36de65c4cc..00000000000 --- a/build/pkgs/nodejs/distros/repology.txt +++ /dev/null @@ -1 +0,0 @@ -nodejs diff --git a/build/pkgs/nodejs/distros/void.txt b/build/pkgs/nodejs/distros/void.txt deleted file mode 100644 index e36de65c4cc..00000000000 --- a/build/pkgs/nodejs/distros/void.txt +++ /dev/null @@ -1 +0,0 @@ -nodejs diff --git a/build/pkgs/nodejs/package-version.txt b/build/pkgs/nodejs/package-version.txt deleted file mode 100644 index 9cd25a1fec8..00000000000 --- a/build/pkgs/nodejs/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -12.18.3 diff --git a/build/pkgs/nodejs/spkg-install b/build/pkgs/nodejs/spkg-install deleted file mode 100755 index 731d8f3089d..00000000000 --- a/build/pkgs/nodejs/spkg-install +++ /dev/null @@ -1,53 +0,0 @@ -if [ -z "$SAGE_LOCAL" ]; then - echo >&2 "SAGE_LOCAL undefined ... exiting" - echo >&2 "Maybe run 'sage --sh'?" - exit 1 -fi - -nodejs_ver=`grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+" package-version.txt` - -if [ $? -ne 0 ]; then - echo "Error determining which nodejs version to install ... exiting" - exit 1 -fi - -nodeenv_dir="$SAGE_LOCAL/share/nodejs/$nodejs_ver" -nodeenv_activate="$nodeenv_dir/bin/activate" - -echo "Will use/install nodejs in nodeenv located at $nodeenv_dir ..." - -if [ ! -f "$nodeenv_activate" ]; then - # The nodeenv may not exist, or it may exist but installing nodejs into - # it previously failed, so --force to cover both cases. - nodeenv --force --verbose --node="$nodejs_ver" "$nodeenv_dir" - - if [ $? -ne 0 ]; then - echo "Error installing nodejs ... exiting" - exit 1 - fi -fi - -. "$nodeenv_activate" - -if [ $? -ne 0 ]; then - echo "Error activating nodeenv containing nodejs ... exiting" - exit 1 -fi - -active_ver=`node --version | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+"` - -if [ $? -ne 0 ]; then - echo "Error determining which nodejs version is active ... exiting" - deactivate_node - exit 1 -fi - -deactivate_node - -if [ ! "$nodejs_ver" = "$active_ver" ]; then - echo "Wrong version of nodejs was activated ... exiting" - echo "Expected $nodejs_ver but found $active_ver" - exit 1 -fi - -ln -sf "$nodeenv_activate" "$SAGE_LOCAL/share/nodejs/activate" diff --git a/build/pkgs/nodejs/type b/build/pkgs/nodejs/type deleted file mode 100644 index 134d9bc32d5..00000000000 --- a/build/pkgs/nodejs/type +++ /dev/null @@ -1 +0,0 @@ -optional From be203fb080f65eb354781cf44bc289f00be7dffc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 11:36:48 -0700 Subject: [PATCH 376/463] build/pkgs/requests: Update to 2.31.0 --- build/pkgs/requests/checksums.ini | 6 +++--- build/pkgs/requests/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/requests/checksums.ini b/build/pkgs/requests/checksums.ini index 5aabe04f278..925be456c02 100644 --- a/build/pkgs/requests/checksums.ini +++ b/build/pkgs/requests/checksums.ini @@ -1,5 +1,5 @@ tarball=requests-VERSION.tar.gz -sha1=53381250a0d114109a9e712dd7ce8e40e63e61e2 -md5=796ea875cdae283529c03b9203d9c454 -cksum=4112189908 +sha1=23ef233afce04d4a1d4856353dc3aaa255cbce3e +md5=941e175c276cd7d39d098092c56679a4 +cksum=2854825644 upstream_url=https://pypi.io/packages/source/r/requests/requests-VERSION.tar.gz diff --git a/build/pkgs/requests/package-version.txt b/build/pkgs/requests/package-version.txt index 9738a24f699..bafceb320ec 100644 --- a/build/pkgs/requests/package-version.txt +++ b/build/pkgs/requests/package-version.txt @@ -1 +1 @@ -2.28.1 +2.31.0 From ceb67ff0224f7bee66edfd068fdb6a4a06ccdaa2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 11:39:56 -0700 Subject: [PATCH 377/463] build/pkgs/urllib3: Update to 2.0.4 --- build/pkgs/urllib3/checksums.ini | 6 +++--- build/pkgs/urllib3/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/urllib3/checksums.ini b/build/pkgs/urllib3/checksums.ini index bfb7c5afa48..d0f5f9320c7 100644 --- a/build/pkgs/urllib3/checksums.ini +++ b/build/pkgs/urllib3/checksums.ini @@ -1,5 +1,5 @@ tarball=urllib3-VERSION.tar.gz -sha1=ad6bd811a3f4c3e04d86c2706c9994c3e2236e53 -md5=ba308b52b9092184cf4905bc59a88fc0 -cksum=2776794349 +sha1=d7f301a1dcb37c46e300f1ce4463e10198ab974f +md5=5d541b944febe50221e24c31cd6e887d +cksum=447764521 upstream_url=https://pypi.io/packages/source/u/urllib3/urllib3-VERSION.tar.gz diff --git a/build/pkgs/urllib3/package-version.txt b/build/pkgs/urllib3/package-version.txt index b74a856da82..2165f8f9b6a 100644 --- a/build/pkgs/urllib3/package-version.txt +++ b/build/pkgs/urllib3/package-version.txt @@ -1 +1 @@ -1.26.12 +2.0.4 From c01ed1bfcecae252608348e25e9e042053546d0d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:04:34 -0700 Subject: [PATCH 378/463] build/pkgs/{rpds_py,jsonschema_specifications}: New (jsonschema deps) --- build/pkgs/jsonschema/dependencies | 2 +- build/pkgs/jsonschema_specifications/SPKG.rst | 18 ++++++++++++++++++ .../jsonschema_specifications/checksums.ini | 5 +++++ .../jsonschema_specifications/dependencies | 4 ++++ .../install-requires.txt | 1 + .../package-version.txt | 1 + build/pkgs/jsonschema_specifications/type | 1 + build/pkgs/referencing/dependencies | 2 +- 8 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 build/pkgs/jsonschema_specifications/SPKG.rst create mode 100644 build/pkgs/jsonschema_specifications/checksums.ini create mode 100644 build/pkgs/jsonschema_specifications/dependencies create mode 100644 build/pkgs/jsonschema_specifications/install-requires.txt create mode 100644 build/pkgs/jsonschema_specifications/package-version.txt create mode 100644 build/pkgs/jsonschema_specifications/type diff --git a/build/pkgs/jsonschema/dependencies b/build/pkgs/jsonschema/dependencies index d0211604157..0a0d0cdec8d 100644 --- a/build/pkgs/jsonschema/dependencies +++ b/build/pkgs/jsonschema/dependencies @@ -1,4 +1,4 @@ - vcversioner attrs importlib_metadata pyrsistent | $(PYTHON_TOOLCHAIN) hatchling hatch_vcs hatch_fancy_pypi_readme $(PYTHON) +jsonschema_specifications attrs importlib_metadata | $(PYTHON_TOOLCHAIN) hatchling hatch_vcs hatch_fancy_pypi_readme $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jsonschema_specifications/SPKG.rst b/build/pkgs/jsonschema_specifications/SPKG.rst new file mode 100644 index 00000000000..0765571207d --- /dev/null +++ b/build/pkgs/jsonschema_specifications/SPKG.rst @@ -0,0 +1,18 @@ +jsonschema_specifications: The JSON Schema meta-schemas and vocabularies, exposed as a Registry +=============================================================================================== + +Description +----------- + +The JSON Schema meta-schemas and vocabularies, exposed as a Registry + +License +------- + +MIT + +Upstream Contact +---------------- + +https://pypi.org/project/jsonschema-specifications/ + diff --git a/build/pkgs/jsonschema_specifications/checksums.ini b/build/pkgs/jsonschema_specifications/checksums.ini new file mode 100644 index 00000000000..e94fb5a274a --- /dev/null +++ b/build/pkgs/jsonschema_specifications/checksums.ini @@ -0,0 +1,5 @@ +tarball=jsonschema_specifications-VERSION-py3-none-any.whl +sha1=f090f72ecf6719cba0835bb86231035fd1224434 +md5=1430f605a9ddbbbc69533e7818f040b8 +cksum=2771748622 +upstream_url=https://pypi.io/packages/py3/j/jsonschema_specifications/jsonschema_specifications-VERSION-py3-none-any.whl diff --git a/build/pkgs/jsonschema_specifications/dependencies b/build/pkgs/jsonschema_specifications/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/jsonschema_specifications/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/jsonschema_specifications/install-requires.txt b/build/pkgs/jsonschema_specifications/install-requires.txt new file mode 100644 index 00000000000..db1f1fad885 --- /dev/null +++ b/build/pkgs/jsonschema_specifications/install-requires.txt @@ -0,0 +1 @@ +jsonschema-specifications diff --git a/build/pkgs/jsonschema_specifications/package-version.txt b/build/pkgs/jsonschema_specifications/package-version.txt new file mode 100644 index 00000000000..fc5723128b2 --- /dev/null +++ b/build/pkgs/jsonschema_specifications/package-version.txt @@ -0,0 +1 @@ +2023.7.1 diff --git a/build/pkgs/jsonschema_specifications/type b/build/pkgs/jsonschema_specifications/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/jsonschema_specifications/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/referencing/dependencies b/build/pkgs/referencing/dependencies index 0738c2d7777..bd42be1a4bf 100644 --- a/build/pkgs/referencing/dependencies +++ b/build/pkgs/referencing/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) rpds_py | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. From 9b3d52b332dd30a2eac602b4dddaede741d795ba Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:05:16 -0700 Subject: [PATCH 379/463] build/pkgs/zipp: Update to 3.16.2, remove vcversioner --- build/pkgs/vcversioner/SPKG.rst | 25 --------------------- build/pkgs/vcversioner/checksums.ini | 4 ---- build/pkgs/vcversioner/dependencies | 4 ---- build/pkgs/vcversioner/distros/conda.txt | 1 - build/pkgs/vcversioner/distros/macports.txt | 1 - build/pkgs/vcversioner/distros/opensuse.txt | 1 - build/pkgs/vcversioner/distros/repology.txt | 2 -- build/pkgs/vcversioner/install-requires.txt | 1 - build/pkgs/vcversioner/package-version.txt | 1 - build/pkgs/vcversioner/spkg-install.in | 14 ------------ build/pkgs/vcversioner/type | 1 - build/pkgs/zipp/checksums.ini | 6 ++--- build/pkgs/zipp/dependencies | 2 +- build/pkgs/zipp/package-version.txt | 2 +- 14 files changed, 5 insertions(+), 60 deletions(-) delete mode 100644 build/pkgs/vcversioner/SPKG.rst delete mode 100644 build/pkgs/vcversioner/checksums.ini delete mode 100644 build/pkgs/vcversioner/dependencies delete mode 100644 build/pkgs/vcversioner/distros/conda.txt delete mode 100644 build/pkgs/vcversioner/distros/macports.txt delete mode 100644 build/pkgs/vcversioner/distros/opensuse.txt delete mode 100644 build/pkgs/vcversioner/distros/repology.txt delete mode 100644 build/pkgs/vcversioner/install-requires.txt delete mode 100644 build/pkgs/vcversioner/package-version.txt delete mode 100644 build/pkgs/vcversioner/spkg-install.in delete mode 100644 build/pkgs/vcversioner/type diff --git a/build/pkgs/vcversioner/SPKG.rst b/build/pkgs/vcversioner/SPKG.rst deleted file mode 100644 index 17d7f952f61..00000000000 --- a/build/pkgs/vcversioner/SPKG.rst +++ /dev/null @@ -1,25 +0,0 @@ -vcversioner: Python build system extension to obtain package version from version control -========================================================================================= - -Description ------------ - -Write a setup.py with no version information specified, and vcversioner -will find a recent, properly-formatted VCS tag and extract a version -from it. - -License -------- - -Python Software Foundation License - - -Upstream Contact ----------------- - -Home page: https://pypi.python.org/pypi/vcversioner/ - -Dependencies ------------- - -Python, Setuptools diff --git a/build/pkgs/vcversioner/checksums.ini b/build/pkgs/vcversioner/checksums.ini deleted file mode 100644 index 4d294a20994..00000000000 --- a/build/pkgs/vcversioner/checksums.ini +++ /dev/null @@ -1,4 +0,0 @@ -tarball=vcversioner-VERSION.tar.gz -sha1=ce076b62e8f0772bf79f29762bfc3cf09f6781b5 -md5=aab6ef5e0cf8614a1b1140ed5b7f107d -cksum=1650555311 diff --git a/build/pkgs/vcversioner/dependencies b/build/pkgs/vcversioner/dependencies deleted file mode 100644 index 47296a7bace..00000000000 --- a/build/pkgs/vcversioner/dependencies +++ /dev/null @@ -1,4 +0,0 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/vcversioner/distros/conda.txt b/build/pkgs/vcversioner/distros/conda.txt deleted file mode 100644 index 39a323addb3..00000000000 --- a/build/pkgs/vcversioner/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -vcversioner diff --git a/build/pkgs/vcversioner/distros/macports.txt b/build/pkgs/vcversioner/distros/macports.txt deleted file mode 100644 index 17f91a4d953..00000000000 --- a/build/pkgs/vcversioner/distros/macports.txt +++ /dev/null @@ -1 +0,0 @@ -py-vcversioner diff --git a/build/pkgs/vcversioner/distros/opensuse.txt b/build/pkgs/vcversioner/distros/opensuse.txt deleted file mode 100644 index a9b307f8509..00000000000 --- a/build/pkgs/vcversioner/distros/opensuse.txt +++ /dev/null @@ -1 +0,0 @@ -python3${PYTHON_MINOR}-vcversioner diff --git a/build/pkgs/vcversioner/distros/repology.txt b/build/pkgs/vcversioner/distros/repology.txt deleted file mode 100644 index 1cf127b4f86..00000000000 --- a/build/pkgs/vcversioner/distros/repology.txt +++ /dev/null @@ -1,2 +0,0 @@ -vcversioner -python:vcversioner diff --git a/build/pkgs/vcversioner/install-requires.txt b/build/pkgs/vcversioner/install-requires.txt deleted file mode 100644 index dbc9d542440..00000000000 --- a/build/pkgs/vcversioner/install-requires.txt +++ /dev/null @@ -1 +0,0 @@ -vcversioner >=2.16.0.0 diff --git a/build/pkgs/vcversioner/package-version.txt b/build/pkgs/vcversioner/package-version.txt deleted file mode 100644 index f66e5d36e77..00000000000 --- a/build/pkgs/vcversioner/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -2.16.0.0.p0 diff --git a/build/pkgs/vcversioner/spkg-install.in b/build/pkgs/vcversioner/spkg-install.in deleted file mode 100644 index 956aeb8c5a7..00000000000 --- a/build/pkgs/vcversioner/spkg-install.in +++ /dev/null @@ -1,14 +0,0 @@ -if [ -z "$SAGE_LOCAL" ]; then - echo >&2 "SAGE_LOCAL undefined ... exiting" - echo >&2 "Maybe run 'sage --sh'?" - exit 1 -fi - -cd src - -sdh_pip_install . - -if [ $? -ne 0 ]; then - echo "Error installing vcversioner ... exiting" - exit 1 -fi diff --git a/build/pkgs/vcversioner/type b/build/pkgs/vcversioner/type deleted file mode 100644 index a6a7b9cd726..00000000000 --- a/build/pkgs/vcversioner/type +++ /dev/null @@ -1 +0,0 @@ -standard diff --git a/build/pkgs/zipp/checksums.ini b/build/pkgs/zipp/checksums.ini index 53d559563f8..755124ecd6b 100644 --- a/build/pkgs/zipp/checksums.ini +++ b/build/pkgs/zipp/checksums.ini @@ -1,5 +1,5 @@ tarball=zipp-VERSION.tar.gz -sha1=3f6c57b68f3b9165586ea7cce96fc2540b0078ec -md5=1fbff3bca7294a3a7f09fa3f0652c3da -cksum=1128680850 +sha1=2bd770f0093ce7ebb11d8f56b0ea8eda0e392fe4 +md5=f5c13dccedc282cbe50aae5983de7fe4 +cksum=3895521123 upstream_url=https://pypi.io/packages/source/z/zipp/zipp-VERSION.tar.gz diff --git a/build/pkgs/zipp/dependencies b/build/pkgs/zipp/dependencies index 9be6b4aab7c..995ddecb8f4 100644 --- a/build/pkgs/zipp/dependencies +++ b/build/pkgs/zipp/dependencies @@ -1,4 +1,4 @@ - vcversioner | $(PYTHON_TOOLCHAIN) $(PYTHON) + | $(PYTHON_TOOLCHAIN) setuptools_scm $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/zipp/package-version.txt b/build/pkgs/zipp/package-version.txt index afad818663d..21221d0e7a4 100644 --- a/build/pkgs/zipp/package-version.txt +++ b/build/pkgs/zipp/package-version.txt @@ -1 +1 @@ -3.11.0 +3.16.2 From d15f78a078656d5b8ca3743f7c3ba6d8ec14d6a2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 11:56:26 -0700 Subject: [PATCH 380/463] build/pkgs/jupyterlab_widgets: Update to 3.0.8 --- build/pkgs/jupyterlab_widgets/checksums.ini | 6 +++--- build/pkgs/jupyterlab_widgets/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyterlab_widgets/checksums.ini b/build/pkgs/jupyterlab_widgets/checksums.ini index 5d021049263..3708a7bfab4 100644 --- a/build/pkgs/jupyterlab_widgets/checksums.ini +++ b/build/pkgs/jupyterlab_widgets/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyterlab_widgets-VERSION-py3-none-any.whl -sha1=584e25e221b38c3ca7139667621a3eaf23260ffc -md5=d7b643a04ef1bb9012c58e6833d277c9 -cksum=202463248 +sha1=2341a44d66dd3fb634ddb77df3ef8f9bae7317d4 +md5=e944763f6aac1688c14c301fdc9846b5 +cksum=2383886392 upstream_url=https://pypi.io/packages/py3/j/jupyterlab_widgets/jupyterlab_widgets-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab_widgets/package-version.txt b/build/pkgs/jupyterlab_widgets/package-version.txt index 75a22a26ac4..67786e246ef 100644 --- a/build/pkgs/jupyterlab_widgets/package-version.txt +++ b/build/pkgs/jupyterlab_widgets/package-version.txt @@ -1 +1 @@ -3.0.3 +3.0.8 From 9e773a5b6fcdcccaa58da2b120fd5152ab7f269e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 12:25:29 -0700 Subject: [PATCH 381/463] build/pkgs/referencing: Downgrade to 0.23.0 (last version before build dependency on Rust via rpds_py --- build/pkgs/referencing/checksums.ini | 6 +++--- build/pkgs/referencing/dependencies | 2 +- build/pkgs/referencing/package-version.txt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/pkgs/referencing/checksums.ini b/build/pkgs/referencing/checksums.ini index 248acf0fe20..a121d900f04 100644 --- a/build/pkgs/referencing/checksums.ini +++ b/build/pkgs/referencing/checksums.ini @@ -1,5 +1,5 @@ tarball=referencing-VERSION-py3-none-any.whl -sha1=8158105b63abdf50dbb9b9e20f4407068528f7d5 -md5=2000702a1de04b64d66bf39f0d4e4b0d -cksum=3675706269 +sha1=9d710ba3a604d24ffded218a3813b5fd1fe2e495 +md5=d12db197f05a5c560011e40e1852e8fc +cksum=2747749685 upstream_url=https://pypi.io/packages/py3/r/referencing/referencing-VERSION-py3-none-any.whl diff --git a/build/pkgs/referencing/dependencies b/build/pkgs/referencing/dependencies index bd42be1a4bf..0738c2d7777 100644 --- a/build/pkgs/referencing/dependencies +++ b/build/pkgs/referencing/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) rpds_py | $(PYTHON_TOOLCHAIN) +$(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/referencing/package-version.txt b/build/pkgs/referencing/package-version.txt index 0f721773736..ca222b7cf39 100644 --- a/build/pkgs/referencing/package-version.txt +++ b/build/pkgs/referencing/package-version.txt @@ -1 +1 @@ -0.30.2 +0.23.0 From ba7bc4a10630f2857fb4edf26b1d0392c5fa95af Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 12:35:58 -0700 Subject: [PATCH 382/463] build/pkgs/jsonschema_specifications: Update to 2023.3.3 --- build/pkgs/jsonschema_specifications/checksums.ini | 6 +++--- build/pkgs/jsonschema_specifications/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jsonschema_specifications/checksums.ini b/build/pkgs/jsonschema_specifications/checksums.ini index e94fb5a274a..b0a51d9b7b4 100644 --- a/build/pkgs/jsonschema_specifications/checksums.ini +++ b/build/pkgs/jsonschema_specifications/checksums.ini @@ -1,5 +1,5 @@ tarball=jsonschema_specifications-VERSION-py3-none-any.whl -sha1=f090f72ecf6719cba0835bb86231035fd1224434 -md5=1430f605a9ddbbbc69533e7818f040b8 -cksum=2771748622 +sha1=4132bed31478bc96960099e58ae4c083c514c551 +md5=dbd17550f666e0f9aa74270d0d4e97a3 +cksum=135654159 upstream_url=https://pypi.io/packages/py3/j/jsonschema_specifications/jsonschema_specifications-VERSION-py3-none-any.whl diff --git a/build/pkgs/jsonschema_specifications/package-version.txt b/build/pkgs/jsonschema_specifications/package-version.txt index fc5723128b2..5fe615f731b 100644 --- a/build/pkgs/jsonschema_specifications/package-version.txt +++ b/build/pkgs/jsonschema_specifications/package-version.txt @@ -1 +1 @@ -2023.7.1 +2023.3.3 From 580f5d246ed623413c65636f343f73d83ea7f079 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 12:39:20 -0700 Subject: [PATCH 383/463] build/pkgs/jsonschema: Update to 4.17.3 --- build/pkgs/jsonschema/checksums.ini | 6 +++--- build/pkgs/jsonschema/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jsonschema/checksums.ini b/build/pkgs/jsonschema/checksums.ini index ef654eabc2f..e2b4c0ecb27 100644 --- a/build/pkgs/jsonschema/checksums.ini +++ b/build/pkgs/jsonschema/checksums.ini @@ -1,5 +1,5 @@ tarball=jsonschema-VERSION.tar.gz -sha1=0a2d0389e93c688e841d3c84a9edda2d44e645a7 -md5=d24cdf4e2010efe22bd144a75661cece -cksum=1595590979 +sha1=9f762c6c2b92defddf1c441cce8132d021252b2c +md5=7c65ceb8923c83cb1f22c2b5a86d99b0 +cksum=2329321415 upstream_url=https://pypi.io/packages/source/j/jsonschema/jsonschema-VERSION.tar.gz diff --git a/build/pkgs/jsonschema/package-version.txt b/build/pkgs/jsonschema/package-version.txt index a69aa5a4289..ab268c2099f 100644 --- a/build/pkgs/jsonschema/package-version.txt +++ b/build/pkgs/jsonschema/package-version.txt @@ -1 +1 @@ -4.19.0 +4.17.3 From 28689cec04c0521bfb770d438a3d28680c887717 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 12:44:16 -0700 Subject: [PATCH 384/463] build/pkgs/jupyter_events: Downgrade to 0.6.3 - last version that does not need jsonschema >=4.18.0 --- build/pkgs/jupyter_events/checksums.ini | 6 +++--- build/pkgs/jupyter_events/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyter_events/checksums.ini b/build/pkgs/jupyter_events/checksums.ini index 01f690c0fcf..b0721f150a1 100644 --- a/build/pkgs/jupyter_events/checksums.ini +++ b/build/pkgs/jupyter_events/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyter_events-VERSION-py3-none-any.whl -sha1=a6cb6e7619559191dde24719b2ceef734fc9a5bd -md5=48ea0cdb47c3b27d02544f2a912666ee -cksum=3827567899 +sha1=1b3fd8c003ea9e51b0f2d38daa89fded161767f7 +md5=c29e5cb7f9f1b3916b2d9d416b470294 +cksum=2851951719 upstream_url=https://pypi.io/packages/py3/j/jupyter_events/jupyter_events-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_events/package-version.txt b/build/pkgs/jupyter_events/package-version.txt index faef31a4357..844f6a91acb 100644 --- a/build/pkgs/jupyter_events/package-version.txt +++ b/build/pkgs/jupyter_events/package-version.txt @@ -1 +1 @@ -0.7.0 +0.6.3 From 9a335c1adff2dac0db3bac17447adc44e0515f6f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:06:24 -0700 Subject: [PATCH 385/463] build/pkgs/fqdn: New (jsonschema dep) --- build/pkgs/fqdn/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/fqdn/checksums.ini | 5 +++++ build/pkgs/fqdn/dependencies | 4 ++++ build/pkgs/fqdn/install-requires.txt | 1 + build/pkgs/fqdn/package-version.txt | 1 + build/pkgs/fqdn/type | 1 + build/pkgs/jsonschema/dependencies | 2 +- 7 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 build/pkgs/fqdn/SPKG.rst create mode 100644 build/pkgs/fqdn/checksums.ini create mode 100644 build/pkgs/fqdn/dependencies create mode 100644 build/pkgs/fqdn/install-requires.txt create mode 100644 build/pkgs/fqdn/package-version.txt create mode 100644 build/pkgs/fqdn/type diff --git a/build/pkgs/fqdn/SPKG.rst b/build/pkgs/fqdn/SPKG.rst new file mode 100644 index 00000000000..7b94349b48e --- /dev/null +++ b/build/pkgs/fqdn/SPKG.rst @@ -0,0 +1,18 @@ +fqdn: Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers +============================================================================================================ + +Description +----------- + +Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers + +License +------- + +MPL 2.0 + +Upstream Contact +---------------- + +https://pypi.org/project/fqdn/ + diff --git a/build/pkgs/fqdn/checksums.ini b/build/pkgs/fqdn/checksums.ini new file mode 100644 index 00000000000..423dc55e68f --- /dev/null +++ b/build/pkgs/fqdn/checksums.ini @@ -0,0 +1,5 @@ +tarball=fqdn-VERSION-py3-none-any.whl +sha1=85a7ac7d7f45d2e0b64c4b7653ab277ceec91ecf +md5=376c19af0cd5029cd8b36d1042a1490e +cksum=4276482151 +upstream_url=https://pypi.io/packages/py3/f/fqdn/fqdn-VERSION-py3-none-any.whl diff --git a/build/pkgs/fqdn/dependencies b/build/pkgs/fqdn/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/fqdn/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/fqdn/install-requires.txt b/build/pkgs/fqdn/install-requires.txt new file mode 100644 index 00000000000..ade5cc3798f --- /dev/null +++ b/build/pkgs/fqdn/install-requires.txt @@ -0,0 +1 @@ +fqdn diff --git a/build/pkgs/fqdn/package-version.txt b/build/pkgs/fqdn/package-version.txt new file mode 100644 index 00000000000..26ca594609a --- /dev/null +++ b/build/pkgs/fqdn/package-version.txt @@ -0,0 +1 @@ +1.5.1 diff --git a/build/pkgs/fqdn/type b/build/pkgs/fqdn/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/fqdn/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/jsonschema/dependencies b/build/pkgs/jsonschema/dependencies index 0a0d0cdec8d..32de8645719 100644 --- a/build/pkgs/jsonschema/dependencies +++ b/build/pkgs/jsonschema/dependencies @@ -1,4 +1,4 @@ -jsonschema_specifications attrs importlib_metadata | $(PYTHON_TOOLCHAIN) hatchling hatch_vcs hatch_fancy_pypi_readme $(PYTHON) +jsonschema_specifications pyrsistent attrs importlib_metadata fqdn | $(PYTHON_TOOLCHAIN) hatchling hatch_vcs hatch_fancy_pypi_readme $(PYTHON) ---------- All lines of this file are ignored except the first. From 94342c60940819d1e25dcbeaa50ff32203794ad6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:07:00 -0700 Subject: [PATCH 386/463] build/pkgs/pyrsistent: Update to 0.19.3 --- build/pkgs/pyrsistent/checksums.ini | 6 +++--- build/pkgs/pyrsistent/dependencies | 2 +- build/pkgs/pyrsistent/package-version.txt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/pkgs/pyrsistent/checksums.ini b/build/pkgs/pyrsistent/checksums.ini index 7d537e43e37..cffce58a92e 100644 --- a/build/pkgs/pyrsistent/checksums.ini +++ b/build/pkgs/pyrsistent/checksums.ini @@ -1,5 +1,5 @@ tarball=pyrsistent-VERSION.tar.gz -sha1=a2c5cc517a33dcfd3918d3eabf4859b8901d3913 -md5=23da81256b8817e123568a858bf78997 -cksum=1165148669 +sha1=79980873658f7634ae25758b9710088b62e0612a +md5=761266eab1f9dc9280cdb0a6d2dedb08 +cksum=2666822194 upstream_url=https://pypi.io/packages/source/p/pyrsistent/pyrsistent-VERSION.tar.gz diff --git a/build/pkgs/pyrsistent/dependencies b/build/pkgs/pyrsistent/dependencies index 9be6b4aab7c..47296a7bace 100644 --- a/build/pkgs/pyrsistent/dependencies +++ b/build/pkgs/pyrsistent/dependencies @@ -1,4 +1,4 @@ - vcversioner | $(PYTHON_TOOLCHAIN) $(PYTHON) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/pyrsistent/package-version.txt b/build/pkgs/pyrsistent/package-version.txt index 61e6e92d914..b72b05ede10 100644 --- a/build/pkgs/pyrsistent/package-version.txt +++ b/build/pkgs/pyrsistent/package-version.txt @@ -1 +1 @@ -0.19.2 +0.19.3 From a32941cbbfbcfaba5bc22ef43551ef87e6530686 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:07:34 -0700 Subject: [PATCH 387/463] build/pkgs/{isoduration,jsonpointer,uri_template,webcolors}: New (jsonschema deps) --- build/pkgs/isoduration/SPKG.rst | 16 ++++++++++++++++ build/pkgs/isoduration/checksums.ini | 5 +++++ build/pkgs/isoduration/dependencies | 4 ++++ build/pkgs/isoduration/install-requires.txt | 1 + build/pkgs/isoduration/package-version.txt | 1 + build/pkgs/isoduration/type | 1 + build/pkgs/jsonpointer/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/jsonpointer/checksums.ini | 5 +++++ build/pkgs/jsonpointer/dependencies | 4 ++++ build/pkgs/jsonpointer/install-requires.txt | 1 + build/pkgs/jsonpointer/package-version.txt | 1 + build/pkgs/jsonpointer/type | 1 + build/pkgs/jsonschema/dependencies | 2 +- build/pkgs/uri_template/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/uri_template/checksums.ini | 5 +++++ build/pkgs/uri_template/dependencies | 4 ++++ build/pkgs/uri_template/install-requires.txt | 1 + build/pkgs/uri_template/package-version.txt | 1 + build/pkgs/uri_template/type | 1 + build/pkgs/webcolors/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/webcolors/checksums.ini | 5 +++++ build/pkgs/webcolors/dependencies | 4 ++++ build/pkgs/webcolors/install-requires.txt | 1 + build/pkgs/webcolors/package-version.txt | 1 + build/pkgs/webcolors/type | 1 + 25 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 build/pkgs/isoduration/SPKG.rst create mode 100644 build/pkgs/isoduration/checksums.ini create mode 100644 build/pkgs/isoduration/dependencies create mode 100644 build/pkgs/isoduration/install-requires.txt create mode 100644 build/pkgs/isoduration/package-version.txt create mode 100644 build/pkgs/isoduration/type create mode 100644 build/pkgs/jsonpointer/SPKG.rst create mode 100644 build/pkgs/jsonpointer/checksums.ini create mode 100644 build/pkgs/jsonpointer/dependencies create mode 100644 build/pkgs/jsonpointer/install-requires.txt create mode 100644 build/pkgs/jsonpointer/package-version.txt create mode 100644 build/pkgs/jsonpointer/type create mode 100644 build/pkgs/uri_template/SPKG.rst create mode 100644 build/pkgs/uri_template/checksums.ini create mode 100644 build/pkgs/uri_template/dependencies create mode 100644 build/pkgs/uri_template/install-requires.txt create mode 100644 build/pkgs/uri_template/package-version.txt create mode 100644 build/pkgs/uri_template/type create mode 100644 build/pkgs/webcolors/SPKG.rst create mode 100644 build/pkgs/webcolors/checksums.ini create mode 100644 build/pkgs/webcolors/dependencies create mode 100644 build/pkgs/webcolors/install-requires.txt create mode 100644 build/pkgs/webcolors/package-version.txt create mode 100644 build/pkgs/webcolors/type diff --git a/build/pkgs/isoduration/SPKG.rst b/build/pkgs/isoduration/SPKG.rst new file mode 100644 index 00000000000..413f8239948 --- /dev/null +++ b/build/pkgs/isoduration/SPKG.rst @@ -0,0 +1,16 @@ +isoduration: Operations with ISO 8601 durations +=============================================== + +Description +----------- + +Operations with ISO 8601 durations + +License +------- + +Upstream Contact +---------------- + +https://pypi.org/project/isoduration/ + diff --git a/build/pkgs/isoduration/checksums.ini b/build/pkgs/isoduration/checksums.ini new file mode 100644 index 00000000000..490fd21be52 --- /dev/null +++ b/build/pkgs/isoduration/checksums.ini @@ -0,0 +1,5 @@ +tarball=isoduration-VERSION-py3-none-any.whl +sha1=a113878d368fee6881efcfd12421b12f8e6ae11c +md5=c5f76c264bf80cca84b99c48d8af5afb +cksum=3373220361 +upstream_url=https://pypi.io/packages/py3/i/isoduration/isoduration-VERSION-py3-none-any.whl diff --git a/build/pkgs/isoduration/dependencies b/build/pkgs/isoduration/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/isoduration/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/isoduration/install-requires.txt b/build/pkgs/isoduration/install-requires.txt new file mode 100644 index 00000000000..05836d3c935 --- /dev/null +++ b/build/pkgs/isoduration/install-requires.txt @@ -0,0 +1 @@ +isoduration diff --git a/build/pkgs/isoduration/package-version.txt b/build/pkgs/isoduration/package-version.txt new file mode 100644 index 00000000000..8b0beab16a5 --- /dev/null +++ b/build/pkgs/isoduration/package-version.txt @@ -0,0 +1 @@ +20.11.0 diff --git a/build/pkgs/isoduration/type b/build/pkgs/isoduration/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/isoduration/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/jsonpointer/SPKG.rst b/build/pkgs/jsonpointer/SPKG.rst new file mode 100644 index 00000000000..60a89995b2a --- /dev/null +++ b/build/pkgs/jsonpointer/SPKG.rst @@ -0,0 +1,18 @@ +jsonpointer: Identify specific nodes in a JSON document (RFC 6901) +================================================================== + +Description +----------- + +Identify specific nodes in a JSON document (RFC 6901) + +License +------- + +Modified BSD License + +Upstream Contact +---------------- + +https://pypi.org/project/jsonpointer/ + diff --git a/build/pkgs/jsonpointer/checksums.ini b/build/pkgs/jsonpointer/checksums.ini new file mode 100644 index 00000000000..67173595af5 --- /dev/null +++ b/build/pkgs/jsonpointer/checksums.ini @@ -0,0 +1,5 @@ +tarball=jsonpointer-VERSION-py2.py3-none-any.whl +sha1=de1b07c2d014f5b8e672cf0fb1225b2232d0b414 +md5=eb9dcb8c4ccf5d97cea88a7d13510032 +cksum=1224177904 +upstream_url=https://pypi.io/packages/py2.py3/j/jsonpointer/jsonpointer-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/jsonpointer/dependencies b/build/pkgs/jsonpointer/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/jsonpointer/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/jsonpointer/install-requires.txt b/build/pkgs/jsonpointer/install-requires.txt new file mode 100644 index 00000000000..5d437553666 --- /dev/null +++ b/build/pkgs/jsonpointer/install-requires.txt @@ -0,0 +1 @@ +jsonpointer diff --git a/build/pkgs/jsonpointer/package-version.txt b/build/pkgs/jsonpointer/package-version.txt new file mode 100644 index 00000000000..6b4950e3de2 --- /dev/null +++ b/build/pkgs/jsonpointer/package-version.txt @@ -0,0 +1 @@ +2.4 diff --git a/build/pkgs/jsonpointer/type b/build/pkgs/jsonpointer/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/jsonpointer/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/jsonschema/dependencies b/build/pkgs/jsonschema/dependencies index 32de8645719..1a62386aa97 100644 --- a/build/pkgs/jsonschema/dependencies +++ b/build/pkgs/jsonschema/dependencies @@ -1,4 +1,4 @@ -jsonschema_specifications pyrsistent attrs importlib_metadata fqdn | $(PYTHON_TOOLCHAIN) hatchling hatch_vcs hatch_fancy_pypi_readme $(PYTHON) +jsonschema_specifications pyrsistent attrs importlib_metadata fqdn isoduration jsonpointer uri_template webcolors | $(PYTHON_TOOLCHAIN) hatchling hatch_vcs hatch_fancy_pypi_readme $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/uri_template/SPKG.rst b/build/pkgs/uri_template/SPKG.rst new file mode 100644 index 00000000000..e8f6af0ec09 --- /dev/null +++ b/build/pkgs/uri_template/SPKG.rst @@ -0,0 +1,18 @@ +uri_template: RFC 6570 URI Template Processor +============================================= + +Description +----------- + +RFC 6570 URI Template Processor + +License +------- + +MIT License + +Upstream Contact +---------------- + +https://pypi.org/project/uri-template/ + diff --git a/build/pkgs/uri_template/checksums.ini b/build/pkgs/uri_template/checksums.ini new file mode 100644 index 00000000000..cdcfc0caeaa --- /dev/null +++ b/build/pkgs/uri_template/checksums.ini @@ -0,0 +1,5 @@ +tarball=uri_template-VERSION-py3-none-any.whl +sha1=bbc8808bdb7e687f0c099c8120cd901dc90bce69 +md5=7d7f28c2ffd7d4746174ab761f6025e5 +cksum=1943559906 +upstream_url=https://pypi.io/packages/py3/u/uri_template/uri_template-VERSION-py3-none-any.whl diff --git a/build/pkgs/uri_template/dependencies b/build/pkgs/uri_template/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/uri_template/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/uri_template/install-requires.txt b/build/pkgs/uri_template/install-requires.txt new file mode 100644 index 00000000000..5d10570d87b --- /dev/null +++ b/build/pkgs/uri_template/install-requires.txt @@ -0,0 +1 @@ +uri-template diff --git a/build/pkgs/uri_template/package-version.txt b/build/pkgs/uri_template/package-version.txt new file mode 100644 index 00000000000..f0bb29e7638 --- /dev/null +++ b/build/pkgs/uri_template/package-version.txt @@ -0,0 +1 @@ +1.3.0 diff --git a/build/pkgs/uri_template/type b/build/pkgs/uri_template/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/uri_template/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/webcolors/SPKG.rst b/build/pkgs/webcolors/SPKG.rst new file mode 100644 index 00000000000..760b53943d2 --- /dev/null +++ b/build/pkgs/webcolors/SPKG.rst @@ -0,0 +1,18 @@ +webcolors: A library for working with the color formats defined by HTML and CSS. +================================================================================ + +Description +----------- + +A library for working with the color formats defined by HTML and CSS. + +License +------- + +BSD-3-Clause + +Upstream Contact +---------------- + +https://pypi.org/project/webcolors/ + diff --git a/build/pkgs/webcolors/checksums.ini b/build/pkgs/webcolors/checksums.ini new file mode 100644 index 00000000000..4a7e6f5de15 --- /dev/null +++ b/build/pkgs/webcolors/checksums.ini @@ -0,0 +1,5 @@ +tarball=webcolors-VERSION-py3-none-any.whl +sha1=e13a9143964b824fc4972b60eddd8115f6839a26 +md5=d9e9ac7c1da7a2b18975265cf0a953ac +cksum=371137261 +upstream_url=https://pypi.io/packages/py3/w/webcolors/webcolors-VERSION-py3-none-any.whl diff --git a/build/pkgs/webcolors/dependencies b/build/pkgs/webcolors/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/webcolors/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/webcolors/install-requires.txt b/build/pkgs/webcolors/install-requires.txt new file mode 100644 index 00000000000..2ff3d436217 --- /dev/null +++ b/build/pkgs/webcolors/install-requires.txt @@ -0,0 +1 @@ +webcolors diff --git a/build/pkgs/webcolors/package-version.txt b/build/pkgs/webcolors/package-version.txt new file mode 100644 index 00000000000..d3456a90f7d --- /dev/null +++ b/build/pkgs/webcolors/package-version.txt @@ -0,0 +1 @@ +1.13 diff --git a/build/pkgs/webcolors/type b/build/pkgs/webcolors/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/webcolors/type @@ -0,0 +1 @@ +standard From 28bad15648283f6e9288cd2b38801c9bd3da2060 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 13:13:09 -0700 Subject: [PATCH 388/463] build/pkgs/arrow: New (isoduration dep) --- build/pkgs/arrow/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/arrow/checksums.ini | 5 +++++ build/pkgs/arrow/dependencies | 4 ++++ build/pkgs/arrow/install-requires.txt | 1 + build/pkgs/arrow/package-version.txt | 1 + build/pkgs/arrow/type | 1 + build/pkgs/isoduration/dependencies | 2 +- 7 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 build/pkgs/arrow/SPKG.rst create mode 100644 build/pkgs/arrow/checksums.ini create mode 100644 build/pkgs/arrow/dependencies create mode 100644 build/pkgs/arrow/install-requires.txt create mode 100644 build/pkgs/arrow/package-version.txt create mode 100644 build/pkgs/arrow/type diff --git a/build/pkgs/arrow/SPKG.rst b/build/pkgs/arrow/SPKG.rst new file mode 100644 index 00000000000..0b4f6eea8b0 --- /dev/null +++ b/build/pkgs/arrow/SPKG.rst @@ -0,0 +1,18 @@ +arrow: Better dates & times for Python +====================================== + +Description +----------- + +Better dates & times for Python + +License +------- + +Apache 2.0 + +Upstream Contact +---------------- + +https://pypi.org/project/arrow/ + diff --git a/build/pkgs/arrow/checksums.ini b/build/pkgs/arrow/checksums.ini new file mode 100644 index 00000000000..c7ca33b4062 --- /dev/null +++ b/build/pkgs/arrow/checksums.ini @@ -0,0 +1,5 @@ +tarball=arrow-VERSION-py3-none-any.whl +sha1=b336eb2a0cbb7590f677e322e4dc7a343f168e04 +md5=9410a9b3db672ccc17314da703e17b35 +cksum=546923343 +upstream_url=https://pypi.io/packages/py3/a/arrow/arrow-VERSION-py3-none-any.whl diff --git a/build/pkgs/arrow/dependencies b/build/pkgs/arrow/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/arrow/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/arrow/install-requires.txt b/build/pkgs/arrow/install-requires.txt new file mode 100644 index 00000000000..e2dc7471c20 --- /dev/null +++ b/build/pkgs/arrow/install-requires.txt @@ -0,0 +1 @@ +arrow diff --git a/build/pkgs/arrow/package-version.txt b/build/pkgs/arrow/package-version.txt new file mode 100644 index 00000000000..0495c4a88ca --- /dev/null +++ b/build/pkgs/arrow/package-version.txt @@ -0,0 +1 @@ +1.2.3 diff --git a/build/pkgs/arrow/type b/build/pkgs/arrow/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/arrow/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/isoduration/dependencies b/build/pkgs/isoduration/dependencies index 0738c2d7777..e928cdc6089 100644 --- a/build/pkgs/isoduration/dependencies +++ b/build/pkgs/isoduration/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) arrow | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. From 3eb92138a5a3c372986e580bfc53f5e3216340f2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 13:16:24 -0700 Subject: [PATCH 389/463] build/pkgs/retrolab: Remove --- build/pkgs/retrolab/SPKG.rst | 16 ---------------- build/pkgs/retrolab/dependencies | 4 ---- build/pkgs/retrolab/distros/conda.txt | 1 - build/pkgs/retrolab/requirements.txt | 1 - build/pkgs/retrolab/type | 1 - 5 files changed, 23 deletions(-) delete mode 100644 build/pkgs/retrolab/SPKG.rst delete mode 100644 build/pkgs/retrolab/dependencies delete mode 100644 build/pkgs/retrolab/distros/conda.txt delete mode 100644 build/pkgs/retrolab/requirements.txt delete mode 100644 build/pkgs/retrolab/type diff --git a/build/pkgs/retrolab/SPKG.rst b/build/pkgs/retrolab/SPKG.rst deleted file mode 100644 index b2d68eac755..00000000000 --- a/build/pkgs/retrolab/SPKG.rst +++ /dev/null @@ -1,16 +0,0 @@ -retrolab: JupyterLab Distribution with a retro look and feel -============================================================ - -Description ------------ - -JupyterLab Distribution with a retro look and feel - -License -------- - -Upstream Contact ----------------- - -https://pypi.org/project/retrolab/ - diff --git a/build/pkgs/retrolab/dependencies b/build/pkgs/retrolab/dependencies deleted file mode 100644 index 58027d3558c..00000000000 --- a/build/pkgs/retrolab/dependencies +++ /dev/null @@ -1,4 +0,0 @@ - jupyterlab | $(PYTHON_TOOLCHAIN) $(PYTHON) - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/retrolab/distros/conda.txt b/build/pkgs/retrolab/distros/conda.txt deleted file mode 100644 index 7f3af99fb78..00000000000 --- a/build/pkgs/retrolab/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -retrolab diff --git a/build/pkgs/retrolab/requirements.txt b/build/pkgs/retrolab/requirements.txt deleted file mode 100644 index 059cd874f5d..00000000000 --- a/build/pkgs/retrolab/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -retrolab ~= 0.3 diff --git a/build/pkgs/retrolab/type b/build/pkgs/retrolab/type deleted file mode 100644 index 134d9bc32d5..00000000000 --- a/build/pkgs/retrolab/type +++ /dev/null @@ -1 +0,0 @@ -optional From 7e60c9b0edda99d0cd5c2164f327244497194dfd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 13:22:26 -0700 Subject: [PATCH 390/463] build/pkgs/jupterlab_server: New --- build/pkgs/jupterlab_server/type | 1 + 1 file changed, 1 insertion(+) create mode 100644 build/pkgs/jupterlab_server/type diff --git a/build/pkgs/jupterlab_server/type b/build/pkgs/jupterlab_server/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/jupterlab_server/type @@ -0,0 +1 @@ +standard From 9c52ac7798c0434e63e420eb0b665190352e1f5a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 13:22:50 -0700 Subject: [PATCH 391/463] build/pkgs/python_json_logger: New --- build/pkgs/python_json_logger/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/python_json_logger/checksums.ini | 5 +++++ build/pkgs/python_json_logger/dependencies | 4 ++++ .../python_json_logger/install-requires.txt | 1 + .../python_json_logger/package-version.txt | 1 + build/pkgs/python_json_logger/type | 1 + 6 files changed, 30 insertions(+) create mode 100644 build/pkgs/python_json_logger/SPKG.rst create mode 100644 build/pkgs/python_json_logger/checksums.ini create mode 100644 build/pkgs/python_json_logger/dependencies create mode 100644 build/pkgs/python_json_logger/install-requires.txt create mode 100644 build/pkgs/python_json_logger/package-version.txt create mode 100644 build/pkgs/python_json_logger/type diff --git a/build/pkgs/python_json_logger/SPKG.rst b/build/pkgs/python_json_logger/SPKG.rst new file mode 100644 index 00000000000..8e25e0f8387 --- /dev/null +++ b/build/pkgs/python_json_logger/SPKG.rst @@ -0,0 +1,18 @@ +python_json_logger: A python library adding a json log formatter +================================================================ + +Description +----------- + +A python library adding a json log formatter + +License +------- + +BSD + +Upstream Contact +---------------- + +https://pypi.org/project/python-json-logger/ + diff --git a/build/pkgs/python_json_logger/checksums.ini b/build/pkgs/python_json_logger/checksums.ini new file mode 100644 index 00000000000..b17d08d7100 --- /dev/null +++ b/build/pkgs/python_json_logger/checksums.ini @@ -0,0 +1,5 @@ +tarball=python_json_logger-VERSION-py3-none-any.whl +sha1=c1176f521d95b5452b6169943b2b9b259e024b39 +md5=618fc5f196be90261afa8372eb458f47 +cksum=349551342 +upstream_url=https://pypi.io/packages/py3/p/python_json_logger/python_json_logger-VERSION-py3-none-any.whl diff --git a/build/pkgs/python_json_logger/dependencies b/build/pkgs/python_json_logger/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/python_json_logger/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/python_json_logger/install-requires.txt b/build/pkgs/python_json_logger/install-requires.txt new file mode 100644 index 00000000000..02a48421600 --- /dev/null +++ b/build/pkgs/python_json_logger/install-requires.txt @@ -0,0 +1 @@ +python-json-logger diff --git a/build/pkgs/python_json_logger/package-version.txt b/build/pkgs/python_json_logger/package-version.txt new file mode 100644 index 00000000000..f1547e6d134 --- /dev/null +++ b/build/pkgs/python_json_logger/package-version.txt @@ -0,0 +1 @@ +2.0.7 diff --git a/build/pkgs/python_json_logger/type b/build/pkgs/python_json_logger/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/python_json_logger/type @@ -0,0 +1 @@ +standard From 2067887d0d15ca6e9d46df7e49853f5294f9b293 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 13:26:20 -0700 Subject: [PATCH 392/463] src/bin/sage-notebook: Remove legacy options --- src/bin/sage-notebook | 48 ------------------------------------------- 1 file changed, 48 deletions(-) diff --git a/src/bin/sage-notebook b/src/bin/sage-notebook index 801b0a6a6a3..8f7687adcc5 100755 --- a/src/bin/sage-notebook +++ b/src/bin/sage-notebook @@ -74,52 +74,6 @@ class NotebookJupyterlab(): main(argv) -class NotebookNbclassic(): - def print_banner(self): - banner() - print('Please wait while the Jupyterlab server starts...') - - @classmethod - def print_help(cls): - cls(['help']) - - def __init__(self, argv): - try: - from nbclassic.notebookapp import main - except ImportError: - import traceback - traceback.print_exc() - print("Jupyterlab is not installed (at least not in this Sage installation).") - print("You can install it by running") - print(" sage -i jupyterlab") - raise SystemExit(1) - self.print_banner() - main(argv) - - -class NotebookRetrolab(): - def print_banner(self): - banner() - print('Please wait while the Jupyterlab server starts...') - - @classmethod - def print_help(cls): - cls(['help']) - - def __init__(self, argv): - try: - from retrolab.app import main - except ImportError: - import traceback - traceback.print_exc() - print("Retrolab is not installed (at least not in this Sage installation).") - print("You can install it by running") - print(" sage -i retrolab") - raise SystemExit(1) - self.print_banner() - main(argv) - - class SageNBExport(NotebookJupyter): def print_banner(self): @@ -183,8 +137,6 @@ notebook_launcher = { 'ipython': NotebookJupyter, 'jupyter': NotebookJupyter, 'jupyterlab': NotebookJupyterlab, - 'nbclassic': NotebookNbclassic, - 'retrolab': NotebookRetrolab, 'export': SageNBExport, } From aea807d22a1c526efcbabeb5df191b03c0fb81d9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 15:24:20 -0700 Subject: [PATCH 393/463] Delete typo'd file --- build/pkgs/jupterlab_server/type | 1 - 1 file changed, 1 deletion(-) delete mode 100644 build/pkgs/jupterlab_server/type diff --git a/build/pkgs/jupterlab_server/type b/build/pkgs/jupterlab_server/type deleted file mode 100644 index a6a7b9cd726..00000000000 --- a/build/pkgs/jupterlab_server/type +++ /dev/null @@ -1 +0,0 @@ -standard From 270fd926bf4ad445001fb0fb4de106693d3fe647 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 15:33:10 -0700 Subject: [PATCH 394/463] build/pkgs/ipywidgets: Update to 8.1.0 --- build/pkgs/ipywidgets/checksums.ini | 6 +++--- build/pkgs/ipywidgets/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/ipywidgets/checksums.ini b/build/pkgs/ipywidgets/checksums.ini index 63a890dcf81..d52277d3241 100644 --- a/build/pkgs/ipywidgets/checksums.ini +++ b/build/pkgs/ipywidgets/checksums.ini @@ -1,5 +1,5 @@ tarball=ipywidgets-VERSION.tar.gz -sha1=b2c8adf4fefc012adfb61e03a2e957bddbbb7597 -md5=c976de164b782eac9e5dfc933e8da295 -cksum=305610881 +sha1=cf0ae8f3f8340230f59f23781987ad0ba6737d88 +md5=3121e08d2fc2672fc1068e147048784a +cksum=2673660683 upstream_url=https://pypi.io/packages/source/i/ipywidgets/ipywidgets-VERSION.tar.gz diff --git a/build/pkgs/ipywidgets/package-version.txt b/build/pkgs/ipywidgets/package-version.txt index 8b22a322d0f..8104cabd36f 100644 --- a/build/pkgs/ipywidgets/package-version.txt +++ b/build/pkgs/ipywidgets/package-version.txt @@ -1 +1 @@ -8.0.2 +8.1.0 From c9487f7a0c81a1d2f4ee5796a50ce5360fddfae9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:09:39 -0700 Subject: [PATCH 395/463] build/pkgs/comm: New (ipywidget dep) --- build/pkgs/comm/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/comm/checksums.ini | 5 +++++ build/pkgs/comm/dependencies | 4 ++++ build/pkgs/comm/install-requires.txt | 1 + build/pkgs/comm/package-version.txt | 1 + build/pkgs/comm/type | 1 + build/pkgs/ipywidgets/dependencies | 2 +- build/pkgs/jupyter_lsp/dependencies | 2 +- build/pkgs/jupyterlab_server/dependencies | 2 +- build/pkgs/notebook_shim/dependencies | 2 +- 10 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 build/pkgs/comm/SPKG.rst create mode 100644 build/pkgs/comm/checksums.ini create mode 100644 build/pkgs/comm/dependencies create mode 100644 build/pkgs/comm/install-requires.txt create mode 100644 build/pkgs/comm/package-version.txt create mode 100644 build/pkgs/comm/type diff --git a/build/pkgs/comm/SPKG.rst b/build/pkgs/comm/SPKG.rst new file mode 100644 index 00000000000..4350999f1fb --- /dev/null +++ b/build/pkgs/comm/SPKG.rst @@ -0,0 +1,18 @@ +comm: Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc. +================================================================================== + +Description +----------- + +Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc. + +License +------- + +BSD 3-Clause License Copyright (c) 2022, Jupyter All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Upstream Contact +---------------- + +https://pypi.org/project/comm/ + diff --git a/build/pkgs/comm/checksums.ini b/build/pkgs/comm/checksums.ini new file mode 100644 index 00000000000..a3c7481f090 --- /dev/null +++ b/build/pkgs/comm/checksums.ini @@ -0,0 +1,5 @@ +tarball=comm-VERSION-py3-none-any.whl +sha1=e7e20f9c1524a9fe059c0b6df90a68e1cd2115a9 +md5=165e29c257c70498b61c7a31916727f2 +cksum=2011044045 +upstream_url=https://pypi.io/packages/py3/c/comm/comm-VERSION-py3-none-any.whl diff --git a/build/pkgs/comm/dependencies b/build/pkgs/comm/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/comm/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/comm/install-requires.txt b/build/pkgs/comm/install-requires.txt new file mode 100644 index 00000000000..9ba1f1eecf4 --- /dev/null +++ b/build/pkgs/comm/install-requires.txt @@ -0,0 +1 @@ +comm diff --git a/build/pkgs/comm/package-version.txt b/build/pkgs/comm/package-version.txt new file mode 100644 index 00000000000..845639eef26 --- /dev/null +++ b/build/pkgs/comm/package-version.txt @@ -0,0 +1 @@ +0.1.4 diff --git a/build/pkgs/comm/type b/build/pkgs/comm/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/comm/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/ipywidgets/dependencies b/build/pkgs/ipywidgets/dependencies index bcb4e030b7d..75467c6fdb0 100644 --- a/build/pkgs/ipywidgets/dependencies +++ b/build/pkgs/ipywidgets/dependencies @@ -1,4 +1,4 @@ - widgetsnbextension jupyterlab_widgets | $(PYTHON_TOOLCHAIN) ipykernel ipython traitlets $(PYTHON) +widgetsnbextension jupyterlab_widgets comm ipykernel ipython traitlets | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_lsp/dependencies b/build/pkgs/jupyter_lsp/dependencies index 0738c2d7777..d7d6b2764a1 100644 --- a/build/pkgs/jupyter_lsp/dependencies +++ b/build/pkgs/jupyter_lsp/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) jupyter_server | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyterlab_server/dependencies b/build/pkgs/jupyterlab_server/dependencies index 91cf86c044f..dd0c6a688ae 100644 --- a/build/pkgs/jupyterlab_server/dependencies +++ b/build/pkgs/jupyterlab_server/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) babel jupyterlab json5 requests | $(PYTHON_TOOLCHAIN) +$(PYTHON) babel jupyterlab json5 jsonschema requests | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/notebook_shim/dependencies b/build/pkgs/notebook_shim/dependencies index 0738c2d7777..d7d6b2764a1 100644 --- a/build/pkgs/notebook_shim/dependencies +++ b/build/pkgs/notebook_shim/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) jupyter_server | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. From f6eeaca359e15939bdf7598185778dc1074ff454 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:14:07 -0700 Subject: [PATCH 396/463] build/pkgs/{comm,jsonschema_specifications,referencing,urllib3}: Fix dependencies --- build/pkgs/comm/dependencies | 2 +- build/pkgs/jsonschema_specifications/dependencies | 2 +- build/pkgs/referencing/dependencies | 2 +- build/pkgs/urllib3/dependencies | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/comm/dependencies b/build/pkgs/comm/dependencies index 0738c2d7777..1da34eeae60 100644 --- a/build/pkgs/comm/dependencies +++ b/build/pkgs/comm/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) traitlets | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jsonschema_specifications/dependencies b/build/pkgs/jsonschema_specifications/dependencies index 0738c2d7777..845ff9a9aca 100644 --- a/build/pkgs/jsonschema_specifications/dependencies +++ b/build/pkgs/jsonschema_specifications/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) referencing | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/referencing/dependencies b/build/pkgs/referencing/dependencies index 0738c2d7777..4fd4a024bd5 100644 --- a/build/pkgs/referencing/dependencies +++ b/build/pkgs/referencing/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) attrs | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/urllib3/dependencies b/build/pkgs/urllib3/dependencies index 47296a7bace..8cd44d06682 100644 --- a/build/pkgs/urllib3/dependencies +++ b/build/pkgs/urllib3/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) +$(PYTHON) | $(PYTHON_TOOLCHAIN) hatchling ---------- All lines of this file are ignored except the first. From 5b8bcca5410e8ec4d4b67410702d1e1a819b47aa Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 25 Aug 2023 14:48:24 -0700 Subject: [PATCH 397/463] build/pkgs/tomlkit: Remove --- build/pkgs/tomlkit/distros/gentoo.txt | 1 - build/pkgs/tomlkit/spkg-configure.m4 | 2 -- 2 files changed, 3 deletions(-) delete mode 100644 build/pkgs/tomlkit/distros/gentoo.txt delete mode 100644 build/pkgs/tomlkit/spkg-configure.m4 diff --git a/build/pkgs/tomlkit/distros/gentoo.txt b/build/pkgs/tomlkit/distros/gentoo.txt deleted file mode 100644 index afe59d9bfe2..00000000000 --- a/build/pkgs/tomlkit/distros/gentoo.txt +++ /dev/null @@ -1 +0,0 @@ -dev-python/tomlkit diff --git a/build/pkgs/tomlkit/spkg-configure.m4 b/build/pkgs/tomlkit/spkg-configure.m4 deleted file mode 100644 index 6da571e5370..00000000000 --- a/build/pkgs/tomlkit/spkg-configure.m4 +++ /dev/null @@ -1,2 +0,0 @@ -SAGE_SPKG_CONFIGURE([tomlkit], [SAGE_PYTHON_PACKAGE_CHECK([tomlkit])]) - From cffbffc29c3a63c93574f52effc4a1d78b2a5450 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 25 Aug 2023 15:13:34 -0700 Subject: [PATCH 398/463] build/pkgs/nbclient: Switch to wheel package --- build/pkgs/nbclient/checksums.ini | 10 +++++----- build/pkgs/nbclient/spkg-install.in | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) delete mode 100644 build/pkgs/nbclient/spkg-install.in diff --git a/build/pkgs/nbclient/checksums.ini b/build/pkgs/nbclient/checksums.ini index 0de2ad1f91d..a5f4616ad8b 100644 --- a/build/pkgs/nbclient/checksums.ini +++ b/build/pkgs/nbclient/checksums.ini @@ -1,5 +1,5 @@ -tarball=nbclient-VERSION.tar.gz -sha1=1976f9f340cac979ba49ce9d270a1f1fda5063b9 -md5=57ad77589339fb970fe67c0d1a8e3f5c -cksum=3517283210 -upstream_url=https://pypi.io/packages/source/n/nbclient/nbclient-VERSION.tar.gz +tarball=nbclient-VERSION-py3-none-any.whl +sha1=fcb4ad9b3ea1bea4d305076c0a7640a483bd11f3 +md5=db61a38c8b66b5b9c7f6f0c7c7de8f26 +cksum=2793018181 +upstream_url=https://pypi.io/packages/py3/n/nbclient/nbclient-VERSION-py3-none-any.whl diff --git a/build/pkgs/nbclient/spkg-install.in b/build/pkgs/nbclient/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/nbclient/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . From 25de63f22df7c6a4fdb948b6a636c4164ea4ed09 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:16:22 -0700 Subject: [PATCH 399/463] build/pkgs/nbformat: Switch to wheel package --- build/pkgs/nbformat/SPKG.rst | 18 ++++++++++++++---- build/pkgs/nbformat/checksums.ini | 10 +++++----- build/pkgs/nbformat/dependencies | 2 +- build/pkgs/nbformat/spkg-install.in | 1 - 4 files changed, 20 insertions(+), 11 deletions(-) delete mode 100644 build/pkgs/nbformat/spkg-install.in diff --git a/build/pkgs/nbformat/SPKG.rst b/build/pkgs/nbformat/SPKG.rst index 88eebb18a2e..fdb14030fd2 100644 --- a/build/pkgs/nbformat/SPKG.rst +++ b/build/pkgs/nbformat/SPKG.rst @@ -1,8 +1,18 @@ -nbformat: Base implementation of the Jupyter notebook format -============================================================ +nbformat: The Jupyter Notebook format +===================================== Description ----------- -This package contains the base implementation of the Jupyter Notebook -format, and Python APIs for working with notebooks. +The Jupyter Notebook format + +License +------- + +BSD 3-Clause License + +Upstream Contact +---------------- + +https://pypi.org/project/nbformat/ + diff --git a/build/pkgs/nbformat/checksums.ini b/build/pkgs/nbformat/checksums.ini index 2de2adc25d0..81f66428e25 100644 --- a/build/pkgs/nbformat/checksums.ini +++ b/build/pkgs/nbformat/checksums.ini @@ -1,5 +1,5 @@ -tarball=nbformat-VERSION.tar.gz -sha1=cead65d27023c88f202b863f8c06451036cd0d2b -md5=091fcdb13305ad00e92f5bb3fb86d2fd -cksum=3366926154 -upstream_url=https://pypi.io/packages/source/n/nbformat/nbformat-VERSION.tar.gz +tarball=nbformat-VERSION-py3-none-any.whl +sha1=e38af74817e9d81101583363d9ffe349f0038eb9 +md5=0821545beba702b7001ad5bd744c89ba +cksum=2633499795 +upstream_url=https://pypi.io/packages/py3/n/nbformat/nbformat-VERSION-py3-none-any.whl diff --git a/build/pkgs/nbformat/dependencies b/build/pkgs/nbformat/dependencies index a6f9cc5f425..4e265a78b6a 100644 --- a/build/pkgs/nbformat/dependencies +++ b/build/pkgs/nbformat/dependencies @@ -1,4 +1,4 @@ - jsonschema fastjsonschema jupyter_core traitlets | $(PYTHON_TOOLCHAIN) hatchling hatch_nodejs_version $(PYTHON) +jsonschema fastjsonschema jupyter_core traitlets | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/nbformat/spkg-install.in b/build/pkgs/nbformat/spkg-install.in deleted file mode 100644 index deba1bb42bb..00000000000 --- a/build/pkgs/nbformat/spkg-install.in +++ /dev/null @@ -1 +0,0 @@ -cd src && sdh_pip_install . From fd796921fec8fd37dc8c83b95d7f5074e775be73 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 25 Aug 2023 15:17:35 -0700 Subject: [PATCH 400/463] build/pkgs/hatch_nodejs_version: Remove --- build/pkgs/hatch_nodejs_version/SPKG.rst | 18 ------------------ build/pkgs/hatch_nodejs_version/checksums.ini | 5 ----- build/pkgs/hatch_nodejs_version/dependencies | 4 ---- .../hatch_nodejs_version/install-requires.txt | 1 - .../hatch_nodejs_version/package-version.txt | 1 - .../pkgs/hatch_nodejs_version/spkg-install.in | 2 -- build/pkgs/hatch_nodejs_version/type | 1 - 7 files changed, 32 deletions(-) delete mode 100644 build/pkgs/hatch_nodejs_version/SPKG.rst delete mode 100644 build/pkgs/hatch_nodejs_version/checksums.ini delete mode 100644 build/pkgs/hatch_nodejs_version/dependencies delete mode 100644 build/pkgs/hatch_nodejs_version/install-requires.txt delete mode 100644 build/pkgs/hatch_nodejs_version/package-version.txt delete mode 100644 build/pkgs/hatch_nodejs_version/spkg-install.in delete mode 100644 build/pkgs/hatch_nodejs_version/type diff --git a/build/pkgs/hatch_nodejs_version/SPKG.rst b/build/pkgs/hatch_nodejs_version/SPKG.rst deleted file mode 100644 index 6a1cd5f991c..00000000000 --- a/build/pkgs/hatch_nodejs_version/SPKG.rst +++ /dev/null @@ -1,18 +0,0 @@ -hatch_nodejs_version: Hatch plugin for versioning from a package.json file -========================================================================== - -Description ------------ - -Hatch plugin for versioning from a package.json file - -License -------- - -MIT - -Upstream Contact ----------------- - -https://pypi.org/project/hatch-nodejs-version/ - diff --git a/build/pkgs/hatch_nodejs_version/checksums.ini b/build/pkgs/hatch_nodejs_version/checksums.ini deleted file mode 100644 index bb5f28d0e24..00000000000 --- a/build/pkgs/hatch_nodejs_version/checksums.ini +++ /dev/null @@ -1,5 +0,0 @@ -tarball=hatch_nodejs_version-VERSION.tar.gz -sha1=ce77992d461d5108c481e985250cfb401b4ee5df -md5=6e5f9d5cfa442572637478cacaa8ea81 -cksum=1271494344 -upstream_url=https://pypi.io/packages/source/h/hatch_nodejs_version/hatch_nodejs_version-VERSION.tar.gz diff --git a/build/pkgs/hatch_nodejs_version/dependencies b/build/pkgs/hatch_nodejs_version/dependencies deleted file mode 100644 index 85e8893f785..00000000000 --- a/build/pkgs/hatch_nodejs_version/dependencies +++ /dev/null @@ -1,4 +0,0 @@ - hatchling | $(PYTHON_TOOLCHAIN) $(PYTHON) - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/hatch_nodejs_version/install-requires.txt b/build/pkgs/hatch_nodejs_version/install-requires.txt deleted file mode 100644 index 5c606fe80f5..00000000000 --- a/build/pkgs/hatch_nodejs_version/install-requires.txt +++ /dev/null @@ -1 +0,0 @@ -hatch-nodejs-version diff --git a/build/pkgs/hatch_nodejs_version/package-version.txt b/build/pkgs/hatch_nodejs_version/package-version.txt deleted file mode 100644 index 9e11b32fcaa..00000000000 --- a/build/pkgs/hatch_nodejs_version/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -0.3.1 diff --git a/build/pkgs/hatch_nodejs_version/spkg-install.in b/build/pkgs/hatch_nodejs_version/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/hatch_nodejs_version/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/hatch_nodejs_version/type b/build/pkgs/hatch_nodejs_version/type deleted file mode 100644 index a6a7b9cd726..00000000000 --- a/build/pkgs/hatch_nodejs_version/type +++ /dev/null @@ -1 +0,0 @@ -standard From b0b33c88b93f5d40a6b132671d5ffee9fc89ac75 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 25 Aug 2023 15:31:20 -0700 Subject: [PATCH 401/463] build/pkgs/debugpy: Update to 1.6.7.post1 --- build/pkgs/debugpy/checksums.ini | 6 +++--- build/pkgs/debugpy/package-version.txt | 2 +- build/pkgs/debugpy/type | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/pkgs/debugpy/checksums.ini b/build/pkgs/debugpy/checksums.ini index 94e60c8de63..0f957eea07f 100644 --- a/build/pkgs/debugpy/checksums.ini +++ b/build/pkgs/debugpy/checksums.ini @@ -1,5 +1,5 @@ tarball=debugpy-VERSION.zip -sha1=44ae7bfe2d355990604f83ee4c24eb81631b4433 -md5=a999f81d29db030bfacab544d5fb0976 -cksum=3944616380 +sha1=dd59205316ac2019b3066ac8c23796d44eb2f273 +md5=7dd011f0e980e55ff55028b82db65cd0 +cksum=3386350262 upstream_url=https://pypi.io/packages/source/d/debugpy/debugpy-VERSION.zip diff --git a/build/pkgs/debugpy/package-version.txt b/build/pkgs/debugpy/package-version.txt index 266146b87cb..d755e2f5bb7 100644 --- a/build/pkgs/debugpy/package-version.txt +++ b/build/pkgs/debugpy/package-version.txt @@ -1 +1 @@ -1.6.3 +1.6.7.post1 diff --git a/build/pkgs/debugpy/type b/build/pkgs/debugpy/type index 134d9bc32d5..a6a7b9cd726 100644 --- a/build/pkgs/debugpy/type +++ b/build/pkgs/debugpy/type @@ -1 +1 @@ -optional +standard From 6e86a8d9d42e480d34653dd81f04850f3b1c3e00 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:17:57 -0700 Subject: [PATCH 402/463] build/pkgs/jupyter_client: Switch to wheel package --- build/pkgs/jupyter_client/SPKG.rst | 16 +++++++++++----- build/pkgs/jupyter_client/checksums.ini | 10 +++++----- build/pkgs/jupyter_client/dependencies | 2 +- build/pkgs/jupyter_client/install-requires.txt | 2 +- build/pkgs/jupyter_client/package-version.txt | 2 +- build/pkgs/jupyter_client/spkg-install.in | 1 - build/pkgs/jupyterlab_server/dependencies | 2 +- 7 files changed, 20 insertions(+), 15 deletions(-) delete mode 100644 build/pkgs/jupyter_client/spkg-install.in diff --git a/build/pkgs/jupyter_client/SPKG.rst b/build/pkgs/jupyter_client/SPKG.rst index 3c25d65afff..8d189350e45 100644 --- a/build/pkgs/jupyter_client/SPKG.rst +++ b/build/pkgs/jupyter_client/SPKG.rst @@ -4,9 +4,15 @@ jupyter_client: Jupyter protocol implementation and client libraries Description ----------- -jupyter_client contains the reference implementation of the Jupyter -protocol. It also provides client and kernel management APIs for working -with kernels. +Jupyter protocol implementation and client libraries + +License +------- + +BSD 3-Clause License - Copyright (c) 2001-2015, IPython Development Team - Copyright (c) 2015-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Upstream Contact +---------------- + +https://pypi.org/project/jupyter-client/ -It also provides the jupyter kernelspec entrypoint for installing -kernelspecs for use with Jupyter frontends. diff --git a/build/pkgs/jupyter_client/checksums.ini b/build/pkgs/jupyter_client/checksums.ini index 7e31fb35fc6..482531e04c8 100644 --- a/build/pkgs/jupyter_client/checksums.ini +++ b/build/pkgs/jupyter_client/checksums.ini @@ -1,5 +1,5 @@ -tarball=jupyter_client-VERSION.tar.gz -sha1=0a9446eda476e3614d4509db0646ae5a89f6b492 -md5=481db492a8a0d16022c49481438e6285 -cksum=3316985535 -upstream_url=https://pypi.io/packages/source/j/jupyter_client/jupyter_client-VERSION.tar.gz +tarball=jupyter_client-VERSION-py3-none-any.whl +sha1=9aab7008353b4bea0a7df79857c60b8564dd74ea +md5=1add15bcf7e7493cf7471d54c5af6274 +cksum=2919595625 +upstream_url=https://pypi.io/packages/py3/j/jupyter_client/jupyter_client-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_client/dependencies b/build/pkgs/jupyter_client/dependencies index dcc8c256fad..3818d456c82 100644 --- a/build/pkgs/jupyter_client/dependencies +++ b/build/pkgs/jupyter_client/dependencies @@ -1,4 +1,4 @@ - jupyter_core | $(PYTHON_TOOLCHAIN) pyzmq dateutil nest_asyncio tornado traitlets entrypoints hatchling $(PYTHON) + jupyter_core pyzmq dateutil tornado traitlets importlib_metadata | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_client/install-requires.txt b/build/pkgs/jupyter_client/install-requires.txt index db02ea315bb..d1eb6b530b3 100644 --- a/build/pkgs/jupyter_client/install-requires.txt +++ b/build/pkgs/jupyter_client/install-requires.txt @@ -1 +1 @@ -jupyter_client >=6.1.6 +jupyter-client diff --git a/build/pkgs/jupyter_client/package-version.txt b/build/pkgs/jupyter_client/package-version.txt index 4e61aeef901..2bf50aaf17a 100644 --- a/build/pkgs/jupyter_client/package-version.txt +++ b/build/pkgs/jupyter_client/package-version.txt @@ -1 +1 @@ -7.4.4 +8.3.0 diff --git a/build/pkgs/jupyter_client/spkg-install.in b/build/pkgs/jupyter_client/spkg-install.in deleted file mode 100644 index deba1bb42bb..00000000000 --- a/build/pkgs/jupyter_client/spkg-install.in +++ /dev/null @@ -1 +0,0 @@ -cd src && sdh_pip_install . diff --git a/build/pkgs/jupyterlab_server/dependencies b/build/pkgs/jupyterlab_server/dependencies index dd0c6a688ae..e112afaed34 100644 --- a/build/pkgs/jupyterlab_server/dependencies +++ b/build/pkgs/jupyterlab_server/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) babel jupyterlab json5 jsonschema requests | $(PYTHON_TOOLCHAIN) +$(PYTHON) babel jupyterlab jupyter_events json5 jsonschema requests | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. From 60ade2e1b86803073565bc6871aefc8cec560711 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 25 Aug 2023 15:58:48 -0700 Subject: [PATCH 403/463] build/pkgs/jupyter_client: Update to 7.4.9 --- build/pkgs/jupyter_client/checksums.ini | 6 +++--- build/pkgs/jupyter_client/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyter_client/checksums.ini b/build/pkgs/jupyter_client/checksums.ini index 482531e04c8..cd9d883763e 100644 --- a/build/pkgs/jupyter_client/checksums.ini +++ b/build/pkgs/jupyter_client/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyter_client-VERSION-py3-none-any.whl -sha1=9aab7008353b4bea0a7df79857c60b8564dd74ea -md5=1add15bcf7e7493cf7471d54c5af6274 -cksum=2919595625 +sha1=d3f338ea9ca02bdb47f5cdb89b81cd9f375f9d6c +md5=a1044eb70daee63d637859d89de6e5a9 +cksum=503921402 upstream_url=https://pypi.io/packages/py3/j/jupyter_client/jupyter_client-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_client/package-version.txt b/build/pkgs/jupyter_client/package-version.txt index 2bf50aaf17a..14ebea1f124 100644 --- a/build/pkgs/jupyter_client/package-version.txt +++ b/build/pkgs/jupyter_client/package-version.txt @@ -1 +1 @@ -8.3.0 +7.4.9 From 39d8fbdf79b6ea991d0eb6b9b1e7aecb578e56eb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 25 Aug 2023 16:37:44 -0700 Subject: [PATCH 404/463] Fixups --- build/pkgs/comm/SPKG.rst | 2 +- build/pkgs/jupyter_client/SPKG.rst | 2 +- build/pkgs/jupyter_events/SPKG.rst | 2 +- build/pkgs/jupyter_server/SPKG.rst | 8 ++++---- build/pkgs/jupyter_server_terminals/SPKG.rst | 6 +++--- build/pkgs/jupyterlab/SPKG.rst | 4 +++- build/pkgs/jupyterlab_pygments/spkg-install.in | 2 -- build/pkgs/notebook/spkg-install.in | 10 ---------- build/pkgs/notebook_shim/SPKG.rst | 2 +- 9 files changed, 14 insertions(+), 24 deletions(-) delete mode 100644 build/pkgs/jupyterlab_pygments/spkg-install.in delete mode 100644 build/pkgs/notebook/spkg-install.in diff --git a/build/pkgs/comm/SPKG.rst b/build/pkgs/comm/SPKG.rst index 4350999f1fb..6f0ec348582 100644 --- a/build/pkgs/comm/SPKG.rst +++ b/build/pkgs/comm/SPKG.rst @@ -9,7 +9,7 @@ Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc. License ------- -BSD 3-Clause License Copyright (c) 2022, Jupyter All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +BSD 3-Clause License Upstream Contact ---------------- diff --git a/build/pkgs/jupyter_client/SPKG.rst b/build/pkgs/jupyter_client/SPKG.rst index 8d189350e45..9b1bb3b235a 100644 --- a/build/pkgs/jupyter_client/SPKG.rst +++ b/build/pkgs/jupyter_client/SPKG.rst @@ -9,7 +9,7 @@ Jupyter protocol implementation and client libraries License ------- -BSD 3-Clause License - Copyright (c) 2001-2015, IPython Development Team - Copyright (c) 2015-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +BSD 3-Clause License Upstream Contact ---------------- diff --git a/build/pkgs/jupyter_events/SPKG.rst b/build/pkgs/jupyter_events/SPKG.rst index 4a685b647c6..760f6035e04 100644 --- a/build/pkgs/jupyter_events/SPKG.rst +++ b/build/pkgs/jupyter_events/SPKG.rst @@ -9,7 +9,7 @@ Jupyter Event System library License ------- -BSD 3-Clause License Copyright (c) 2022-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +BSD 3-Clause License Upstream Contact ---------------- diff --git a/build/pkgs/jupyter_server/SPKG.rst b/build/pkgs/jupyter_server/SPKG.rst index 6a9b87f36ad..19c144f9a8e 100644 --- a/build/pkgs/jupyter_server/SPKG.rst +++ b/build/pkgs/jupyter_server/SPKG.rst @@ -1,15 +1,15 @@ -jupyter_server: The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications. -===================================================================================================== +jupyter_server: The backend (core services, APIs, REST endpoints) to Jupyter web applications +============================================================================================= Description ----------- -The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications. +The backend, i.e., core services, APIs, and REST endpoints, to Jupyter web applications. License ------- -BSD 3-Clause License - Copyright (c) 2001-2015, IPython Development Team - Copyright (c) 2015-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +BSD 3-Clause License Upstream Contact ---------------- diff --git a/build/pkgs/jupyter_server_terminals/SPKG.rst b/build/pkgs/jupyter_server_terminals/SPKG.rst index a739e9edcc0..6624c35d243 100644 --- a/build/pkgs/jupyter_server_terminals/SPKG.rst +++ b/build/pkgs/jupyter_server_terminals/SPKG.rst @@ -1,5 +1,5 @@ -jupyter_server_terminals: A Jupyter Server Extension Providing Terminals. -========================================================================= +jupyter_server_terminals: A Jupyter Server Extension Providing Terminals +======================================================================== Description ----------- @@ -9,7 +9,7 @@ A Jupyter Server Extension Providing Terminals. License ------- -# Licensing terms This project is licensed under the terms of the Modified BSD License (also known as New or Revised or 3-Clause BSD), as follows: - Copyright (c) 2021-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Jupyter Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## About the Jupyter Development Team The Jupyter Development Team is the set of all contributors to the Jupyter project. This includes all of the Jupyter subprojects. The core team that coordinates development on GitHub can be found here: https://github.com/jupyter/. ## Our Copyright Policy Jupyter uses a shared copyright model. Each contributor maintains copyright over their contributions to Jupyter. But, it is important to note that these contributions are typically only changes to the repositories. Thus, the Jupyter source code, in its entirety is not the copyright of any single person or institution. Instead, it is the collective copyright of the entire Jupyter Development Team. If individual contributors want to maintain a record of what changes/contributions they have specific copyright on, they should indicate their copyright in the commit message of the change, when they commit the change to one of the Jupyter repositories. With this in mind, the following banner should be used in any source code file to indicate the copyright and license terms: # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. +Modified BSD License (also known as New or Revised or 3-Clause BSD) Upstream Contact ---------------- diff --git a/build/pkgs/jupyterlab/SPKG.rst b/build/pkgs/jupyterlab/SPKG.rst index 728448f7f71..00c89cb7aa0 100644 --- a/build/pkgs/jupyterlab/SPKG.rst +++ b/build/pkgs/jupyterlab/SPKG.rst @@ -9,7 +9,9 @@ JupyterLab computational environment License ------- -Copyright (c) 2015-2022 Project Jupyter Contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Semver File License =================== The semver.py file is from https://github.com/podhmo/python-semver which is licensed under the "MIT" license. See the semver.py file for details. +Copyright (c) 2015-2022 Project Jupyter Contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Semver File License: The semver.py file is from https://github.com/podhmo/python-semver which is licensed under the "MIT" license. See the semver.py file for details. Upstream Contact ---------------- diff --git a/build/pkgs/jupyterlab_pygments/spkg-install.in b/build/pkgs/jupyterlab_pygments/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/jupyterlab_pygments/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/notebook/spkg-install.in b/build/pkgs/notebook/spkg-install.in deleted file mode 100644 index b0979b55cb8..00000000000 --- a/build/pkgs/notebook/spkg-install.in +++ /dev/null @@ -1,10 +0,0 @@ -cd src - -set -e - -sdh_pip_install . - -# Install the Jupyter notebook configuration in the installation tree -ETC_JUPYTER="$SAGE_INST_LOCAL"/etc/jupyter -mkdir -p "$ETC_JUPYTER" -cp ../jupyter_notebook_config.py "$ETC_JUPYTER"/ diff --git a/build/pkgs/notebook_shim/SPKG.rst b/build/pkgs/notebook_shim/SPKG.rst index 3ed2cb01e0d..102ffbb5b99 100644 --- a/build/pkgs/notebook_shim/SPKG.rst +++ b/build/pkgs/notebook_shim/SPKG.rst @@ -9,7 +9,7 @@ A shim layer for notebook traits and config License ------- -BSD 3-Clause License Copyright (c) 2022 Project Jupyter Contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +BSD 3-Clause License Upstream Contact ---------------- From 8232a0aa8de6cc1671c627d19f0cce810913d439 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:19:56 -0700 Subject: [PATCH 405/463] build/pkgs/bleach: Update to 6, make it a wheel package --- build/pkgs/bleach/checksums.ini | 10 +++++----- build/pkgs/bleach/dependencies | 2 +- build/pkgs/bleach/install-requires.txt | 2 +- build/pkgs/bleach/package-version.txt | 2 +- build/pkgs/bleach/spkg-install.in | 1 - 5 files changed, 8 insertions(+), 9 deletions(-) delete mode 100644 build/pkgs/bleach/spkg-install.in diff --git a/build/pkgs/bleach/checksums.ini b/build/pkgs/bleach/checksums.ini index 4d4855aab72..9c220829178 100644 --- a/build/pkgs/bleach/checksums.ini +++ b/build/pkgs/bleach/checksums.ini @@ -1,5 +1,5 @@ -tarball=bleach-VERSION.tar.gz -sha1=73c6b8fad993b318859ca65c365ac2191edd35fc -md5=03b5faa43c0d771a86a2c4cb2575d070 -cksum=4204308806 -upstream_url=https://pypi.io/packages/source/b/bleach/bleach-VERSION.tar.gz +tarball=bleach-VERSION-py3-none-any.whl +sha1=2c26315754501b4449d4cbbdc95c1c4cc9daf526 +md5=f3768630dc40d44f0a9a1b2023e6fcc7 +cksum=3947199582 +upstream_url=https://pypi.io/packages/py3/b/bleach/bleach-VERSION-py3-none-any.whl diff --git a/build/pkgs/bleach/dependencies b/build/pkgs/bleach/dependencies index c7ac2e8b3e7..b597779be66 100644 --- a/build/pkgs/bleach/dependencies +++ b/build/pkgs/bleach/dependencies @@ -1,4 +1,4 @@ - packaging six webencodings | $(PYTHON_TOOLCHAIN) $(PYTHON) + six webencodings | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/bleach/install-requires.txt b/build/pkgs/bleach/install-requires.txt index 49c810a0dcb..7f7581bd261 100644 --- a/build/pkgs/bleach/install-requires.txt +++ b/build/pkgs/bleach/install-requires.txt @@ -1 +1 @@ -bleach >=3.1.5 +bleach >= 5 diff --git a/build/pkgs/bleach/package-version.txt b/build/pkgs/bleach/package-version.txt index 6b244dcd696..09b254e90c6 100644 --- a/build/pkgs/bleach/package-version.txt +++ b/build/pkgs/bleach/package-version.txt @@ -1 +1 @@ -5.0.1 +6.0.0 diff --git a/build/pkgs/bleach/spkg-install.in b/build/pkgs/bleach/spkg-install.in deleted file mode 100644 index deba1bb42bb..00000000000 --- a/build/pkgs/bleach/spkg-install.in +++ /dev/null @@ -1 +0,0 @@ -cd src && sdh_pip_install . From 7b0e24c6ed6095626bc269ab189cec6c07198b9e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:20:16 -0700 Subject: [PATCH 406/463] build/pkgs/arrow/dependencies: Add dateutil --- build/pkgs/arrow/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/arrow/dependencies b/build/pkgs/arrow/dependencies index 0738c2d7777..c09669bc4e7 100644 --- a/build/pkgs/arrow/dependencies +++ b/build/pkgs/arrow/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +dateutil | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. From 861360edc58780a3d16a8b2451060598f4b43c9c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 18:20:51 -0700 Subject: [PATCH 407/463] build/pkgs/jupyterlab_server/dependencies: Add jupyter_server --- build/pkgs/jupyterlab_server/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/jupyterlab_server/dependencies b/build/pkgs/jupyterlab_server/dependencies index e112afaed34..72b740a6c66 100644 --- a/build/pkgs/jupyterlab_server/dependencies +++ b/build/pkgs/jupyterlab_server/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) babel jupyterlab jupyter_events json5 jsonschema requests | $(PYTHON_TOOLCHAIN) + babel jupyterlab jupyter_events jupyter_server json5 jsonschema requests | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. From 069c83ee55ec9ac855e3c01142f1aa48b22ecbb4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 4 Sep 2023 22:37:16 -0700 Subject: [PATCH 408/463] build/pkgs/notebook: Update to 7.0.3 --- build/pkgs/notebook/checksums.ini | 6 +++--- build/pkgs/notebook/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/notebook/checksums.ini b/build/pkgs/notebook/checksums.ini index c93f3f3c1a3..82bd76cd73c 100644 --- a/build/pkgs/notebook/checksums.ini +++ b/build/pkgs/notebook/checksums.ini @@ -1,5 +1,5 @@ tarball=notebook-VERSION-py3-none-any.whl -sha1=072def379a2015bc7295065330e83a6f878965dc -md5=741fa46d8ac2df863bad53e375a114ef -cksum=116542382 +sha1=433b91fb8857e2244515e8ae2e873880b3323d64 +md5=edc9b8e695f6f712a577c8afebfcd784 +cksum=1990528497 upstream_url=https://pypi.io/packages/py3/n/notebook/notebook-VERSION-py3-none-any.whl diff --git a/build/pkgs/notebook/package-version.txt b/build/pkgs/notebook/package-version.txt index a8907c025d5..a50da181e9b 100644 --- a/build/pkgs/notebook/package-version.txt +++ b/build/pkgs/notebook/package-version.txt @@ -1 +1 @@ -7.0.2 +7.0.3 From dd15edf749d7447419bedf6ef981475920b90ffc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 4 Sep 2023 22:38:17 -0700 Subject: [PATCH 409/463] build/pkgs/anyio: Update to 4.0.0 --- build/pkgs/anyio/checksums.ini | 6 +++--- build/pkgs/anyio/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/anyio/checksums.ini b/build/pkgs/anyio/checksums.ini index 9e9041163a8..4dcafcb69da 100644 --- a/build/pkgs/anyio/checksums.ini +++ b/build/pkgs/anyio/checksums.ini @@ -1,5 +1,5 @@ tarball=anyio-VERSION-py3-none-any.whl -sha1=bed42cf64ff0753ea0062689b533727745470f68 -md5=1e50429e671f536b3a41ed6a94e94c9f -cksum=1692872471 +sha1=bb08368bb19e1aff2f4190e39300e43fee52103e +md5=420d85e19168705cdf0223621b18831a +cksum=627181302 upstream_url=https://pypi.io/packages/py3/a/anyio/anyio-VERSION-py3-none-any.whl diff --git a/build/pkgs/anyio/package-version.txt b/build/pkgs/anyio/package-version.txt index a76ccff2a6e..fcdb2e109f6 100644 --- a/build/pkgs/anyio/package-version.txt +++ b/build/pkgs/anyio/package-version.txt @@ -1 +1 @@ -3.7.1 +4.0.0 From 4fa744cb84cd24bbfcb1386f3dc8f6a1db2c05fb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:13:03 -0700 Subject: [PATCH 410/463] build/pkgs/jupyterlab_mathjax2: New --- build/pkgs/jupyterlab_mathjax2/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/jupyterlab_mathjax2/checksums.ini | 5 +++++ build/pkgs/jupyterlab_mathjax2/dependencies | 4 ++++ .../jupyterlab_mathjax2/install-requires.txt | 1 + .../jupyterlab_mathjax2/package-version.txt | 1 + build/pkgs/jupyterlab_mathjax2/type | 1 + 6 files changed, 30 insertions(+) create mode 100644 build/pkgs/jupyterlab_mathjax2/SPKG.rst create mode 100644 build/pkgs/jupyterlab_mathjax2/checksums.ini create mode 100644 build/pkgs/jupyterlab_mathjax2/dependencies create mode 100644 build/pkgs/jupyterlab_mathjax2/install-requires.txt create mode 100644 build/pkgs/jupyterlab_mathjax2/package-version.txt create mode 100644 build/pkgs/jupyterlab_mathjax2/type diff --git a/build/pkgs/jupyterlab_mathjax2/SPKG.rst b/build/pkgs/jupyterlab_mathjax2/SPKG.rst new file mode 100644 index 00000000000..521fef10085 --- /dev/null +++ b/build/pkgs/jupyterlab_mathjax2/SPKG.rst @@ -0,0 +1,18 @@ +jupyterlab_mathjax2: A MathJax Typesetting provider for JupyterLab 4 and above +============================================================================== + +Description +----------- + +A MathJax Typesetting provider for JupyterLab 4 and above + +License +------- + +BSD 3-Clause License Copyright (c) 2023, Project Jupyter All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Upstream Contact +---------------- + +https://pypi.org/project/jupyterlab-mathjax2/ + diff --git a/build/pkgs/jupyterlab_mathjax2/checksums.ini b/build/pkgs/jupyterlab_mathjax2/checksums.ini new file mode 100644 index 00000000000..6a428bd21dc --- /dev/null +++ b/build/pkgs/jupyterlab_mathjax2/checksums.ini @@ -0,0 +1,5 @@ +tarball=jupyterlab_mathjax2-VERSION-py3-none-any.whl +sha1=4e2bb182594a6c4f5d4edfb4f6e33597f09de402 +md5=4172e36b068af6a3f36c26a3f1946dc9 +cksum=387386440 +upstream_url=https://pypi.io/packages/py3/j/jupyterlab_mathjax2/jupyterlab_mathjax2-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab_mathjax2/dependencies b/build/pkgs/jupyterlab_mathjax2/dependencies new file mode 100644 index 00000000000..47296a7bace --- /dev/null +++ b/build/pkgs/jupyterlab_mathjax2/dependencies @@ -0,0 +1,4 @@ + | $(PYTHON_TOOLCHAIN) $(PYTHON) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyterlab_mathjax2/install-requires.txt b/build/pkgs/jupyterlab_mathjax2/install-requires.txt new file mode 100644 index 00000000000..d0db4b4ac19 --- /dev/null +++ b/build/pkgs/jupyterlab_mathjax2/install-requires.txt @@ -0,0 +1 @@ +jupyterlab-mathjax2 diff --git a/build/pkgs/jupyterlab_mathjax2/package-version.txt b/build/pkgs/jupyterlab_mathjax2/package-version.txt new file mode 100644 index 00000000000..fcdb2e109f6 --- /dev/null +++ b/build/pkgs/jupyterlab_mathjax2/package-version.txt @@ -0,0 +1 @@ +4.0.0 diff --git a/build/pkgs/jupyterlab_mathjax2/type b/build/pkgs/jupyterlab_mathjax2/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/jupyterlab_mathjax2/type @@ -0,0 +1 @@ +standard From f62df2519f88857053eab27a983fa2110229836a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:20:19 -0700 Subject: [PATCH 411/463] build/pkgs/ipywidgets: Update to 8.1.1 --- build/pkgs/ipywidgets/checksums.ini | 6 +++--- build/pkgs/ipywidgets/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/ipywidgets/checksums.ini b/build/pkgs/ipywidgets/checksums.ini index d52277d3241..a04080bb509 100644 --- a/build/pkgs/ipywidgets/checksums.ini +++ b/build/pkgs/ipywidgets/checksums.ini @@ -1,5 +1,5 @@ tarball=ipywidgets-VERSION.tar.gz -sha1=cf0ae8f3f8340230f59f23781987ad0ba6737d88 -md5=3121e08d2fc2672fc1068e147048784a -cksum=2673660683 +sha1=95f7ec13e8ce75e2da40c1789b4af291946a6d99 +md5=2809d1668037606caac588cab329bece +cksum=1839869422 upstream_url=https://pypi.io/packages/source/i/ipywidgets/ipywidgets-VERSION.tar.gz diff --git a/build/pkgs/ipywidgets/package-version.txt b/build/pkgs/ipywidgets/package-version.txt index 8104cabd36f..0e79152459e 100644 --- a/build/pkgs/ipywidgets/package-version.txt +++ b/build/pkgs/ipywidgets/package-version.txt @@ -1 +1 @@ -8.1.0 +8.1.1 From a8102689688836e58a09f49789038e43fedec6b6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:22:15 -0700 Subject: [PATCH 412/463] build/pkgs/notebook: Update to 7.0.4 --- build/pkgs/notebook/checksums.ini | 6 +++--- build/pkgs/notebook/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/notebook/checksums.ini b/build/pkgs/notebook/checksums.ini index 82bd76cd73c..6ca7d2f1cdd 100644 --- a/build/pkgs/notebook/checksums.ini +++ b/build/pkgs/notebook/checksums.ini @@ -1,5 +1,5 @@ tarball=notebook-VERSION-py3-none-any.whl -sha1=433b91fb8857e2244515e8ae2e873880b3323d64 -md5=edc9b8e695f6f712a577c8afebfcd784 -cksum=1990528497 +sha1=7fdcf39856537f7451648665a8c7073ca49e17aa +md5=b125816110bca7fd435446425f9b1b14 +cksum=681260324 upstream_url=https://pypi.io/packages/py3/n/notebook/notebook-VERSION-py3-none-any.whl diff --git a/build/pkgs/notebook/package-version.txt b/build/pkgs/notebook/package-version.txt index a50da181e9b..4489f5a6df8 100644 --- a/build/pkgs/notebook/package-version.txt +++ b/build/pkgs/notebook/package-version.txt @@ -1 +1 @@ -7.0.3 +7.0.4 From 279b23a9af989fb261c25984e643c1af252e4f8f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:25:58 -0700 Subject: [PATCH 413/463] build/pkgs/urllib3: Update to 2.0.5 --- build/pkgs/urllib3/checksums.ini | 6 +++--- build/pkgs/urllib3/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/urllib3/checksums.ini b/build/pkgs/urllib3/checksums.ini index d0f5f9320c7..758013b041c 100644 --- a/build/pkgs/urllib3/checksums.ini +++ b/build/pkgs/urllib3/checksums.ini @@ -1,5 +1,5 @@ tarball=urllib3-VERSION.tar.gz -sha1=d7f301a1dcb37c46e300f1ce4463e10198ab974f -md5=5d541b944febe50221e24c31cd6e887d -cksum=447764521 +sha1=b784e5ebe0377d45a406665f3a3fad2616cbed22 +md5=4d824b7bba1976591fc05fad02fb258d +cksum=3511203397 upstream_url=https://pypi.io/packages/source/u/urllib3/urllib3-VERSION.tar.gz diff --git a/build/pkgs/urllib3/package-version.txt b/build/pkgs/urllib3/package-version.txt index 2165f8f9b6a..e01025862f7 100644 --- a/build/pkgs/urllib3/package-version.txt +++ b/build/pkgs/urllib3/package-version.txt @@ -1 +1 @@ -2.0.4 +2.0.5 From a1e6fe0a6c5c0bf6d03f00c6e241df98042a5989 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:27:40 -0700 Subject: [PATCH 414/463] build/pkgs/jupyterlab_server: Update to 2.25.0 --- build/pkgs/jupyterlab_server/checksums.ini | 6 +++--- build/pkgs/jupyterlab_server/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyterlab_server/checksums.ini b/build/pkgs/jupyterlab_server/checksums.ini index 3bd8926fd7b..b12d0dfc818 100644 --- a/build/pkgs/jupyterlab_server/checksums.ini +++ b/build/pkgs/jupyterlab_server/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyterlab_server-VERSION-py3-none-any.whl -sha1=1fff8c8bc4c81b006cb83d4524dc8a6f3364e57c -md5=795bbf343ae17b75a31a50ef574d4b77 -cksum=696988100 +sha1=52e71089cd4bfa5cba04b29466d9ca3ab6deb748 +md5=69efd95154a579493aa5a083e150ce01 +cksum=3821437972 upstream_url=https://pypi.io/packages/py3/j/jupyterlab_server/jupyterlab_server-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab_server/package-version.txt b/build/pkgs/jupyterlab_server/package-version.txt index ad2261920c0..5c18f9195b5 100644 --- a/build/pkgs/jupyterlab_server/package-version.txt +++ b/build/pkgs/jupyterlab_server/package-version.txt @@ -1 +1 @@ -2.24.0 +2.25.0 From ff97a1d6f43cb99b212ee6818ca4c4a1dbd53b7a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:27:47 -0700 Subject: [PATCH 415/463] build/pkgs/jupyter_server: Update to 2.7.3 --- build/pkgs/jupyter_server/checksums.ini | 6 +++--- build/pkgs/jupyter_server/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyter_server/checksums.ini b/build/pkgs/jupyter_server/checksums.ini index 5ff8fec7b23..e81f1110be3 100644 --- a/build/pkgs/jupyter_server/checksums.ini +++ b/build/pkgs/jupyter_server/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyter_server-VERSION-py3-none-any.whl -sha1=17dc2fb6998e00d25979342673f030f9aad7ae83 -md5=71d3d41c11faa3e9f3cd39f9da594a86 -cksum=354373153 +sha1=a54aa7f6f1657a55cae9ecc4a6654b6e3ca5fb73 +md5=b028711b35fa80f6c7b01a54bd70718a +cksum=1159424906 upstream_url=https://pypi.io/packages/py3/j/jupyter_server/jupyter_server-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_server/package-version.txt b/build/pkgs/jupyter_server/package-version.txt index 37c2961c243..2c9b4ef42ec 100644 --- a/build/pkgs/jupyter_server/package-version.txt +++ b/build/pkgs/jupyter_server/package-version.txt @@ -1 +1 @@ -2.7.2 +2.7.3 From 46b116dd82a23a1b99f073323b311415e42db152 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:27:58 -0700 Subject: [PATCH 416/463] build/pkgs/jupyterlab: Update to 4.0.6 --- build/pkgs/jupyterlab/checksums.ini | 6 +++--- build/pkgs/jupyterlab/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyterlab/checksums.ini b/build/pkgs/jupyterlab/checksums.ini index 8dba14bbe00..8ce07466089 100644 --- a/build/pkgs/jupyterlab/checksums.ini +++ b/build/pkgs/jupyterlab/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyterlab-VERSION-py3-none-any.whl -sha1=eb08c6639c36d0a4ba39f123d352f9a04cb74a00 -md5=0f98f63b89302b61495454b346add431 -cksum=3453842466 +sha1=06ca895226e055d4bf92f3971eab23035d9c18c7 +md5=a608fbbd9a4616afcc8b0f2e9e0c76ef +cksum=1688505838 upstream_url=https://pypi.io/packages/py3/j/jupyterlab/jupyterlab-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab/package-version.txt b/build/pkgs/jupyterlab/package-version.txt index 7636e75650d..d13e837c8ec 100644 --- a/build/pkgs/jupyterlab/package-version.txt +++ b/build/pkgs/jupyterlab/package-version.txt @@ -1 +1 @@ -4.0.5 +4.0.6 From e63c63328d0bd9eaf1bc6aa6125621b1721aa09f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:29:11 -0700 Subject: [PATCH 417/463] build/pkgs/beautifulsoup4: Update to 4.12.2 --- build/pkgs/beautifulsoup4/checksums.ini | 6 +++--- build/pkgs/beautifulsoup4/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/beautifulsoup4/checksums.ini b/build/pkgs/beautifulsoup4/checksums.ini index aa0baa2216c..0fd063dd71c 100644 --- a/build/pkgs/beautifulsoup4/checksums.ini +++ b/build/pkgs/beautifulsoup4/checksums.ini @@ -1,5 +1,5 @@ tarball=beautifulsoup4-VERSION.tar.gz -sha1=fbb73ba4221122b56cd4eac2d9e5d3ad2e383ae0 -md5=22f22f89cf9da41b22e1ece9639c66a3 -cksum=2807377018 +sha1=d9cd72f81e7710692b8ff0a42e69bf93375b5fd3 +md5=b49a6696a762e946c2be97c36a5adaa8 +cksum=839566236 upstream_url=https://pypi.io/packages/source/b/beautifulsoup4/beautifulsoup4-VERSION.tar.gz diff --git a/build/pkgs/beautifulsoup4/package-version.txt b/build/pkgs/beautifulsoup4/package-version.txt index d782fca8f64..f1cd7de1de5 100644 --- a/build/pkgs/beautifulsoup4/package-version.txt +++ b/build/pkgs/beautifulsoup4/package-version.txt @@ -1 +1 @@ -4.11.1 +4.12.2 From 0aa422b00e442d50a21753c289a8ee2981446831 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:37:28 -0700 Subject: [PATCH 418/463] build/pkgs/websocket_client: Update to 1.6.3 --- build/pkgs/websocket_client/checksums.ini | 6 +++--- build/pkgs/websocket_client/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/websocket_client/checksums.ini b/build/pkgs/websocket_client/checksums.ini index 916f8ae6a45..57faf28b688 100644 --- a/build/pkgs/websocket_client/checksums.ini +++ b/build/pkgs/websocket_client/checksums.ini @@ -1,5 +1,5 @@ tarball=websocket_client-VERSION-py3-none-any.whl -sha1=4e387c09ed3ec0c15eb6bd3dcd343cf18f028f95 -md5=02d92a8221cc6d8fd2d22c370aa05ef3 -cksum=3728437026 +sha1=92a12b97f51ee3916233ced535f84034350c10f9 +md5=95118bd01e2c0be8cc46407e11792622 +cksum=1792172292 upstream_url=https://pypi.io/packages/py3/w/websocket_client/websocket_client-VERSION-py3-none-any.whl diff --git a/build/pkgs/websocket_client/package-version.txt b/build/pkgs/websocket_client/package-version.txt index fdd3be6df54..266146b87cb 100644 --- a/build/pkgs/websocket_client/package-version.txt +++ b/build/pkgs/websocket_client/package-version.txt @@ -1 +1 @@ -1.6.2 +1.6.3 From d20d99638d0bfc7a5b5e8c3d1514e04fa66592fb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:37:47 -0700 Subject: [PATCH 419/463] build/pkgs/widgetsnbextension: Update to 4.0.9 --- build/pkgs/widgetsnbextension/checksums.ini | 6 +++--- build/pkgs/widgetsnbextension/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/widgetsnbextension/checksums.ini b/build/pkgs/widgetsnbextension/checksums.ini index 30e08312a8f..6c7893d9502 100644 --- a/build/pkgs/widgetsnbextension/checksums.ini +++ b/build/pkgs/widgetsnbextension/checksums.ini @@ -1,5 +1,5 @@ tarball=widgetsnbextension-VERSION-py3-none-any.whl -sha1=1ffb84b17fca00a6e4bbad41f395ed6f37e1c6b9 -md5=38786a4166938b1b4165a76c244c3fc9 -cksum=2255132975 +sha1=067535b5d1738a4de0abb5f1219581a4a66d243c +md5=ac2760673371602f990bb24ac7925c5f +cksum=1509404095 upstream_url=https://pypi.io/packages/py3/w/widgetsnbextension/widgetsnbextension-VERSION-py3-none-any.whl diff --git a/build/pkgs/widgetsnbextension/package-version.txt b/build/pkgs/widgetsnbextension/package-version.txt index a2cec7aff41..7919852fe10 100644 --- a/build/pkgs/widgetsnbextension/package-version.txt +++ b/build/pkgs/widgetsnbextension/package-version.txt @@ -1 +1 @@ -4.0.8 +4.0.9 From d8556ddcf0abad3492d6b997d0d4d20e36812080 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:37:58 -0700 Subject: [PATCH 420/463] build/pkgs/zipp: Update to 3.17.0 --- build/pkgs/zipp/checksums.ini | 6 +++--- build/pkgs/zipp/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/zipp/checksums.ini b/build/pkgs/zipp/checksums.ini index 755124ecd6b..66cd13339d6 100644 --- a/build/pkgs/zipp/checksums.ini +++ b/build/pkgs/zipp/checksums.ini @@ -1,5 +1,5 @@ tarball=zipp-VERSION.tar.gz -sha1=2bd770f0093ce7ebb11d8f56b0ea8eda0e392fe4 -md5=f5c13dccedc282cbe50aae5983de7fe4 -cksum=3895521123 +sha1=a9f9aebc205b7829c43b34e79c3f87c42b183176 +md5=a4cf8c530da863c27a04251724436681 +cksum=1303269799 upstream_url=https://pypi.io/packages/source/z/zipp/zipp-VERSION.tar.gz diff --git a/build/pkgs/zipp/package-version.txt b/build/pkgs/zipp/package-version.txt index 21221d0e7a4..3f67e25cea1 100644 --- a/build/pkgs/zipp/package-version.txt +++ b/build/pkgs/zipp/package-version.txt @@ -1 +1 @@ -3.16.2 +3.17.0 From c453e07409afdf7dedde11e19997d6c112b5c7b5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:46:53 -0700 Subject: [PATCH 421/463] build/pkgs/pyyaml: Add to dependencies --- build/pkgs/pyyaml/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/pyyaml/dependencies b/build/pkgs/pyyaml/dependencies index 0738c2d7777..909380550a2 100644 --- a/build/pkgs/pyyaml/dependencies +++ b/build/pkgs/pyyaml/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) cython $(PYTHON) ---------- All lines of this file are ignored except the first. From c50f6bdb6b0458c9846583f4ec36f7532d7bbac6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 13:29:16 -0700 Subject: [PATCH 422/463] build/pkgs/jupyterlab_widgets: Update to 3.0.9 --- build/pkgs/jupyterlab_widgets/checksums.ini | 6 +++--- build/pkgs/jupyterlab_widgets/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyterlab_widgets/checksums.ini b/build/pkgs/jupyterlab_widgets/checksums.ini index 3708a7bfab4..7da29e7849e 100644 --- a/build/pkgs/jupyterlab_widgets/checksums.ini +++ b/build/pkgs/jupyterlab_widgets/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyterlab_widgets-VERSION-py3-none-any.whl -sha1=2341a44d66dd3fb634ddb77df3ef8f9bae7317d4 -md5=e944763f6aac1688c14c301fdc9846b5 -cksum=2383886392 +sha1=b10775bb3966af627bb44fbda4efb553b24a5b93 +md5=fc3c9f41000461dbdca2b965fcee37db +cksum=441194289 upstream_url=https://pypi.io/packages/py3/j/jupyterlab_widgets/jupyterlab_widgets-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab_widgets/package-version.txt b/build/pkgs/jupyterlab_widgets/package-version.txt index 67786e246ef..747457c6d22 100644 --- a/build/pkgs/jupyterlab_widgets/package-version.txt +++ b/build/pkgs/jupyterlab_widgets/package-version.txt @@ -1 +1 @@ -3.0.8 +3.0.9 From 0f4a8ebd6f565ab140d5f2db0dc03669eb433e7b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 13:31:47 -0700 Subject: [PATCH 423/463] build/pkgs/ipympl: Make standard --- build/pkgs/ipympl/type | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/ipympl/type b/build/pkgs/ipympl/type index 134d9bc32d5..a6a7b9cd726 100644 --- a/build/pkgs/ipympl/type +++ b/build/pkgs/ipympl/type @@ -1 +1 @@ -optional +standard From 439422d21527f5bfdb68a34e0145b7379e771e3b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 13:39:46 -0700 Subject: [PATCH 424/463] build/pkgs/jupyterlab_server: Remove circular dep on jupyterlab --- build/pkgs/jupyterlab_server/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/jupyterlab_server/dependencies b/build/pkgs/jupyterlab_server/dependencies index 72b740a6c66..8a1817a0d0d 100644 --- a/build/pkgs/jupyterlab_server/dependencies +++ b/build/pkgs/jupyterlab_server/dependencies @@ -1,4 +1,4 @@ - babel jupyterlab jupyter_events jupyter_server json5 jsonschema requests | $(PYTHON_TOOLCHAIN) $(PYTHON) +babel jupyter_events jupyter_server json5 jsonschema requests | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. From 9feba2c087a28d9419c0efc5708112075d9bbc53 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Sep 2023 16:06:25 -0700 Subject: [PATCH 425/463] build/pkgs/debugpy: Update to 1.8.0 --- build/pkgs/debugpy/checksums.ini | 6 +++--- build/pkgs/debugpy/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/debugpy/checksums.ini b/build/pkgs/debugpy/checksums.ini index 0f957eea07f..43f1c2c84a5 100644 --- a/build/pkgs/debugpy/checksums.ini +++ b/build/pkgs/debugpy/checksums.ini @@ -1,5 +1,5 @@ tarball=debugpy-VERSION.zip -sha1=dd59205316ac2019b3066ac8c23796d44eb2f273 -md5=7dd011f0e980e55ff55028b82db65cd0 -cksum=3386350262 +sha1=af611dc5c401424196c27363379fc483814efe26 +md5=b4a6173035b58a0ad61561a4c5017885 +cksum=57995549 upstream_url=https://pypi.io/packages/source/d/debugpy/debugpy-VERSION.zip diff --git a/build/pkgs/debugpy/package-version.txt b/build/pkgs/debugpy/package-version.txt index d755e2f5bb7..27f9cd322bb 100644 --- a/build/pkgs/debugpy/package-version.txt +++ b/build/pkgs/debugpy/package-version.txt @@ -1 +1 @@ -1.6.7.post1 +1.8.0 From ffeaa66c59ab16147fa9ca38fd3581c1999e53fa Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Sep 2023 16:07:24 -0700 Subject: [PATCH 426/463] build/pkgs/importlib_resources: Update to 6.1.0 --- build/pkgs/importlib_resources/checksums.ini | 6 +++--- build/pkgs/importlib_resources/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/importlib_resources/checksums.ini b/build/pkgs/importlib_resources/checksums.ini index 5f8bc23a6fd..39040fbf296 100644 --- a/build/pkgs/importlib_resources/checksums.ini +++ b/build/pkgs/importlib_resources/checksums.ini @@ -1,5 +1,5 @@ tarball=importlib_resources-VERSION.tar.gz -sha1=dc5322c0a6414fa823f54ef7fe938210abecd6a8 -md5=ebb549867902e44c9314ac3998e0d31f -cksum=3214105952 +sha1=4af82ed75a1672a45157bfa7d09c4dfd0605802a +md5=525d238db212bdec2df06c0d4b479e73 +cksum=1494471486 upstream_url=https://pypi.io/packages/source/i/importlib_resources/importlib_resources-VERSION.tar.gz diff --git a/build/pkgs/importlib_resources/package-version.txt b/build/pkgs/importlib_resources/package-version.txt index 5fe60723048..dfda3e0b4f0 100644 --- a/build/pkgs/importlib_resources/package-version.txt +++ b/build/pkgs/importlib_resources/package-version.txt @@ -1 +1 @@ -6.0.1 +6.1.0 From 2b2fb16313bf9fa4b28dd00b90339145514b8334 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Sep 2023 16:09:21 -0700 Subject: [PATCH 427/463] build/pkgs/jupyter_core: Update to 5.3.2 --- build/pkgs/jupyter_core/checksums.ini | 6 +++--- build/pkgs/jupyter_core/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyter_core/checksums.ini b/build/pkgs/jupyter_core/checksums.ini index cf968d4a511..0c807beeff7 100644 --- a/build/pkgs/jupyter_core/checksums.ini +++ b/build/pkgs/jupyter_core/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyter_core-VERSION.tar.gz -sha1=bd666ad6cb0484e1704fc73a828f6671a8bb9641 -md5=b9b8f90ee76509fba4c63f90c9d39d8b -cksum=2599933228 +sha1=0fe33e3247e595cdb83e2220f02c566ea9397e6a +md5=1d61b3c16f6781d8f44e1bd95cd8e73f +cksum=523684111 upstream_url=https://pypi.io/packages/source/j/jupyter_core/jupyter_core-VERSION.tar.gz diff --git a/build/pkgs/jupyter_core/package-version.txt b/build/pkgs/jupyter_core/package-version.txt index c7cb1311a64..84197c89467 100644 --- a/build/pkgs/jupyter_core/package-version.txt +++ b/build/pkgs/jupyter_core/package-version.txt @@ -1 +1 @@ -5.3.1 +5.3.2 From 99897e8ce086025b8562959a78d53bcee39f0a72 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Sep 2023 16:11:44 -0700 Subject: [PATCH 428/463] build/pkgs/nbconvert: Update to 7.8.0 --- build/pkgs/nbconvert/checksums.ini | 6 +++--- build/pkgs/nbconvert/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/nbconvert/checksums.ini b/build/pkgs/nbconvert/checksums.ini index 3ba9564f206..76bac50fd74 100644 --- a/build/pkgs/nbconvert/checksums.ini +++ b/build/pkgs/nbconvert/checksums.ini @@ -1,5 +1,5 @@ tarball=nbconvert-VERSION-py3-none-any.whl -sha1=561265d271f3024ed072cb9a203dfaa8d7addf43 -md5=5e0b48c5f0483ff4ef5ef7bd4858fa95 -cksum=126073822 +sha1=29dc4ab9fd86736b414a141e543f3e652aaae8e3 +md5=d375a9cacbedb178d0f80b18b434185b +cksum=87589391 upstream_url=https://pypi.io/packages/py3/n/nbconvert/nbconvert-VERSION-py3-none-any.whl diff --git a/build/pkgs/nbconvert/package-version.txt b/build/pkgs/nbconvert/package-version.txt index 2de5f33fb8c..09a6d30847d 100644 --- a/build/pkgs/nbconvert/package-version.txt +++ b/build/pkgs/nbconvert/package-version.txt @@ -1 +1 @@ -7.7.4 +7.8.0 From bcd359ee9debdad92abc8be9f252f2c744d5a7a6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Sep 2023 16:13:28 -0700 Subject: [PATCH 429/463] build/pkgs/nest_asyncio: Update to 1.5.8 --- build/pkgs/nest_asyncio/checksums.ini | 6 +++--- build/pkgs/nest_asyncio/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/nest_asyncio/checksums.ini b/build/pkgs/nest_asyncio/checksums.ini index 498f877da48..9752b8da3bb 100644 --- a/build/pkgs/nest_asyncio/checksums.ini +++ b/build/pkgs/nest_asyncio/checksums.ini @@ -1,5 +1,5 @@ tarball=nest_asyncio-VERSION.tar.gz -sha1=cba134c03c8a01f798de46f62755e0813b6b4556 -md5=577ade8444e1429c62b63854e5e67c3d -cksum=334638127 +sha1=e7d8036f6558011c5ae0c649e0af21eb530044d3 +md5=9f0fe9ca229b1eef6e1ffba266413616 +cksum=3560927178 upstream_url=https://pypi.io/packages/source/n/nest_asyncio/nest_asyncio-VERSION.tar.gz diff --git a/build/pkgs/nest_asyncio/package-version.txt b/build/pkgs/nest_asyncio/package-version.txt index f01291b87fd..1cc9c180e26 100644 --- a/build/pkgs/nest_asyncio/package-version.txt +++ b/build/pkgs/nest_asyncio/package-version.txt @@ -1 +1 @@ -1.5.7 +1.5.8 From fdf21c5b15b93f94f7c496609a6b289a1bbc6fe5 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 29 Sep 2023 13:35:00 +0100 Subject: [PATCH 430/463] patch pyyaml for Cython 3+ --- .../pyyaml/patches/pyyaml-6.0.1-cython3.patch | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 build/pkgs/pyyaml/patches/pyyaml-6.0.1-cython3.patch diff --git a/build/pkgs/pyyaml/patches/pyyaml-6.0.1-cython3.patch b/build/pkgs/pyyaml/patches/pyyaml-6.0.1-cython3.patch new file mode 100644 index 00000000000..d55db130977 --- /dev/null +++ b/build/pkgs/pyyaml/patches/pyyaml-6.0.1-cython3.patch @@ -0,0 +1,33 @@ +From 17dc5b6cd96dcfe64fd71789c771ca9b96d260e5 Mon Sep 17 00:00:00 2001 +From: "Andrew J. Hesford" +Date: Fri, 21 Jul 2023 09:50:00 -0400 +Subject: [PATCH] Fix builds with Cython 3 + +This is a *de minimis* fix for building with Cython 3. Recent Cython<3 +releases provided `Cython.Distutils.build_ext` as an alias to +`Cython.Distutils.old_build_ext.old_build_ext`; Cython 3 drops this +alias and instead uses a wholly new `Cython.Distutils.build_ext` that +does not provide the `cython_sources` function used in `setup.py`. + +Explicitly importing `old_build_ext` preserves the existing behavior for +recent Cython<3 and uses the correct behavior for Cython 3. Should the +import fail (*e.g.*, because the version of Cython available predates +the availability of `old_build_ext`), the import falls back to just +`Cython.Distutils.build_ext`. + +Signed-off-by: Andrew J. Hesford +--- a/setup.py ++++ b/setup.py +@@ -82,7 +82,11 @@ + with_cython = True + try: + from Cython.Distutils.extension import Extension as _Extension +- from Cython.Distutils import build_ext as _build_ext ++ try: ++ from Cython.Distutils.old_build_ext import old_build_ext as _build_ext ++ except ImportError: ++ from Cython.Distutils import build_ext as _build_ext ++ + with_cython = True + except ImportError: + if with_cython: From 121a00ba6b820adeae6f80e810b4d297a5a92a97 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 30 Sep 2023 10:28:26 -0700 Subject: [PATCH 431/463] build/pkgs/jupyter_core/dependencies: Add hatchling --- build/pkgs/jupyter_core/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/jupyter_core/dependencies b/build/pkgs/jupyter_core/dependencies index 0e3bf021c04..7099b915818 100644 --- a/build/pkgs/jupyter_core/dependencies +++ b/build/pkgs/jupyter_core/dependencies @@ -1,4 +1,4 @@ -platformdirs traitlets | $(PYTHON_TOOLCHAIN) $(PYTHON) +platformdirs traitlets | $(PYTHON_TOOLCHAIN) hatchling $(PYTHON) ---------- All lines of this file are ignored except the first. From b9330a26ca6acde7e7ff478f4e209b320080b05f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 09:29:42 -0700 Subject: [PATCH 432/463] build/pkgs/arrow: Update to 1.3.0 --- build/pkgs/arrow/checksums.ini | 6 +++--- build/pkgs/arrow/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/arrow/checksums.ini b/build/pkgs/arrow/checksums.ini index c7ca33b4062..8823edda27e 100644 --- a/build/pkgs/arrow/checksums.ini +++ b/build/pkgs/arrow/checksums.ini @@ -1,5 +1,5 @@ tarball=arrow-VERSION-py3-none-any.whl -sha1=b336eb2a0cbb7590f677e322e4dc7a343f168e04 -md5=9410a9b3db672ccc17314da703e17b35 -cksum=546923343 +sha1=fd9376ef4788dc2b1c981e6b5beb9048e046c556 +md5=71d18bb3d882ae242b5b1a397313bb12 +cksum=244356435 upstream_url=https://pypi.io/packages/py3/a/arrow/arrow-VERSION-py3-none-any.whl diff --git a/build/pkgs/arrow/package-version.txt b/build/pkgs/arrow/package-version.txt index 0495c4a88ca..f0bb29e7638 100644 --- a/build/pkgs/arrow/package-version.txt +++ b/build/pkgs/arrow/package-version.txt @@ -1 +1 @@ -1.2.3 +1.3.0 From c7a891e2b3301f995e069802a5769c6871481e3a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 09:31:18 -0700 Subject: [PATCH 433/463] build/pkgs/bleach: Update to 6.1.0 --- build/pkgs/bleach/checksums.ini | 6 +++--- build/pkgs/bleach/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/bleach/checksums.ini b/build/pkgs/bleach/checksums.ini index 9c220829178..33843727cd9 100644 --- a/build/pkgs/bleach/checksums.ini +++ b/build/pkgs/bleach/checksums.ini @@ -1,5 +1,5 @@ tarball=bleach-VERSION-py3-none-any.whl -sha1=2c26315754501b4449d4cbbdc95c1c4cc9daf526 -md5=f3768630dc40d44f0a9a1b2023e6fcc7 -cksum=3947199582 +sha1=7ba81a446171fb840d3083afadd0c87f0b599305 +md5=ec9e860103ffbc3e6e9963485464bfbc +cksum=1174632300 upstream_url=https://pypi.io/packages/py3/b/bleach/bleach-VERSION-py3-none-any.whl diff --git a/build/pkgs/bleach/package-version.txt b/build/pkgs/bleach/package-version.txt index 09b254e90c6..dfda3e0b4f0 100644 --- a/build/pkgs/bleach/package-version.txt +++ b/build/pkgs/bleach/package-version.txt @@ -1 +1 @@ -6.0.0 +6.1.0 From d9fd47e1cf77c5ffccf3f12fd45c901e1f8b2c42 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 09:36:10 -0700 Subject: [PATCH 434/463] build/pkgs/jupyter_client: Update to 8.3.1 --- build/pkgs/jupyter_client/checksums.ini | 6 +++--- build/pkgs/jupyter_client/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyter_client/checksums.ini b/build/pkgs/jupyter_client/checksums.ini index cd9d883763e..b91837ba332 100644 --- a/build/pkgs/jupyter_client/checksums.ini +++ b/build/pkgs/jupyter_client/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyter_client-VERSION-py3-none-any.whl -sha1=d3f338ea9ca02bdb47f5cdb89b81cd9f375f9d6c -md5=a1044eb70daee63d637859d89de6e5a9 -cksum=503921402 +sha1=341f822626b55b53f03a21a44d78dc203472406b +md5=cca418dacc69d69f3e3c71704f1fd259 +cksum=753481733 upstream_url=https://pypi.io/packages/py3/j/jupyter_client/jupyter_client-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_client/package-version.txt b/build/pkgs/jupyter_client/package-version.txt index 14ebea1f124..56b6be4ebb2 100644 --- a/build/pkgs/jupyter_client/package-version.txt +++ b/build/pkgs/jupyter_client/package-version.txt @@ -1 +1 @@ -7.4.9 +8.3.1 From d258c18d05a0b26557c25af103be3aa5a4be8de3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 09:41:28 -0700 Subject: [PATCH 435/463] build/pkgs/nbconvert: Update to 7.9.2 --- build/pkgs/nbconvert/checksums.ini | 6 +++--- build/pkgs/nbconvert/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/nbconvert/checksums.ini b/build/pkgs/nbconvert/checksums.ini index 76bac50fd74..20eb0e3e2df 100644 --- a/build/pkgs/nbconvert/checksums.ini +++ b/build/pkgs/nbconvert/checksums.ini @@ -1,5 +1,5 @@ tarball=nbconvert-VERSION-py3-none-any.whl -sha1=29dc4ab9fd86736b414a141e543f3e652aaae8e3 -md5=d375a9cacbedb178d0f80b18b434185b -cksum=87589391 +sha1=5317fa68bbd7f66fc3fcc5b0e6b0d6e2df967ba0 +md5=ad534f2db53d8677b790be0e98992f8e +cksum=2885634129 upstream_url=https://pypi.io/packages/py3/n/nbconvert/nbconvert-VERSION-py3-none-any.whl diff --git a/build/pkgs/nbconvert/package-version.txt b/build/pkgs/nbconvert/package-version.txt index 09a6d30847d..33d00300e4a 100644 --- a/build/pkgs/nbconvert/package-version.txt +++ b/build/pkgs/nbconvert/package-version.txt @@ -1 +1 @@ -7.8.0 +7.9.2 From fa6f58629e6874aa4c50ad728ef6ac8555d5a942 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 09:50:34 -0700 Subject: [PATCH 436/463] build/pkgs/websocket_client: Update to 1.6.4 --- build/pkgs/websocket_client/checksums.ini | 6 +++--- build/pkgs/websocket_client/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/websocket_client/checksums.ini b/build/pkgs/websocket_client/checksums.ini index 57faf28b688..5ebee45e9f9 100644 --- a/build/pkgs/websocket_client/checksums.ini +++ b/build/pkgs/websocket_client/checksums.ini @@ -1,5 +1,5 @@ tarball=websocket_client-VERSION-py3-none-any.whl -sha1=92a12b97f51ee3916233ced535f84034350c10f9 -md5=95118bd01e2c0be8cc46407e11792622 -cksum=1792172292 +sha1=eb78bd39f1ae4d531cc965bd21d121ba3d156f84 +md5=bea7b61d0eda66ffb9071c469d937255 +cksum=21706746 upstream_url=https://pypi.io/packages/py3/w/websocket_client/websocket_client-VERSION-py3-none-any.whl diff --git a/build/pkgs/websocket_client/package-version.txt b/build/pkgs/websocket_client/package-version.txt index 266146b87cb..9edc58bb1dd 100644 --- a/build/pkgs/websocket_client/package-version.txt +++ b/build/pkgs/websocket_client/package-version.txt @@ -1 +1 @@ -1.6.3 +1.6.4 From d66d213b1ba53e8609b946be4fd57fe375063f40 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 09:52:01 -0700 Subject: [PATCH 437/463] build/pkgs/*/dependencies: Make PYTHON order-only --- build/pkgs/anyio/dependencies | 2 +- build/pkgs/async_lru/dependencies | 2 +- build/pkgs/calver/dependencies | 2 +- build/pkgs/comm/dependencies | 2 +- build/pkgs/fqdn/dependencies | 2 +- build/pkgs/json5/dependencies | 2 +- build/pkgs/jsonpointer/dependencies | 2 +- build/pkgs/jsonschema_specifications/dependencies | 2 +- build/pkgs/jupyter_events/dependencies | 2 +- build/pkgs/jupyter_lsp/dependencies | 2 +- build/pkgs/jupyter_server/dependencies | 2 +- build/pkgs/jupyter_server_terminals/dependencies | 2 +- build/pkgs/notebook/dependencies | 2 +- build/pkgs/notebook_shim/dependencies | 2 +- build/pkgs/notedown/dependencies | 2 +- build/pkgs/overrides/dependencies | 2 +- build/pkgs/pandoc_attributes/dependencies | 2 +- build/pkgs/python_json_logger/dependencies | 2 +- build/pkgs/referencing/dependencies | 2 +- build/pkgs/rfc3339_validator/dependencies | 2 +- build/pkgs/rfc3986_validator/dependencies | 2 +- build/pkgs/sniffio/dependencies | 2 +- build/pkgs/uri_template/dependencies | 2 +- build/pkgs/urllib3/dependencies | 2 +- build/pkgs/webcolors/dependencies | 2 +- build/pkgs/websocket_client/dependencies | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/build/pkgs/anyio/dependencies b/build/pkgs/anyio/dependencies index 654e350b35c..5be99073470 100644 --- a/build/pkgs/anyio/dependencies +++ b/build/pkgs/anyio/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) idna sniffio | $(PYTHON_TOOLCHAIN) +idna sniffio | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/async_lru/dependencies b/build/pkgs/async_lru/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/async_lru/dependencies +++ b/build/pkgs/async_lru/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/calver/dependencies b/build/pkgs/calver/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/calver/dependencies +++ b/build/pkgs/calver/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/comm/dependencies b/build/pkgs/comm/dependencies index 1da34eeae60..73ec1534907 100644 --- a/build/pkgs/comm/dependencies +++ b/build/pkgs/comm/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) traitlets | $(PYTHON_TOOLCHAIN) +traitlets | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/fqdn/dependencies b/build/pkgs/fqdn/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/fqdn/dependencies +++ b/build/pkgs/fqdn/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/json5/dependencies b/build/pkgs/json5/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/json5/dependencies +++ b/build/pkgs/json5/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jsonpointer/dependencies b/build/pkgs/jsonpointer/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/jsonpointer/dependencies +++ b/build/pkgs/jsonpointer/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jsonschema_specifications/dependencies b/build/pkgs/jsonschema_specifications/dependencies index 845ff9a9aca..19f2b856671 100644 --- a/build/pkgs/jsonschema_specifications/dependencies +++ b/build/pkgs/jsonschema_specifications/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) referencing | $(PYTHON_TOOLCHAIN) + referencing | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_events/dependencies b/build/pkgs/jupyter_events/dependencies index 62262a4456c..f82f8a9adba 100644 --- a/build/pkgs/jupyter_events/dependencies +++ b/build/pkgs/jupyter_events/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) jsonschema python_json_logger pyyaml referencing rfc3339_validator rfc3986_validator | $(PYTHON_TOOLCHAIN) +jsonschema python_json_logger pyyaml referencing rfc3339_validator rfc3986_validator | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_lsp/dependencies b/build/pkgs/jupyter_lsp/dependencies index d7d6b2764a1..97d97af24c5 100644 --- a/build/pkgs/jupyter_lsp/dependencies +++ b/build/pkgs/jupyter_lsp/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) jupyter_server | $(PYTHON_TOOLCHAIN) +jupyter_server | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_server/dependencies b/build/pkgs/jupyter_server/dependencies index 2c70b9a3343..2b81efb7a64 100644 --- a/build/pkgs/jupyter_server/dependencies +++ b/build/pkgs/jupyter_server/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) anyio argon2_cffi jinja2 jupyter_client jupyter_core jupyter_events jupyter_server_terminals nbconvert nbformat overrides platformdirs prometheus_client pyzmq send2trash terminado tornado traitlets websocket_client | $(PYTHON_TOOLCHAIN) +anyio argon2_cffi jinja2 jupyter_client jupyter_core jupyter_events jupyter_server_terminals nbconvert nbformat overrides platformdirs prometheus_client pyzmq send2trash terminado tornado traitlets websocket_client | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyter_server_terminals/dependencies b/build/pkgs/jupyter_server_terminals/dependencies index 13b93d5c952..6aedae84479 100644 --- a/build/pkgs/jupyter_server_terminals/dependencies +++ b/build/pkgs/jupyter_server_terminals/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) terminado | $(PYTHON_TOOLCHAIN) +terminado | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/notebook/dependencies b/build/pkgs/notebook/dependencies index 3d42b5cbcc8..876c76eec23 100644 --- a/build/pkgs/notebook/dependencies +++ b/build/pkgs/notebook/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) jupyter_server jupyterlab_server jupyterlab notebook_shim | $(PYTHON_TOOLCHAIN) $(PYTHON) +jupyter_server jupyterlab_server jupyterlab notebook_shim | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/notebook_shim/dependencies b/build/pkgs/notebook_shim/dependencies index d7d6b2764a1..97d97af24c5 100644 --- a/build/pkgs/notebook_shim/dependencies +++ b/build/pkgs/notebook_shim/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) jupyter_server | $(PYTHON_TOOLCHAIN) +jupyter_server | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/notedown/dependencies b/build/pkgs/notedown/dependencies index 3dcb5b1900f..58f0c5d2c56 100644 --- a/build/pkgs/notedown/dependencies +++ b/build/pkgs/notedown/dependencies @@ -1,4 +1,4 @@ - $(PYTHON_TOOLCHAIN) | pip nbformat nbconvert six pandoc_attributes $(PYTHON) +nbformat nbconvert six pandoc_attributes | $(PYTHON) $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/overrides/dependencies b/build/pkgs/overrides/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/overrides/dependencies +++ b/build/pkgs/overrides/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/pandoc_attributes/dependencies b/build/pkgs/pandoc_attributes/dependencies index cc9d4970706..4d6a540cf45 100644 --- a/build/pkgs/pandoc_attributes/dependencies +++ b/build/pkgs/pandoc_attributes/dependencies @@ -1,4 +1,4 @@ - $(PYTHON_TOOLCHAIN) | pip pandocfilters $(PYTHON) + | pandocfilters $(PYTHON) $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/python_json_logger/dependencies b/build/pkgs/python_json_logger/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/python_json_logger/dependencies +++ b/build/pkgs/python_json_logger/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/referencing/dependencies b/build/pkgs/referencing/dependencies index 4fd4a024bd5..12067bf5c3e 100644 --- a/build/pkgs/referencing/dependencies +++ b/build/pkgs/referencing/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) attrs | $(PYTHON_TOOLCHAIN) +attrs | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/rfc3339_validator/dependencies b/build/pkgs/rfc3339_validator/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/rfc3339_validator/dependencies +++ b/build/pkgs/rfc3339_validator/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/rfc3986_validator/dependencies b/build/pkgs/rfc3986_validator/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/rfc3986_validator/dependencies +++ b/build/pkgs/rfc3986_validator/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/sniffio/dependencies b/build/pkgs/sniffio/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/sniffio/dependencies +++ b/build/pkgs/sniffio/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/uri_template/dependencies b/build/pkgs/uri_template/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/uri_template/dependencies +++ b/build/pkgs/uri_template/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/urllib3/dependencies b/build/pkgs/urllib3/dependencies index 8cd44d06682..cfb7c484697 100644 --- a/build/pkgs/urllib3/dependencies +++ b/build/pkgs/urllib3/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) hatchling + | $(PYTHON_TOOLCHAIN) hatchling $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/webcolors/dependencies b/build/pkgs/webcolors/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/webcolors/dependencies +++ b/build/pkgs/webcolors/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/websocket_client/dependencies b/build/pkgs/websocket_client/dependencies index 0738c2d7777..47296a7bace 100644 --- a/build/pkgs/websocket_client/dependencies +++ b/build/pkgs/websocket_client/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. From ec5ac8d27d3f64b823efd81221416fea4798380b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 10:15:29 -0700 Subject: [PATCH 438/463] build/pkgs/idna: Change to wheel package --- build/pkgs/idna/checksums.ini | 10 +++++----- build/pkgs/idna/spkg-install.in | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) delete mode 100644 build/pkgs/idna/spkg-install.in diff --git a/build/pkgs/idna/checksums.ini b/build/pkgs/idna/checksums.ini index 47b585b69cd..d87a004eb57 100644 --- a/build/pkgs/idna/checksums.ini +++ b/build/pkgs/idna/checksums.ini @@ -1,5 +1,5 @@ -tarball=idna-VERSION.tar.gz -sha1=c01a061b5ace87f662049d205d5d15e7f8a3a533 -md5=13ea24e076212b6baae1135a116d1e0e -cksum=1497605198 -upstream_url=https://pypi.io/packages/source/i/idna/idna-VERSION.tar.gz +tarball=idna-VERSION-py3-none-any.whl +sha1=4460f34853efc88e4b14ea5e0e3fa7959b3f0c29 +md5=7ab9782a3a1180cfa1fef20a1c9c166c +cksum=3196216420 +upstream_url=https://pypi.io/packages/py3/i/idna/idna-VERSION-py3-none-any.whl diff --git a/build/pkgs/idna/spkg-install.in b/build/pkgs/idna/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/idna/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . From bac0a094ff33869f43b7b80617ab8b5595f692fe Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 16 Oct 2023 22:49:17 -0700 Subject: [PATCH 439/463] build/pkgs/notebook: Update to 7.0.5 --- build/pkgs/notebook/checksums.ini | 6 +++--- build/pkgs/notebook/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/notebook/checksums.ini b/build/pkgs/notebook/checksums.ini index 6ca7d2f1cdd..4a6bc115aa8 100644 --- a/build/pkgs/notebook/checksums.ini +++ b/build/pkgs/notebook/checksums.ini @@ -1,5 +1,5 @@ tarball=notebook-VERSION-py3-none-any.whl -sha1=7fdcf39856537f7451648665a8c7073ca49e17aa -md5=b125816110bca7fd435446425f9b1b14 -cksum=681260324 +sha1=24b1c97945d4025be291aa81823dc9148eb4631f +md5=d77b32a12ad68401fc0b2f6322abaf22 +cksum=4042063410 upstream_url=https://pypi.io/packages/py3/n/notebook/notebook-VERSION-py3-none-any.whl diff --git a/build/pkgs/notebook/package-version.txt b/build/pkgs/notebook/package-version.txt index 4489f5a6df8..2be8aeb6b14 100644 --- a/build/pkgs/notebook/package-version.txt +++ b/build/pkgs/notebook/package-version.txt @@ -1 +1 @@ -7.0.4 +7.0.5 From 6f7da9bc178ecb79ff58236bdac7700b2f38bf46 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 18:24:28 -0800 Subject: [PATCH 440/463] build/pkgs/notebook: Update to 7.0.6 --- build/pkgs/notebook/checksums.ini | 6 +++--- build/pkgs/notebook/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/notebook/checksums.ini b/build/pkgs/notebook/checksums.ini index 4a6bc115aa8..434646c23c3 100644 --- a/build/pkgs/notebook/checksums.ini +++ b/build/pkgs/notebook/checksums.ini @@ -1,5 +1,5 @@ tarball=notebook-VERSION-py3-none-any.whl -sha1=24b1c97945d4025be291aa81823dc9148eb4631f -md5=d77b32a12ad68401fc0b2f6322abaf22 -cksum=4042063410 +sha1=cd0c99c8a267ced6a451f712007665df88c60d71 +md5=e61e0d6c55bf3920c013554c6dd071b9 +cksum=2202937268 upstream_url=https://pypi.io/packages/py3/n/notebook/notebook-VERSION-py3-none-any.whl diff --git a/build/pkgs/notebook/package-version.txt b/build/pkgs/notebook/package-version.txt index 2be8aeb6b14..024b4b9b53a 100644 --- a/build/pkgs/notebook/package-version.txt +++ b/build/pkgs/notebook/package-version.txt @@ -1 +1 @@ -7.0.5 +7.0.6 From 91ead2f1efa5b4b5571b17468a8ccd6e89310d10 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 18:50:13 -0800 Subject: [PATCH 441/463] build/pkgs/asttokens: Update to 2.4.1 --- build/pkgs/asttokens/checksums.ini | 6 +++--- build/pkgs/asttokens/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/asttokens/checksums.ini b/build/pkgs/asttokens/checksums.ini index e3759368f21..44d0ca1b500 100644 --- a/build/pkgs/asttokens/checksums.ini +++ b/build/pkgs/asttokens/checksums.ini @@ -1,5 +1,5 @@ tarball=asttokens-VERSION.tar.gz -sha1=eda0bf8bf38ecd475e8358d6ce15968c8679ae86 -md5=a9ae6ae0f85398e511bcb9ec87695eed -cksum=1688343887 +sha1=d522a139240293953c99d32ca62c41542babb963 +md5=c353679585a40f43c24ca60fca33bbf6 +cksum=1117135252 upstream_url=https://pypi.io/packages/source/a/asttokens/asttokens-VERSION.tar.gz diff --git a/build/pkgs/asttokens/package-version.txt b/build/pkgs/asttokens/package-version.txt index c043eea7767..005119baaa0 100644 --- a/build/pkgs/asttokens/package-version.txt +++ b/build/pkgs/asttokens/package-version.txt @@ -1 +1 @@ -2.2.1 +2.4.1 From c6fea573545ddf738effe0b053f52eca58298960 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 18:50:27 -0800 Subject: [PATCH 442/463] build/pkgs/stack_data: Update to 0.6.3 --- build/pkgs/stack_data/checksums.ini | 6 +++--- build/pkgs/stack_data/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/stack_data/checksums.ini b/build/pkgs/stack_data/checksums.ini index b9bc5e8e3e3..f86f44c1587 100644 --- a/build/pkgs/stack_data/checksums.ini +++ b/build/pkgs/stack_data/checksums.ini @@ -1,5 +1,5 @@ tarball=stack_data-VERSION.tar.gz -sha1=71d14defdfc9741bca4aaff049668197f01cd088 -md5=bf86c3c81a0158e1e7f3979da5a0033b -cksum=3302525331 +sha1=7f7627afc47570ffb06924c1b2fbb48e21bac724 +md5=d04f7cda6589138e90691aec1edbf0d5 +cksum=4043168585 upstream_url=https://pypi.io/packages/source/s/stack_data/stack_data-VERSION.tar.gz diff --git a/build/pkgs/stack_data/package-version.txt b/build/pkgs/stack_data/package-version.txt index b6160487433..844f6a91acb 100644 --- a/build/pkgs/stack_data/package-version.txt +++ b/build/pkgs/stack_data/package-version.txt @@ -1 +1 @@ -0.6.2 +0.6.3 From 7b6c8c6b20ab10fce80b0d07e1ae18e15162c562 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 18:50:36 -0800 Subject: [PATCH 443/463] build/pkgs/wcwidth: Update to 0.2.12 --- build/pkgs/wcwidth/checksums.ini | 6 +++--- build/pkgs/wcwidth/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/wcwidth/checksums.ini b/build/pkgs/wcwidth/checksums.ini index bca0da44a2c..2745366a726 100644 --- a/build/pkgs/wcwidth/checksums.ini +++ b/build/pkgs/wcwidth/checksums.ini @@ -1,5 +1,5 @@ tarball=wcwidth-VERSION.tar.gz -sha1=ec98f6ba8ea7c5d2cec9d24d31539d39e2f90d17 -md5=976b997f2ed155b5c2e9a4d50e528d90 -cksum=2272376797 +sha1=49bdbcac346f31be8201c663082331b693264382 +md5=c37cceb9d573adcce0b3e5167ecb1df9 +cksum=68756555 upstream_url=https://pypi.io/packages/source/w/wcwidth/wcwidth-VERSION.tar.gz diff --git a/build/pkgs/wcwidth/package-version.txt b/build/pkgs/wcwidth/package-version.txt index 53a75d67355..f2722b13396 100644 --- a/build/pkgs/wcwidth/package-version.txt +++ b/build/pkgs/wcwidth/package-version.txt @@ -1 +1 @@ -0.2.6 +0.2.12 From f7980b2a6f3c6c778ae86d2c6522e33a7914da3e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 18:50:46 -0800 Subject: [PATCH 444/463] build/pkgs/jedi: Update to 0.19.1 --- build/pkgs/jedi/checksums.ini | 6 +++--- build/pkgs/jedi/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jedi/checksums.ini b/build/pkgs/jedi/checksums.ini index b91b9b187f4..291cf130faf 100644 --- a/build/pkgs/jedi/checksums.ini +++ b/build/pkgs/jedi/checksums.ini @@ -1,5 +1,5 @@ tarball=jedi-VERSION.tar.gz -sha1=8ff91cf4b06cd540108a4c69105770756f831020 -md5=47e89a2b8bedcfeb1527fac37b9ba1b3 -cksum=3224505263 +sha1=07d1e04c24cecf1b7f38f8905ce81c006f76cc20 +md5=0951191b506b660bfdb90c3dcd5b3254 +cksum=8256815 upstream_url=https://pypi.io/packages/source/j/jedi/jedi-VERSION.tar.gz diff --git a/build/pkgs/jedi/package-version.txt b/build/pkgs/jedi/package-version.txt index 503a21deb47..41915c79947 100644 --- a/build/pkgs/jedi/package-version.txt +++ b/build/pkgs/jedi/package-version.txt @@ -1 +1 @@ -0.18.2 +0.19.1 From d744ff81b605d02932a87486f571b0c60d3a7afb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 18:59:25 -0800 Subject: [PATCH 445/463] build/pkgs/ipykernel: Update to 6.27.0 --- build/pkgs/ipykernel/checksums.ini | 6 +++--- build/pkgs/ipykernel/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/ipykernel/checksums.ini b/build/pkgs/ipykernel/checksums.ini index bf5d60330a7..ea6c455e5b2 100644 --- a/build/pkgs/ipykernel/checksums.ini +++ b/build/pkgs/ipykernel/checksums.ini @@ -1,5 +1,5 @@ tarball=ipykernel-VERSION.tar.gz -sha1=5a5cf7f8c0c02d0c0cc5fe3e0fe7481a86de6552 -md5=f940975eb00de793695c386ad3a8800c -cksum=597841676 +sha1=88c5159bb5caba780383f00fceebb4cce80f96b5 +md5=9a5a3ded6795afecfe55c74f9f77307d +cksum=3205929883 upstream_url=https://files.pythonhosted.org/packages/60/30/cf3867ce0dee0a7230ec5eb85232136c3875688816ad355a7b65f4f4e8ef/ipykernel-6.6.0.tar.gz diff --git a/build/pkgs/ipykernel/package-version.txt b/build/pkgs/ipykernel/package-version.txt index 826f5ce030e..9cd1a39f656 100644 --- a/build/pkgs/ipykernel/package-version.txt +++ b/build/pkgs/ipykernel/package-version.txt @@ -1 +1 @@ -6.6.0 +6.27.0 From 2ffff581f427d0fbb9ccadc66a59d478cf0c19b8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 19:10:38 -0800 Subject: [PATCH 446/463] build/pkgs/ipykernel/patches/debugpy-make-optional.patch: Remove --- .../patches/debugpy-make-optional.patch | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 build/pkgs/ipykernel/patches/debugpy-make-optional.patch diff --git a/build/pkgs/ipykernel/patches/debugpy-make-optional.patch b/build/pkgs/ipykernel/patches/debugpy-make-optional.patch deleted file mode 100644 index 308e4dd26f9..00000000000 --- a/build/pkgs/ipykernel/patches/debugpy-make-optional.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/pyproject.toml 2021-12-01 10:23:30.000000000 -0300 -+++ b/pyproject.toml 2021-12-13 18:01:36.239921204 -0300 -@@ -3,7 +3,6 @@ - requires=[ - "setuptools", - "wheel", -- "debugpy", - "ipython>=5", - "jupyter_core>=4.2", - "jupyter_client", -diff -ruN a/setup.py b/setup.py ---- a/setup.py 2021-12-01 10:23:09.000000000 -0300 -+++ b/setup.py 2021-12-13 18:01:40.112873823 -0300 -@@ -63,7 +63,6 @@ - install_requires=[ - 'importlib-metadata<5;python_version<"3.8.0"', - 'argcomplete>=1.12.3;python_version<"3.8.0"', -- 'debugpy>=1.0.0,<2.0', - 'ipython>=7.23.1', - 'traitlets>=5.1.0,<6.0', - 'jupyter_client<8.0', From fa8d962b3f4da5dbe7a26c7fed5c5f4313bd1e63 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 19:12:44 -0800 Subject: [PATCH 447/463] build/pkgs/psutil: Resurrected --- build/pkgs/psutil/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/psutil/checksums.ini | 5 +++++ build/pkgs/psutil/dependencies | 4 ++++ build/pkgs/psutil/install-requires.txt | 1 + build/pkgs/psutil/package-version.txt | 1 + build/pkgs/psutil/spkg-install.in | 2 ++ build/pkgs/psutil/type | 1 + 7 files changed, 32 insertions(+) create mode 100644 build/pkgs/psutil/SPKG.rst create mode 100644 build/pkgs/psutil/checksums.ini create mode 100644 build/pkgs/psutil/dependencies create mode 100644 build/pkgs/psutil/install-requires.txt create mode 100644 build/pkgs/psutil/package-version.txt create mode 100644 build/pkgs/psutil/spkg-install.in create mode 100644 build/pkgs/psutil/type diff --git a/build/pkgs/psutil/SPKG.rst b/build/pkgs/psutil/SPKG.rst new file mode 100644 index 00000000000..90c0ffe4bd9 --- /dev/null +++ b/build/pkgs/psutil/SPKG.rst @@ -0,0 +1,18 @@ +psutil: Cross-platform lib for process and system monitoring in Python. +======================================================================= + +Description +----------- + +Cross-platform lib for process and system monitoring in Python. + +License +------- + +BSD-3-Clause + +Upstream Contact +---------------- + +https://pypi.org/project/psutil/ + diff --git a/build/pkgs/psutil/checksums.ini b/build/pkgs/psutil/checksums.ini new file mode 100644 index 00000000000..f9d3d687f9d --- /dev/null +++ b/build/pkgs/psutil/checksums.ini @@ -0,0 +1,5 @@ +tarball=psutil-VERSION.tar.gz +sha1=24c493ef33d4df44e76a1801e480b4185bd911c5 +md5=eec35090e7474e471a12f0dd16c981f9 +cksum=3278898496 +upstream_url=https://pypi.io/packages/source/p/psutil/psutil-VERSION.tar.gz diff --git a/build/pkgs/psutil/dependencies b/build/pkgs/psutil/dependencies new file mode 100644 index 00000000000..47296a7bace --- /dev/null +++ b/build/pkgs/psutil/dependencies @@ -0,0 +1,4 @@ + | $(PYTHON_TOOLCHAIN) $(PYTHON) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/psutil/install-requires.txt b/build/pkgs/psutil/install-requires.txt new file mode 100644 index 00000000000..a4d92cc08db --- /dev/null +++ b/build/pkgs/psutil/install-requires.txt @@ -0,0 +1 @@ +psutil diff --git a/build/pkgs/psutil/package-version.txt b/build/pkgs/psutil/package-version.txt new file mode 100644 index 00000000000..9bc6cde81a7 --- /dev/null +++ b/build/pkgs/psutil/package-version.txt @@ -0,0 +1 @@ +5.9.6 diff --git a/build/pkgs/psutil/spkg-install.in b/build/pkgs/psutil/spkg-install.in new file mode 100644 index 00000000000..37ac1a53437 --- /dev/null +++ b/build/pkgs/psutil/spkg-install.in @@ -0,0 +1,2 @@ +cd src +sdh_pip_install . diff --git a/build/pkgs/psutil/type b/build/pkgs/psutil/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/psutil/type @@ -0,0 +1 @@ +standard From 9dc6fb2ba259a18292f160a3bfa74172dbccec11 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 19:15:49 -0800 Subject: [PATCH 448/463] build/pkgs/ipykernel/dependencies: Update --- build/pkgs/ipykernel/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/ipykernel/dependencies b/build/pkgs/ipykernel/dependencies index 7e153a0cb46..000e4aafb66 100644 --- a/build/pkgs/ipykernel/dependencies +++ b/build/pkgs/ipykernel/dependencies @@ -1,4 +1,4 @@ - ipython_genutils importlib_metadata matplotlib_inline ipython jupyter_client tornado appnope traitlets executing | $(PYTHON_TOOLCHAIN) $(PYTHON) +debugpy ipython comm traitlets jupyter_client jupyter_core nest_asyncio tornado matplotlib_inline appnope pyzmq psutil packaging | $(PYTHON_TOOLCHAIN) hatchling $(PYTHON) ---------- All lines of this file are ignored except the first. From 8a408e2fd7c98c4acd62ab04e1e9509682ecf89d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 19:25:33 -0800 Subject: [PATCH 449/463] build/pkgs/jupyterlab_server: Downgrade to 2.24.0 --- build/pkgs/jupyterlab_server/checksums.ini | 6 +++--- build/pkgs/jupyterlab_server/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jupyterlab_server/checksums.ini b/build/pkgs/jupyterlab_server/checksums.ini index b12d0dfc818..3bd8926fd7b 100644 --- a/build/pkgs/jupyterlab_server/checksums.ini +++ b/build/pkgs/jupyterlab_server/checksums.ini @@ -1,5 +1,5 @@ tarball=jupyterlab_server-VERSION-py3-none-any.whl -sha1=52e71089cd4bfa5cba04b29466d9ca3ab6deb748 -md5=69efd95154a579493aa5a083e150ce01 -cksum=3821437972 +sha1=1fff8c8bc4c81b006cb83d4524dc8a6f3364e57c +md5=795bbf343ae17b75a31a50ef574d4b77 +cksum=696988100 upstream_url=https://pypi.io/packages/py3/j/jupyterlab_server/jupyterlab_server-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab_server/package-version.txt b/build/pkgs/jupyterlab_server/package-version.txt index 5c18f9195b5..ad2261920c0 100644 --- a/build/pkgs/jupyterlab_server/package-version.txt +++ b/build/pkgs/jupyterlab_server/package-version.txt @@ -1 +1 @@ -2.25.0 +2.24.0 From fc3a6d8315643d3b644e03e9350dd54c1aa9a5f7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 19:32:23 -0800 Subject: [PATCH 450/463] build/pkgs/types_python_dateutil: New, arrow dependency --- build/pkgs/arrow/dependencies | 2 +- build/pkgs/types_python_dateutil/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/types_python_dateutil/checksums.ini | 5 +++++ build/pkgs/types_python_dateutil/dependencies | 4 ++++ .../types_python_dateutil/install-requires.txt | 1 + .../types_python_dateutil/package-version.txt | 1 + build/pkgs/types_python_dateutil/type | 1 + 7 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 build/pkgs/types_python_dateutil/SPKG.rst create mode 100644 build/pkgs/types_python_dateutil/checksums.ini create mode 100644 build/pkgs/types_python_dateutil/dependencies create mode 100644 build/pkgs/types_python_dateutil/install-requires.txt create mode 100644 build/pkgs/types_python_dateutil/package-version.txt create mode 100644 build/pkgs/types_python_dateutil/type diff --git a/build/pkgs/arrow/dependencies b/build/pkgs/arrow/dependencies index c09669bc4e7..585a06aa604 100644 --- a/build/pkgs/arrow/dependencies +++ b/build/pkgs/arrow/dependencies @@ -1,4 +1,4 @@ -dateutil | $(PYTHON_TOOLCHAIN) $(PYTHON) +dateutil types_python_dateutil | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/types_python_dateutil/SPKG.rst b/build/pkgs/types_python_dateutil/SPKG.rst new file mode 100644 index 00000000000..8c8c7929594 --- /dev/null +++ b/build/pkgs/types_python_dateutil/SPKG.rst @@ -0,0 +1,18 @@ +types_python_dateutil: Typing stubs for python-dateutil +======================================================= + +Description +----------- + +Typing stubs for python-dateutil + +License +------- + +Apache-2.0 license + +Upstream Contact +---------------- + +https://pypi.org/project/types-python-dateutil/ + diff --git a/build/pkgs/types_python_dateutil/checksums.ini b/build/pkgs/types_python_dateutil/checksums.ini new file mode 100644 index 00000000000..f0dc860781b --- /dev/null +++ b/build/pkgs/types_python_dateutil/checksums.ini @@ -0,0 +1,5 @@ +tarball=types_python_dateutil-VERSION-py3-none-any.whl +sha1=c039b93ad4b5f3ea1c6aac3d08386995e8c7b19e +md5=6281a2b67e2347366238ef28e3f8a070 +cksum=1399426019 +upstream_url=https://pypi.io/packages/py3/t/types_python_dateutil/types_python_dateutil-VERSION-py3-none-any.whl diff --git a/build/pkgs/types_python_dateutil/dependencies b/build/pkgs/types_python_dateutil/dependencies new file mode 100644 index 00000000000..47296a7bace --- /dev/null +++ b/build/pkgs/types_python_dateutil/dependencies @@ -0,0 +1,4 @@ + | $(PYTHON_TOOLCHAIN) $(PYTHON) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/types_python_dateutil/install-requires.txt b/build/pkgs/types_python_dateutil/install-requires.txt new file mode 100644 index 00000000000..890ac2f7409 --- /dev/null +++ b/build/pkgs/types_python_dateutil/install-requires.txt @@ -0,0 +1 @@ +types-python-dateutil diff --git a/build/pkgs/types_python_dateutil/package-version.txt b/build/pkgs/types_python_dateutil/package-version.txt new file mode 100644 index 00000000000..b7ec6d6578b --- /dev/null +++ b/build/pkgs/types_python_dateutil/package-version.txt @@ -0,0 +1 @@ +2.8.19.14 diff --git a/build/pkgs/types_python_dateutil/type b/build/pkgs/types_python_dateutil/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/types_python_dateutil/type @@ -0,0 +1 @@ +standard From 3f96fa284f451ee12c06da6d39dd7da119dbde19 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 19:45:10 -0800 Subject: [PATCH 451/463] build/pkgs/ipykernel: Fix upstream url --- build/pkgs/ipykernel/checksums.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/ipykernel/checksums.ini b/build/pkgs/ipykernel/checksums.ini index ea6c455e5b2..3eaa681a507 100644 --- a/build/pkgs/ipykernel/checksums.ini +++ b/build/pkgs/ipykernel/checksums.ini @@ -2,4 +2,4 @@ tarball=ipykernel-VERSION.tar.gz sha1=88c5159bb5caba780383f00fceebb4cce80f96b5 md5=9a5a3ded6795afecfe55c74f9f77307d cksum=3205929883 -upstream_url=https://files.pythonhosted.org/packages/60/30/cf3867ce0dee0a7230ec5eb85232136c3875688816ad355a7b65f4f4e8ef/ipykernel-6.6.0.tar.gz +upstream_url=https://pypi.io/packages/source/i/ipykernel/ipykernel-VERSION.tar.gz From d8d85f3577150e695eb27930793a8ab4acdec163 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 19:49:48 -0800 Subject: [PATCH 452/463] build/pkgs/prompt_toolkit: Update to 3.0.41 --- build/pkgs/prompt_toolkit/checksums.ini | 6 +++--- build/pkgs/prompt_toolkit/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/prompt_toolkit/checksums.ini b/build/pkgs/prompt_toolkit/checksums.ini index 372a5d3b41c..47d7ffa3c1c 100644 --- a/build/pkgs/prompt_toolkit/checksums.ini +++ b/build/pkgs/prompt_toolkit/checksums.ini @@ -1,5 +1,5 @@ tarball=prompt_toolkit-VERSION.tar.gz -sha1=a45022d4b1b3bd827cb2e094de7ce40cc7b05337 -md5=c5e321dd56e1ed8ed95c5fccffb8f3da -cksum=2595783299 +sha1=d36c3286a16c09b9bc02c2733b9fc7a8a9c30ba1 +md5=252a5d200e41d46b65a3076d2bc0a4bd +cksum=361343842 upstream_url=https://pypi.io/packages/source/p/prompt_toolkit/prompt_toolkit-VERSION.tar.gz diff --git a/build/pkgs/prompt_toolkit/package-version.txt b/build/pkgs/prompt_toolkit/package-version.txt index 766ca985e2b..dad0d9dd27c 100644 --- a/build/pkgs/prompt_toolkit/package-version.txt +++ b/build/pkgs/prompt_toolkit/package-version.txt @@ -1 +1 @@ -3.0.38 +3.0.41 From 0790a8198de403d318f30500564b89d22e12d180 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 19:54:45 -0800 Subject: [PATCH 453/463] build/pkgs/traitlets: Update to 5.13.0 --- build/pkgs/traitlets/checksums.ini | 6 +++--- build/pkgs/traitlets/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/traitlets/checksums.ini b/build/pkgs/traitlets/checksums.ini index 8ca6285b9e3..fb0575fb4db 100644 --- a/build/pkgs/traitlets/checksums.ini +++ b/build/pkgs/traitlets/checksums.ini @@ -1,5 +1,5 @@ tarball=traitlets-VERSION.tar.gz -sha1=694fb48d89f2dcdca0d15957a23e24e340ac1567 -md5=91af43de0a2182735677875b4c8a533a -cksum=1530835442 +sha1=7dffc7781492e43a88dad84c925c0acfbc370943 +md5=58e13c21997e7cc01dda3765c9731f95 +cksum=1487040947 upstream_url=https://pypi.io/packages/source/t/traitlets/traitlets-VERSION.tar.gz diff --git a/build/pkgs/traitlets/package-version.txt b/build/pkgs/traitlets/package-version.txt index b3d91f9cfc0..26f30f79ccc 100644 --- a/build/pkgs/traitlets/package-version.txt +++ b/build/pkgs/traitlets/package-version.txt @@ -1 +1 @@ -5.9.0 +5.13.0 From c13fe374c552b1b715722b42e4251a30d6d633a8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 23 Nov 2023 21:40:12 -0800 Subject: [PATCH 454/463] Import get_ipython from IPython.core.getipython --- src/sage/doctest/control.py | 2 +- src/sage/repl/attach.py | 2 +- src/sage/repl/inputhook.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index 633afd5c2e6..364ac5dc50c 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -1607,7 +1607,7 @@ def stringify(x): if not save_dtmode: if options.debug: raise ValueError("You should not try to run doctests with a debugger from within Sage: IPython objects to embedded shells") - from IPython import get_ipython + from IPython.core.getipython import get_ipython IP = get_ipython() if IP is not None: old_color = IP.colors diff --git a/src/sage/repl/attach.py b/src/sage/repl/attach.py index 3ae3e7ad0cf..689759d50a8 100644 --- a/src/sage/repl/attach.py +++ b/src/sage/repl/attach.py @@ -70,7 +70,7 @@ import os import time -from IPython import get_ipython +from IPython.core.getipython import get_ipython from sage.repl.load import load, load_wrap import sage.repl.inputhook diff --git a/src/sage/repl/inputhook.py b/src/sage/repl/inputhook.py index 7f7894f6dcf..d49a7ee9060 100644 --- a/src/sage/repl/inputhook.py +++ b/src/sage/repl/inputhook.py @@ -20,7 +20,7 @@ import contextlib import io -from IPython import get_ipython +from IPython.core.getipython import get_ipython from IPython.terminal.pt_inputhooks import register import sage.repl.attach From 572b68def24948a693198044fffba9a009cd3106 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 24 Nov 2023 11:00:08 -0800 Subject: [PATCH 455/463] configure.ac (--disable-notebook): Add new notebook/jupyterlab dependencies --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 62d80bc79ca..a4e34fadcd6 100644 --- a/configure.ac +++ b/configure.ac @@ -507,7 +507,7 @@ AC_ARG_ENABLE([cvxopt], AC_ARG_ENABLE([notebook], AS_HELP_STRING([--disable-notebook], [disable build of the Jupyter notebook and related packages]), [ - for pkg in notebook nbconvert beautifulsoup4 sagenb_export nbformat nbclient terminado send2trash prometheus_client mistune pandocfilters bleach defusedxml jsonschema jupyter_jsmol argon2_cffi argon2_cffi_bindings webencodings tinycss2 ipympl soupsieve fastjsonschema; do + for pkg in notebook nbconvert beautifulsoup4 sagenb_export nbformat nbclient terminado send2trash prometheus_client mistune pandocfilters bleach defusedxml jsonschema jupyter_jsmol argon2_cffi argon2_cffi_bindings webencodings tinycss2 ipympl soupsieve fastjsonschema anyio arrow async_lru fqdn isoduration json5 jsonpointer jsonschema_specifications jupyter_events jupyter_lsp jupyter_server jupyter_server_terminals jupyterlab jupyterlab_mathjax2 notebook_shim overrides python_json_logger pyyaml referencing rfc3339_validator rfc3986_validator sniffio types_python_dateutil uri_template webcolors websocket_client; do AS_VAR_SET([SAGE_ENABLE_$pkg], [$enableval]) done ]) From 0e96e4bfce2cacd15879ae2855b5daeeda1c10ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Sat, 25 Nov 2023 20:21:26 -0300 Subject: [PATCH 456/463] fix doctest for nauty 2.8.8 --- src/sage/graphs/graph_generators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index 7e2a2341a46..485316db4e3 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -1130,7 +1130,7 @@ def nauty_genbg(self, options="", debug=False): sage: list(graphs.nauty_genbg("-c1 2", debug=True)) ['>E Usage: ...genbg [-c -ugs -vq -lzF] [-Z#] [-D#] [-A] [-d#|-d#:#] [-D#|-D#:#] n1 n2... sage: list(graphs.nauty_genbg("-c 1 2", debug=True)) - ['>A ...genbg n=1+2 e=2:2 d=1:1 D=2:1 c\n', Bipartite graph on 3 vertices] + ['>A ...genbg n=1+2 e=2:2 d=1:1 D=2:1 c...\n', Bipartite graph on 3 vertices] We must have n1=1..24, n2=0..32 and n1+n2=1..32 (:trac:`34179`):: From 744e4b7cefb668941bef2a37c100d24bc14ae444 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 27 Nov 2023 08:59:26 -0800 Subject: [PATCH 457/463] build/pkgs/exceptiongroup: New (ipython dependency for python < 3.11) --- build/pkgs/exceptiongroup/SPKG.rst | 16 ++++++++++++++++ build/pkgs/exceptiongroup/checksums.ini | 5 +++++ build/pkgs/exceptiongroup/dependencies | 4 ++++ build/pkgs/exceptiongroup/install-requires.txt | 1 + build/pkgs/exceptiongroup/package-version.txt | 1 + build/pkgs/exceptiongroup/type | 1 + build/pkgs/ipython/dependencies | 2 +- configure.ac | 2 +- 8 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 build/pkgs/exceptiongroup/SPKG.rst create mode 100644 build/pkgs/exceptiongroup/checksums.ini create mode 100644 build/pkgs/exceptiongroup/dependencies create mode 100644 build/pkgs/exceptiongroup/install-requires.txt create mode 100644 build/pkgs/exceptiongroup/package-version.txt create mode 100644 build/pkgs/exceptiongroup/type diff --git a/build/pkgs/exceptiongroup/SPKG.rst b/build/pkgs/exceptiongroup/SPKG.rst new file mode 100644 index 00000000000..4fe6e94f57e --- /dev/null +++ b/build/pkgs/exceptiongroup/SPKG.rst @@ -0,0 +1,16 @@ +exceptiongroup: Backport of PEP 654 (exception groups) +====================================================== + +Description +----------- + +Backport of PEP 654 (exception groups) + +License +------- + +Upstream Contact +---------------- + +https://pypi.org/project/exceptiongroup/ + diff --git a/build/pkgs/exceptiongroup/checksums.ini b/build/pkgs/exceptiongroup/checksums.ini new file mode 100644 index 00000000000..1ca0c50d46d --- /dev/null +++ b/build/pkgs/exceptiongroup/checksums.ini @@ -0,0 +1,5 @@ +tarball=exceptiongroup-VERSION-py3-none-any.whl +sha1=e69c438e6d15111c4f7cc18224b31a42a58663da +md5=d252c64173c449dc34654e7be8211744 +cksum=527795480 +upstream_url=https://pypi.io/packages/py3/e/exceptiongroup/exceptiongroup-VERSION-py3-none-any.whl diff --git a/build/pkgs/exceptiongroup/dependencies b/build/pkgs/exceptiongroup/dependencies new file mode 100644 index 00000000000..47296a7bace --- /dev/null +++ b/build/pkgs/exceptiongroup/dependencies @@ -0,0 +1,4 @@ + | $(PYTHON_TOOLCHAIN) $(PYTHON) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/exceptiongroup/install-requires.txt b/build/pkgs/exceptiongroup/install-requires.txt new file mode 100644 index 00000000000..341183a94c9 --- /dev/null +++ b/build/pkgs/exceptiongroup/install-requires.txt @@ -0,0 +1 @@ +exceptiongroup diff --git a/build/pkgs/exceptiongroup/package-version.txt b/build/pkgs/exceptiongroup/package-version.txt new file mode 100644 index 00000000000..26aaba0e866 --- /dev/null +++ b/build/pkgs/exceptiongroup/package-version.txt @@ -0,0 +1 @@ +1.2.0 diff --git a/build/pkgs/exceptiongroup/type b/build/pkgs/exceptiongroup/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/exceptiongroup/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/ipython/dependencies b/build/pkgs/ipython/dependencies index cc719ef4ea5..b00056b1a63 100644 --- a/build/pkgs/ipython/dependencies +++ b/build/pkgs/ipython/dependencies @@ -1,4 +1,4 @@ -tornado pyzmq pickleshare traitlets decorator wcwidth prompt_toolkit pygments pexpect appnope backcall jedi stack_data | $(PYTHON_TOOLCHAIN) $(PYTHON) +tornado pyzmq pickleshare traitlets decorator wcwidth prompt_toolkit pygments pexpect appnope backcall jedi stack_data exceptiongroup | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/configure.ac b/configure.ac index a4e34fadcd6..d1c2aceb413 100644 --- a/configure.ac +++ b/configure.ac @@ -544,7 +544,7 @@ AC_ARG_ENABLE([sagelib], dnl Handle combinations of --disable-foo flags that may enable us to dnl prune even more dependencies. AS_IF([test "$SAGE_ENABLE_notebook" = no -a "$SAGE_ENABLE_sagelib" = no], [ - for pkg in jupyter_client ipykernel ipython zeromq pyzmq; do + for pkg in jupyter_client ipykernel ipython zeromq pyzmq exceptiongroup; do AS_VAR_SET([SAGE_ENABLE_$pkg], [$enableval]) done ]) From f9aeca57d76136a88b74a0c3297250070c0227a3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 27 Nov 2023 12:59:47 -0800 Subject: [PATCH 458/463] src/sage/geometry/lattice_polytope.py: Mark large example as # not tested --- src/sage/geometry/lattice_polytope.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index cdf2c374e9f..1cd9f578113 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -3138,7 +3138,7 @@ def normal_form(self, algorithm="palp_native", permutation=False): M( 12, -1, -9, -6, 6), M( 12, -1, -6, -3, 3) in 5-d lattice M - sage: P.normal_form(algorithm="palp_modified") # long time (22s) # needs sage.groups + sage: P.normal_form(algorithm="palp_modified") # not tested (22s; MemoryError on 32 bit), needs sage.groups M( 6, 0, 0, 0, 0), M( -6, 0, 0, 0, 0), M( 0, 1, 0, 0, 0), From 633e5fc097c6d230b0a0b41d4a5b9ec3f149e268 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 30 Nov 2023 06:11:46 +0900 Subject: [PATCH 459/463] Remove a wrong comment --- src/sage/schemes/curves/affine_curve.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py index e33092ca0d3..e1032861b2f 100644 --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -2304,7 +2304,7 @@ def _nonsingular_model(self): F = F.extension(f, names[i]) coords[i] = F.gen() - proper_extension = F.base_field() is not F # and n is 1 + proper_extension = F.base_field() is not F if proper_extension: N, from_N, to_N = F.simple_model() From 8953d8bd603cb7696e1795240cae43fc33283265 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 30 Nov 2023 08:35:04 +0900 Subject: [PATCH 460/463] Fix grammatic errors --- src/sage/schemes/curves/projective_curve.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index cac2990fdd9..7c82026b3c1 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -2431,7 +2431,7 @@ def _function_field(self): @lazy_attribute def _map_to_function_field(self): """ - Return the map to function field of the curve. + Return the map to the function field of the curve. TESTS:: @@ -2469,7 +2469,7 @@ def _coordinate_functions(self): @lazy_attribute def _map_from_function_field(self): """ - Return the map to the function field of the curve. + Return the map from the function field of the curve. TESTS:: From b2813506039143e6f0abe859ab67a343abf72c2e Mon Sep 17 00:00:00 2001 From: Release Manager Date: Thu, 30 Nov 2023 22:51:29 +0100 Subject: [PATCH 461/463] Updated SageMath version to 10.2.rc5 --- 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_bliss/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_coxeter3/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_mcqd/install-requires.txt | 2 +- build/pkgs/sagemath_meataxe/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- build/pkgs/sagemath_sirocco/install-requires.txt | 2 +- build/pkgs/sagemath_tdlib/install-requires.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 38 files changed, 45 insertions(+), 45 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index d065a454dc6..0a73d8da64e 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.2.rc4 +version: 10.2.rc5 doi: 10.5281/zenodo.593563 -date-released: 2023-11-17 +date-released: 2023-11-30 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 529cf2e0639..9fb07a54404 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.2.rc4, Release Date: 2023-11-17 +SageMath version 10.2.rc5, Release Date: 2023-11-30 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 95aa8183102..98b8d9e6ad5 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=522d5fb44038e051abeed5fc0bd8f26dc0c33dd4 -md5=7c89c8b88491557e0f6d6a351809e886 -cksum=1283778476 +sha1=615fc6a4d0eeb9b3dd4bb915c151a631d1979eff +md5=d59860c6efb7274cc16c5cbf2dfc0e3c +cksum=3537541662 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 6b1538549bc..adc514205e8 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -3ae48f93bb78b004a818376fdcf959d661cb838d +6a5b6c0f934acefeadcdfcfb937092a124c0a09a diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 768110a40b2..69ceb96ebeb 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.2rc4 +sage-conf ~= 10.2rc5 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index 20b4014d9c9..7eb9bc66d31 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.2rc4 +sage-docbuild ~= 10.2rc5 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index e8f9803223b..97e120387e6 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.2rc4 +sage-setup ~= 10.2rc5 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index 210e209b2b1..2dba653e685 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.2rc4 +sage-sws2rst ~= 10.2rc5 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 041db2e12b2..88b37e5b39b 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 -sagemath-standard ~= 10.2rc4 +sagemath-standard ~= 10.2rc5 diff --git a/build/pkgs/sagemath_bliss/install-requires.txt b/build/pkgs/sagemath_bliss/install-requires.txt index 489dabd64e2..802cb5862b5 100644 --- a/build/pkgs/sagemath_bliss/install-requires.txt +++ b/build/pkgs/sagemath_bliss/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.2rc4 +sagemath-bliss ~= 10.2rc5 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index c6b1335bb36..2b855c948b8 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.2rc4 +sagemath-categories ~= 10.2rc5 diff --git a/build/pkgs/sagemath_coxeter3/install-requires.txt b/build/pkgs/sagemath_coxeter3/install-requires.txt index 147b0859f3c..53877fef069 100644 --- a/build/pkgs/sagemath_coxeter3/install-requires.txt +++ b/build/pkgs/sagemath_coxeter3/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.2rc4 +sagemath-coxeter3 ~= 10.2rc5 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index 7a744b52d45..baa147acba3 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.2rc4 +sagemath-environment ~= 10.2rc5 diff --git a/build/pkgs/sagemath_mcqd/install-requires.txt b/build/pkgs/sagemath_mcqd/install-requires.txt index 6aa36800227..d788fa95032 100644 --- a/build/pkgs/sagemath_mcqd/install-requires.txt +++ b/build/pkgs/sagemath_mcqd/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.2rc4 +sagemath-mcqd ~= 10.2rc5 diff --git a/build/pkgs/sagemath_meataxe/install-requires.txt b/build/pkgs/sagemath_meataxe/install-requires.txt index f94e1aac639..785e39748d8 100644 --- a/build/pkgs/sagemath_meataxe/install-requires.txt +++ b/build/pkgs/sagemath_meataxe/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.2rc4 +sagemath-meataxe ~= 10.2rc5 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index 772df655f0d..fc3dc412bcd 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.2rc4 +sagemath-objects ~= 10.2rc5 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 850ce7e19d3..c8430b9db44 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.2rc4 +sagemath-repl ~= 10.2rc5 diff --git a/build/pkgs/sagemath_sirocco/install-requires.txt b/build/pkgs/sagemath_sirocco/install-requires.txt index f3cc76b26fa..ccb288563b1 100644 --- a/build/pkgs/sagemath_sirocco/install-requires.txt +++ b/build/pkgs/sagemath_sirocco/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.2rc4 +sagemath-sirocco ~= 10.2rc5 diff --git a/build/pkgs/sagemath_tdlib/install-requires.txt b/build/pkgs/sagemath_tdlib/install-requires.txt index bffa6c8223c..cb431838e65 100644 --- a/build/pkgs/sagemath_tdlib/install-requires.txt +++ b/build/pkgs/sagemath_tdlib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.2rc4 +sagemath-tdlib ~= 10.2rc5 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/src/VERSION.txt b/src/VERSION.txt index 6bdcf0406e9..ea61754a6ef 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.2.rc4 +10.2.rc5 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index c2a6f2749ae..5adb8b5983d 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.2.rc4' -SAGE_RELEASE_DATE='2023-11-17' -SAGE_VERSION_BANNER='SageMath version 10.2.rc4, Release Date: 2023-11-17' +SAGE_VERSION='10.2.rc5' +SAGE_RELEASE_DATE='2023-11-30' +SAGE_VERSION_BANNER='SageMath version 10.2.rc5, Release Date: 2023-11-30' diff --git a/src/sage/version.py b/src/sage/version.py index 106eb6564e7..bdb6c002ac5 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.2.rc4' -date = '2023-11-17' -banner = 'SageMath version 10.2.rc4, Release Date: 2023-11-17' +version = '10.2.rc5' +date = '2023-11-30' +banner = 'SageMath version 10.2.rc5, Release Date: 2023-11-30' From 2a9a4267f93588cf33119cbacc032ed9acc433e5 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sun, 3 Dec 2023 11:07:02 +0100 Subject: [PATCH 462/463] Updated SageMath version to 10.2 --- 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_bliss/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_coxeter3/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_mcqd/install-requires.txt | 2 +- build/pkgs/sagemath_meataxe/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- build/pkgs/sagemath_sirocco/install-requires.txt | 2 +- build/pkgs/sagemath_tdlib/install-requires.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 38 files changed, 45 insertions(+), 45 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 0a73d8da64e..6998dacb03a 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.2.rc5 +version: 10.2 doi: 10.5281/zenodo.593563 -date-released: 2023-11-30 +date-released: 2023-12-03 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 9fb07a54404..274290e658a 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.2.rc5, Release Date: 2023-11-30 +SageMath version 10.2, Release Date: 2023-12-03 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 98b8d9e6ad5..6a9ab0ca8aa 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=615fc6a4d0eeb9b3dd4bb915c151a631d1979eff -md5=d59860c6efb7274cc16c5cbf2dfc0e3c -cksum=3537541662 +sha1=c769dfca6414cc453b22e64863aee153c4041e6f +md5=b098e551614a15569894e0b99b4909ff +cksum=2514200459 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index adc514205e8..af9bec1ae59 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -6a5b6c0f934acefeadcdfcfb937092a124c0a09a +b2813506039143e6f0abe859ab67a343abf72c2e diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 69ceb96ebeb..8eb5ae88a85 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.2rc5 +sage-conf ~= 10.2 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index 7eb9bc66d31..ff18a74200a 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.2rc5 +sage-docbuild ~= 10.2 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index 97e120387e6..eb6834048e1 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.2rc5 +sage-setup ~= 10.2 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index 2dba653e685..5cc98378a84 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.2rc5 +sage-sws2rst ~= 10.2 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 88b37e5b39b..8609e43c636 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 -sagemath-standard ~= 10.2rc5 +sagemath-standard ~= 10.2 diff --git a/build/pkgs/sagemath_bliss/install-requires.txt b/build/pkgs/sagemath_bliss/install-requires.txt index 802cb5862b5..cd1c51681dc 100644 --- a/build/pkgs/sagemath_bliss/install-requires.txt +++ b/build/pkgs/sagemath_bliss/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.2rc5 +sagemath-bliss ~= 10.2 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index 2b855c948b8..017b3d374b0 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.2rc5 +sagemath-categories ~= 10.2 diff --git a/build/pkgs/sagemath_coxeter3/install-requires.txt b/build/pkgs/sagemath_coxeter3/install-requires.txt index 53877fef069..40569f233fc 100644 --- a/build/pkgs/sagemath_coxeter3/install-requires.txt +++ b/build/pkgs/sagemath_coxeter3/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.2rc5 +sagemath-coxeter3 ~= 10.2 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index baa147acba3..a1f32f6bc98 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.2rc5 +sagemath-environment ~= 10.2 diff --git a/build/pkgs/sagemath_mcqd/install-requires.txt b/build/pkgs/sagemath_mcqd/install-requires.txt index d788fa95032..7f4164c93a1 100644 --- a/build/pkgs/sagemath_mcqd/install-requires.txt +++ b/build/pkgs/sagemath_mcqd/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.2rc5 +sagemath-mcqd ~= 10.2 diff --git a/build/pkgs/sagemath_meataxe/install-requires.txt b/build/pkgs/sagemath_meataxe/install-requires.txt index 785e39748d8..9122afd82be 100644 --- a/build/pkgs/sagemath_meataxe/install-requires.txt +++ b/build/pkgs/sagemath_meataxe/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.2rc5 +sagemath-meataxe ~= 10.2 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index fc3dc412bcd..a322fd5489f 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.2rc5 +sagemath-objects ~= 10.2 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index c8430b9db44..9c272edab74 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.2rc5 +sagemath-repl ~= 10.2 diff --git a/build/pkgs/sagemath_sirocco/install-requires.txt b/build/pkgs/sagemath_sirocco/install-requires.txt index ccb288563b1..e7ab8fa942b 100644 --- a/build/pkgs/sagemath_sirocco/install-requires.txt +++ b/build/pkgs/sagemath_sirocco/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.2rc5 +sagemath-sirocco ~= 10.2 diff --git a/build/pkgs/sagemath_tdlib/install-requires.txt b/build/pkgs/sagemath_tdlib/install-requires.txt index cb431838e65..f717989d8c4 100644 --- a/build/pkgs/sagemath_tdlib/install-requires.txt +++ b/build/pkgs/sagemath_tdlib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.2rc5 +sagemath-tdlib ~= 10.2 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/src/VERSION.txt b/src/VERSION.txt index ea61754a6ef..e2498ea52d3 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.2.rc5 +10.2 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 5adb8b5983d..17ce1d95cd5 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.2.rc5' -SAGE_RELEASE_DATE='2023-11-30' -SAGE_VERSION_BANNER='SageMath version 10.2.rc5, Release Date: 2023-11-30' +SAGE_VERSION='10.2' +SAGE_RELEASE_DATE='2023-12-03' +SAGE_VERSION_BANNER='SageMath version 10.2, Release Date: 2023-12-03' diff --git a/src/sage/version.py b/src/sage/version.py index bdb6c002ac5..911aeb53f24 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.2.rc5' -date = '2023-11-30' -banner = 'SageMath version 10.2.rc5, Release Date: 2023-11-30' +version = '10.2' +date = '2023-12-03' +banner = 'SageMath version 10.2, Release Date: 2023-12-03' From 272582be9e0ddbf253a5dfbcd772f53c51fcf700 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Wed, 6 Dec 2023 00:47:58 +0100 Subject: [PATCH 463/463] Updated SageMath version to 10.3.beta0 --- .upstream.d/20-github.com-sagemath-sage-releases | 1 + 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_bliss/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_coxeter3/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_mcqd/install-requires.txt | 2 +- build/pkgs/sagemath_meataxe/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- build/pkgs/sagemath_sirocco/install-requires.txt | 2 +- build/pkgs/sagemath_tdlib/install-requires.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 39 files changed, 46 insertions(+), 45 deletions(-) diff --git a/.upstream.d/20-github.com-sagemath-sage-releases b/.upstream.d/20-github.com-sagemath-sage-releases index 0176fddf829..1ab20a34a06 100644 --- a/.upstream.d/20-github.com-sagemath-sage-releases +++ b/.upstream.d/20-github.com-sagemath-sage-releases @@ -1,4 +1,5 @@ # Upstream packages as uploaded as GitHub release assets. # This file is automatically updated by the sage-update-version script. +https://github.com/sagemath/sage/releases/download/10.3/ https://github.com/sagemath/sage/releases/download/10.2/ https://github.com/sagemath/sage/releases/download/10.1/ diff --git a/CITATION.cff b/CITATION.cff index 6998dacb03a..33dda263384 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.2 +version: 10.3.beta0 doi: 10.5281/zenodo.593563 -date-released: 2023-12-03 +date-released: 2023-12-05 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 274290e658a..75f3e554fbb 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.2, Release Date: 2023-12-03 +SageMath version 10.3.beta0, Release Date: 2023-12-05 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 9d9a932630e..6fab326e890 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=09ed008d1bdba4837fdb078f8f50a67cac9a9d7f -md5=eeed6bf17634e46f99f44c1f8dcd010a -cksum=1753047461 +sha1=cba1a107f45084e1884ca8a873504c70eec9c16c +md5=b61e77023581c8994c73313e867a6c26 +cksum=615928275 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 61f7a9c7ecd..d124c289596 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -c3f06e4734ef325db812d73dcdb2bf846b590104 +9b1e18ffc022a8ed0e7451ccf190a009ceb2d81c diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 8eb5ae88a85..38ec7e2cd5d 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.2 +sage-conf ~= 10.3b0 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index ff18a74200a..3769c7054e8 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.2 +sage-docbuild ~= 10.3b0 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index eb6834048e1..0913b873634 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.2 +sage-setup ~= 10.3b0 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index 5cc98378a84..8e3570a99d3 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.2 +sage-sws2rst ~= 10.3b0 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 8609e43c636..307a02db545 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 -sagemath-standard ~= 10.2 +sagemath-standard ~= 10.3b0 diff --git a/build/pkgs/sagemath_bliss/install-requires.txt b/build/pkgs/sagemath_bliss/install-requires.txt index cd1c51681dc..b340ea27044 100644 --- a/build/pkgs/sagemath_bliss/install-requires.txt +++ b/build/pkgs/sagemath_bliss/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.2 +sagemath-bliss ~= 10.3b0 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index 017b3d374b0..9019a793f10 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.2 +sagemath-categories ~= 10.3b0 diff --git a/build/pkgs/sagemath_coxeter3/install-requires.txt b/build/pkgs/sagemath_coxeter3/install-requires.txt index 40569f233fc..e57fd056654 100644 --- a/build/pkgs/sagemath_coxeter3/install-requires.txt +++ b/build/pkgs/sagemath_coxeter3/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.2 +sagemath-coxeter3 ~= 10.3b0 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index a1f32f6bc98..9202789d78a 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.2 +sagemath-environment ~= 10.3b0 diff --git a/build/pkgs/sagemath_mcqd/install-requires.txt b/build/pkgs/sagemath_mcqd/install-requires.txt index 7f4164c93a1..93f176e6fc5 100644 --- a/build/pkgs/sagemath_mcqd/install-requires.txt +++ b/build/pkgs/sagemath_mcqd/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.2 +sagemath-mcqd ~= 10.3b0 diff --git a/build/pkgs/sagemath_meataxe/install-requires.txt b/build/pkgs/sagemath_meataxe/install-requires.txt index 9122afd82be..ee1e280aad1 100644 --- a/build/pkgs/sagemath_meataxe/install-requires.txt +++ b/build/pkgs/sagemath_meataxe/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.2 +sagemath-meataxe ~= 10.3b0 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index a322fd5489f..07baf32ec81 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.2 +sagemath-objects ~= 10.3b0 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 9c272edab74..79c7e5a7ed0 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.2 +sagemath-repl ~= 10.3b0 diff --git a/build/pkgs/sagemath_sirocco/install-requires.txt b/build/pkgs/sagemath_sirocco/install-requires.txt index e7ab8fa942b..44ebb97d788 100644 --- a/build/pkgs/sagemath_sirocco/install-requires.txt +++ b/build/pkgs/sagemath_sirocco/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.2 +sagemath-sirocco ~= 10.3b0 diff --git a/build/pkgs/sagemath_tdlib/install-requires.txt b/build/pkgs/sagemath_tdlib/install-requires.txt index f717989d8c4..ea24439a16a 100644 --- a/build/pkgs/sagemath_tdlib/install-requires.txt +++ b/build/pkgs/sagemath_tdlib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.2 +sagemath-tdlib ~= 10.3b0 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/src/VERSION.txt b/src/VERSION.txt index e2498ea52d3..d1741c9f234 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.2 +10.3.beta0 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 17ce1d95cd5..9f4098364dc 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.2' -SAGE_RELEASE_DATE='2023-12-03' -SAGE_VERSION_BANNER='SageMath version 10.2, Release Date: 2023-12-03' +SAGE_VERSION='10.3.beta0' +SAGE_RELEASE_DATE='2023-12-05' +SAGE_VERSION_BANNER='SageMath version 10.3.beta0, Release Date: 2023-12-05' diff --git a/src/sage/version.py b/src/sage/version.py index 911aeb53f24..f7c0467ee4e 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.2' -date = '2023-12-03' -banner = 'SageMath version 10.2, Release Date: 2023-12-03' +version = '10.3.beta0' +date = '2023-12-05' +banner = 'SageMath version 10.3.beta0, Release Date: 2023-12-05'