From 92e59d148f146af0d8d4193c92f98dade9c32d72 Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Thu, 6 Jun 2024 14:09:11 -0500 Subject: [PATCH 001/210] fix green function in projective_ds --- .../arithmetic_dynamics/projective_ds.py | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 3b92c79eee7..a3e33d9ce50 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -2042,7 +2042,7 @@ def green_function(self, P, v, **kwds): sage: f.green_function(P([2, 1]), K.ideal(7), N=7) 0.48647753726382832627633818586 sage: f.green_function(P([w, 1]), K.ideal(17), error_bound=0.001) - -0.70813041039490996737374178059 + -0.70821687320448199545278619351 :: @@ -2073,7 +2073,7 @@ def green_function(self, P, v, **kwds): K = BR elif is_prime(v): K = Qp(v, prec) - elif v == 0: + elif v == 0 and BR == QQ: K = R v = BR.places(prec=prec)[0] else: @@ -2095,6 +2095,7 @@ def green_function(self, P, v, **kwds): # compute upper bound if isinstance(v, RingHomomorphism_im_gens): #archimedean vindex = BR.places(prec=prec).index(v) + emb = BR.places(prec=prec)[vindex] U = GBR.local_height_arch(vindex, prec=prec) + R(binomial(dim + d, d)).log() else: #non-archimedean U = GBR.local_height(v, prec=prec) @@ -2103,31 +2104,32 @@ def green_function(self, P, v, **kwds): CR = GBR.codomain().ambient_space().coordinate_ring() #.lift() only works over fields I = CR.ideal(GBR.defining_polynomials()) maxh = 0 - Res = 1 for k in range(dim + 1): CoeffPolys = (CR.gen(k) ** D).lift(I) h = 1 - for poly in CoeffPolys: - if poly != 0: - for c in poly.coefficients(): - Res = lcm(Res, c.denominator()) for poly in CoeffPolys: if poly != 0: if isinstance(v, RingHomomorphism_im_gens): #archimedean if BR == QQ: - h = max([(Res*c).local_height_arch(prec=prec) for c in poly.coefficients()]) + h = max([R(K(c).abs()) for c in poly.coefficients()]) else: - h = max([(Res*c).local_height_arch(vindex, prec=prec) for c in poly.coefficients()]) + h = max([R(emb(c).abs()) for c in poly.coefficients()]) else: #non-archimedean - h = max([c.local_height(v, prec=prec) for c in poly.coefficients()]) + if BR == QQ: + h = max([R(v)**(-R(c.valuation(v))) for c in poly.coefficients()]) + else: + h = max([R(c.abs_non_arch(v, prec=prec)) for c in poly.coefficients()]) if h > maxh: - maxh = h + maxh=h if maxh == 0: maxh = 1 #avoid division by 0 if isinstance(v, RingHomomorphism_im_gens): #archimedean - L = R(Res / ((dim + 1) * binomial(dim + D - d, D - d) * maxh)).log().abs() + L = R(1 / ((dim + 1) * binomial(dim + D - d, D - d) * maxh)).log().abs() else: #non-archimedean - L = R(Res / maxh).log().abs() + if BR == QQ: + L = ((-self.resultant().valuation(v))*R(v).log()).abs() + else: + L = (self.resultant().abs_non_arch(v, prec=prec)).log().abs() C = max([U, L]) if C != 0: N = R(C / (err*(d-1))).log(d).abs().ceil() @@ -2253,7 +2255,7 @@ def canonical_height(self, P, **kwds): sage: f = DynamicalSystem_projective([1000*x^2 - 29*y^2, 1000*y^2]) sage: Q = P(-1/4, 1) sage: f.canonical_height(Q, error_bound=0.01) # needs sage.libs.pari - 3.7996079979254623065837411853 + 3.7979215342343045582800170705 :: From 398c7bad37a71e4bffd587b0416c37b5e5b91021 Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Thu, 6 Jun 2024 14:27:08 -0500 Subject: [PATCH 002/210] fix lint error --- src/sage/dynamics/arithmetic_dynamics/projective_ds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index a3e33d9ce50..c5560545110 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -2120,7 +2120,7 @@ def green_function(self, P, v, **kwds): else: h = max([R(c.abs_non_arch(v, prec=prec)) for c in poly.coefficients()]) if h > maxh: - maxh=h + maxh = h if maxh == 0: maxh = 1 #avoid division by 0 if isinstance(v, RingHomomorphism_im_gens): #archimedean From 627b9f15c516ed2aafffb635a4fab7d78d8b12d6 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sun, 13 Oct 2024 20:06:09 +0900 Subject: [PATCH 003/210] Introduce negated optional tag --- src/doc/en/developer/coding_basics.rst | 25 ++++++++++++++++++--- src/sage/databases/sloane.py | 22 +++++++++++++++---- src/sage/doctest/parsing.py | 18 ++++++++-------- src/sage/graphs/graph_latex.py | 3 ++- src/sage/groups/perm_gps/cubegroup.py | 30 +++++++++++++------------- 5 files changed, 66 insertions(+), 32 deletions(-) diff --git a/src/doc/en/developer/coding_basics.rst b/src/doc/en/developer/coding_basics.rst index 5e15c4b2455..bd89514cae0 100644 --- a/src/doc/en/developer/coding_basics.rst +++ b/src/doc/en/developer/coding_basics.rst @@ -1258,13 +1258,32 @@ framework. Here is a comprehensive list: - **optional/needs:** A line tagged with ``optional - FEATURE`` or ``needs FEATURE`` is not tested unless the ``--optional=KEYWORD`` flag - is passed to ``sage -t`` (see - :ref:`section-optional-doctest-flag`). The main applications are: + is passed to ``sage -t`` (see :ref:`section-optional-doctest-flag`). + + If ``FEATURE`` starts with an exclamation point ``!``, then the condition is + negated, that is, the doctest runs only if the feature is not available. + + The main applications are: - **optional packages:** When a line requires an optional package to be - installed (e.g. the ``sloane_database`` package):: + installed (e.g. the ``rubiks`` package):: + + sage: C = RubiksCube("R*L") + sage: C.solve() # optional - rubiks (a hybrid algorithm is used) + 'L R' + sage: C.solve() # optional - !rubiks (GAP is used) + 'L*R' + + - **optional database:** When a line requires a database to be present:: sage: SloaneEncyclopedia[60843] # optional - sloane_database + [1, 6, 21, 107, 47176870] + + sage: SloaneEncyclopedia[60843] # optional - !sloane_database + Traceback (most recent call last): + ... + OSError: The Sloane Encyclopedia database must be installed. Use e.g. + 'SloaneEncyclopedia.install()' to download and install it. - **internet:** For lines that require an internet connection:: diff --git a/src/sage/databases/sloane.py b/src/sage/databases/sloane.py index 78fc268b486..aac252d84a8 100644 --- a/src/sage/databases/sloane.py +++ b/src/sage/databases/sloane.py @@ -12,7 +12,7 @@ :: sage: SloaneEncyclopedia[60843] # optional - sloane_database - [1, 6, 21, 107] + [1, 6, 21, 107, 47176870] To get the name of a sequence, type @@ -149,6 +149,17 @@ def __len__(self): self.load() return len(self.__data__) + def is_installed(self): + """ + Check if a local copy of the encyclopedia is installed. + + EXAMPLES:: + + sage: SloaneEncyclopedia.is_installed() # optional - sloane_database + True + """ + return os.path.exists(self.__file__) and os.path.exists(self.__file_names__) + def find(self, seq, maxresults=30): """ Return a list of all sequences which have seq as a subsequence, up @@ -274,7 +285,7 @@ def load(self): for L in file_seq: if len(L) == 0: continue - m = entry.search(L) + m = entry.search(L.decode('utf-8')) if m: seqnum = int(m.group('num')) msg = m.group('body').strip() @@ -287,10 +298,13 @@ def load(self): for L in file_names: if not L: continue - m = entry.search(L) + m = entry.search(L.decode('utf-8')) if m: seqnum = int(m.group('num')) - self.__data__[seqnum][3] = m.group('body').strip() + if seqnum in self.__data__: + self.__data__[seqnum][3] = m.group('body').strip() + else: + self.__data__[seqnum] = [seqnum, None, 'unknown', m.group('body').strip()] file_names.close() self.__loaded_names__ = True except KeyError: diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index d9b054ae2dd..97d01a6a120 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -58,7 +58,7 @@ special_optional_regex = ( "py2|long time|not implemented|not tested|optional|needs|known bug" ) -tag_with_explanation_regex = r"((?:\w|[.])*)\s*(?:\((?P.*?)\))?" +tag_with_explanation_regex = r"((?:!?\w|[.])*)\s*(?:\((?P.*?)\))?" optional_regex = re.compile( rf"[^ a-z]\s*(?P{special_optional_regex})(?:\s|[:-])*(?P(?:(?:{tag_with_explanation_regex})\s*)*)", re.IGNORECASE, @@ -1124,14 +1124,14 @@ def check_and_clear_tag_counts(): continue if self.optional_tags is not True: - extra = { - tag - for tag in optional_tags - if ( - tag not in self.optional_tags - and tag not in available_software - ) - } + extra = set() + for tag in optional_tags: + if tag not in self.optional_tags: + if tag.startswith('!'): + if tag[1:] in available_software: + extra.add(tag) + elif tag not in available_software: + extra.add(tag) if extra and any(tag in ["bug"] for tag in extra): # Bug only occurs on a specific platform? bug_platform = optional_tags_with_values.get("bug") diff --git a/src/sage/graphs/graph_latex.py b/src/sage/graphs/graph_latex.py index f0fb9329002..12fe5c6ed99 100644 --- a/src/sage/graphs/graph_latex.py +++ b/src/sage/graphs/graph_latex.py @@ -207,6 +207,7 @@ % \end{tikzpicture} + EXAMPLES: This example illustrates switching between the built-in styles when using the @@ -1566,7 +1567,7 @@ def tkz_picture(self): For a complicated vertex, a TeX box is used. :: sage: B = crystals.Tableaux(['B', 2], shape=[1]) - sage: latex(B) + sage: latex(B) # optional - !dot2tex \begin{tikzpicture} ... \newsavebox{\vertex} diff --git a/src/sage/groups/perm_gps/cubegroup.py b/src/sage/groups/perm_gps/cubegroup.py index 8eadbac39f1..fffdbe84753 100644 --- a/src/sage/groups/perm_gps/cubegroup.py +++ b/src/sage/groups/perm_gps/cubegroup.py @@ -1420,7 +1420,7 @@ def __richcmp__(self, other, op): return NotImplemented return richcmp(self._state, other._state, op) - def solve(self, algorithm='hybrid', timeout=15): + def solve(self, algorithm='default', timeout=15): r""" Solve the Rubik's cube. @@ -1428,17 +1428,14 @@ def solve(self, algorithm='hybrid', timeout=15): - ``algorithm`` -- must be one of the following: - - ``hybrid`` -- try ``kociemba`` for timeout seconds, then ``dietz`` - - ``kociemba`` -- use Dik T. Winter's program - (reasonable speed, few moves) - - ``dietz`` -- use Eric Dietz's cubex program - (fast but lots of moves) - - ``optimal`` -- use Michael Reid's optimal program - (may take a long time) + - ``hybrid`` -- (default) try ``kociemba`` for timeout seconds, then ``dietz`` + - ``kociemba`` -- use Dik T. Winter's program (reasonable speed, few moves) + - ``dietz`` -- use Eric Dietz's cubex program (fast but lots of moves) + - ``optimal`` -- use Michael Reid's optimal program (may take a long time) - ``gap`` -- use GAP word solution (can be slow) - Any choice other than ``gap`` requires the optional package - ``rubiks``. Otherwise, the ``gap`` algorithm is used. + Any choice other than ``gap`` requires the optional package ``rubiks``. + If the package is not installed, the ``gap`` algorithm is used by default. EXAMPLES:: @@ -1450,7 +1447,10 @@ def solve(self, algorithm='hybrid', timeout=15): solutions:: sage: s = C.solve('dietz'); s # optional - rubiks - "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'" + "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: C2 = RubiksCube(s) # optional - rubiks sage: C == C2 # optional - rubiks True @@ -1458,11 +1458,11 @@ def solve(self, algorithm='hybrid', timeout=15): from sage.features.rubiks import Rubiks if Rubiks().is_present(): import sage.interfaces.rubik # here to avoid circular referencing + if algorithm == 'default': + algorithm = "hybrid" else: - algorithm = 'gap' - - if algorithm == "default": - algorithm = "hybrid" + if algorithm == 'default': + algorithm = 'gap' if algorithm == "hybrid": try: From d7db870dedecfa4d106338ed9e578a41de6d9876 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sun, 13 Oct 2024 23:22:11 +0900 Subject: [PATCH 004/210] Edit optional needs tags explanation --- src/doc/en/developer/coding_basics.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/doc/en/developer/coding_basics.rst b/src/doc/en/developer/coding_basics.rst index bd89514cae0..9b56de46ad0 100644 --- a/src/doc/en/developer/coding_basics.rst +++ b/src/doc/en/developer/coding_basics.rst @@ -6,7 +6,6 @@ General Conventions =================== - There are many ways to contribute to Sage, including sharing scripts and Jupyter notebooks that implement new functionality using Sage, improving to the Sage library, or to working on the many underlying @@ -1256,13 +1255,15 @@ framework. Here is a comprehensive list: Neither of this applies to files or directories which are explicitly given as command line arguments: those are always tested. -- **optional/needs:** A line tagged with ``optional - FEATURE`` - or ``needs FEATURE`` is not tested unless the ``--optional=KEYWORD`` flag - is passed to ``sage -t`` (see :ref:`section-optional-doctest-flag`). - - If ``FEATURE`` starts with an exclamation point ``!``, then the condition is +- **optional** or **needs:** A line tagged with ``optional - FEATURE`` or + ``needs FEATURE`` is tested if the feature is available in Sage. If + ``FEATURE`` starts with an exclamation point ``!``, then the condition is negated, that is, the doctest runs only if the feature is not available. + If the feature is included in the ``--optional=KEYWORD`` flag passed to + ``sage -t`` (see :ref:`section-optional-doctest-flag`), then the line is + tested regardless of the feature availability. + The main applications are: - **optional packages:** When a line requires an optional package to be @@ -1274,7 +1275,7 @@ framework. Here is a comprehensive list: sage: C.solve() # optional - !rubiks (GAP is used) 'L*R' - - **optional database:** When a line requires a database to be present:: + - **features:** When a line requires a feature to be present:: sage: SloaneEncyclopedia[60843] # optional - sloane_database [1, 6, 21, 107, 47176870] @@ -1285,7 +1286,7 @@ framework. Here is a comprehensive list: OSError: The Sloane Encyclopedia database must be installed. Use e.g. 'SloaneEncyclopedia.install()' to download and install it. - - **internet:** For lines that require an internet connection:: + For lines that require an internet connection:: sage: oeis(60843) # optional - internet A060843: Busy Beaver problem: a(n) = maximal number of steps that an From 71197264e74f9537d19fa5c1ae0e8fc1bb2f47f9 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 16 Oct 2024 06:54:48 +0900 Subject: [PATCH 005/210] Add features --- src/sage/features/dot2tex.py | 42 +++++++++++++++++++++ src/sage/features/sloane_database.py | 56 ++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 src/sage/features/dot2tex.py create mode 100644 src/sage/features/sloane_database.py diff --git a/src/sage/features/dot2tex.py b/src/sage/features/dot2tex.py new file mode 100644 index 00000000000..e9f97b6e704 --- /dev/null +++ b/src/sage/features/dot2tex.py @@ -0,0 +1,42 @@ +# sage_setup: distribution = sagemath-environment +r""" +Check for ``dot2tex`` +""" + +# ***************************************************************************** +# Copyright (C) 2024 Kwankyu Lee +# +# 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 . import PythonModule + + +class dot2tex(PythonModule): + r""" + A :class:`sage.features.Feature` describing the presence of :ref:`dot2tex `. + + dot2tex is provided by an optional package in the Sage distribution. + + EXAMPLES:: + + sage: from sage.features.dot2tex import dot2tex + sage: dot2tex().is_present() # optional - dot2tex + FeatureTestResult('dot2tex', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.dot2tex import dot2tex + sage: isinstance(dot2tex(), dot2tex) + True + """ + PythonModule.__init__(self, 'dot2tex', spkg='dot2tex') + + +def all_features(): + return [dot2tex()] diff --git a/src/sage/features/sloane_database.py b/src/sage/features/sloane_database.py new file mode 100644 index 00000000000..9abfbea8891 --- /dev/null +++ b/src/sage/features/sloane_database.py @@ -0,0 +1,56 @@ +# sage_setup: distribution = sagemath-environment +r""" +Feature for testing the presence of Sloane Online Encyclopedia of Integer Sequences +""" + +# **************************************************************************** +# Copyright (C) 2024 Kwankyu Lee +# +# 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 . import Feature + + +class SloaneOEIS(Feature): + r""" + A :class:`~sage.features.Feature` which describes the presence of + the Sloane Online Encyclopedia of Integer Sequences. + + EXAMPLES:: + + sage: from sage.features.sloane_database import SloaneOEIS + sage: bool(SloaneOEIS().is_present()) # optional - sloane_database + True + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sloane_database import SloaneOEIS + sage: isinstance(SloaneOEIS(), SloaneOEIS) + True + """ + Feature.__init__(self, name='sloane_database', + description='Sloane Online Encyclopedia of Integer Sequences') + + def _is_present(self): + r""" + Return whether the database is installed. + + EXAMPLES:: + + sage: from sage.features.sloane_database import SloaneOEIS + sage: bool(SloaneOEIS().is_present()) # optional - !sloane_database + False + """ + from sage.databases.sloane import SloaneEncyclopedia + return SloaneEncyclopedia.is_installed() + + +def all_features(): + return [SloaneOEIS()] From 0812d9d5ea96a1d956450c9b6abaf3b18547dbff Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 16 Oct 2024 15:02:25 +0900 Subject: [PATCH 006/210] Fix modularization regression --- src/sage/features/sloane_database.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/features/sloane_database.py b/src/sage/features/sloane_database.py index 9abfbea8891..84aad5ce67a 100644 --- a/src/sage/features/sloane_database.py +++ b/src/sage/features/sloane_database.py @@ -40,7 +40,7 @@ def __init__(self): def _is_present(self): r""" - Return whether the database is installed. + Return whether the database is available. EXAMPLES:: @@ -48,7 +48,10 @@ def _is_present(self): sage: bool(SloaneOEIS().is_present()) # optional - !sloane_database False """ - from sage.databases.sloane import SloaneEncyclopedia + try: + from sage.databases.sloane import SloaneEncyclopedia + except ImportError: + return False return SloaneEncyclopedia.is_installed() From 4ca8c0dae5b1ac957985eddfdf5f928f5df9f839 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 17 Oct 2024 00:22:51 +0900 Subject: [PATCH 007/210] Delete a spurious empty line --- src/sage/graphs/graph_latex.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/graphs/graph_latex.py b/src/sage/graphs/graph_latex.py index 12fe5c6ed99..f50758496c4 100644 --- a/src/sage/graphs/graph_latex.py +++ b/src/sage/graphs/graph_latex.py @@ -207,7 +207,6 @@ % \end{tikzpicture} - EXAMPLES: This example illustrates switching between the built-in styles when using the From b1e08e62e8dafd8a0026c31f386de38f9fd8d4a4 Mon Sep 17 00:00:00 2001 From: maple3142 Date: Thu, 24 Oct 2024 01:26:12 +0800 Subject: [PATCH 008/210] Improve Matrix_mod2_dense solve_right performance Use M4RI builtin `mzd_solve_left` function to solve equation. --- src/sage/libs/m4ri.pxd | 3 ++ src/sage/matrix/matrix_mod2_dense.pyx | 69 +++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/sage/libs/m4ri.pxd b/src/sage/libs/m4ri.pxd index 7fbdd35b856..a762a68323b 100644 --- a/src/sage/libs/m4ri.pxd +++ b/src/sage/libs/m4ri.pxd @@ -179,6 +179,9 @@ cdef extern from "m4ri/m4ri.h": # reduced row echelon form using PLUQ factorization cdef mzd_t *mzd_kernel_left_pluq(mzd_t *A, int cutoff) + # system solving + cdef int mzd_solve_left(mzd_t *A, mzd_t *B, int cutoff, int inconsistency_check) + ######################## # Bit operations ######################## diff --git a/src/sage/matrix/matrix_mod2_dense.pyx b/src/sage/matrix/matrix_mod2_dense.pyx index 07c54d6add9..0dd000d6ba9 100644 --- a/src/sage/matrix/matrix_mod2_dense.pyx +++ b/src/sage/matrix/matrix_mod2_dense.pyx @@ -1918,6 +1918,75 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse mzd_free(A) self.cache('rank', r) return r + + def _solve_right_general(self, B, check=True): + """ + Solve the matrix equation AX = B for X using the M4RI library. + + INPUT: + + - ``B`` -- a matrix + - ``check`` -- boolean (default: ``True``); whether to check if the + matrix equation has a solution + + EXAMPLES:: + + sage: A = matrix(GF(2), [[1, 0], [0, 1], [1, 1]]) + sage: A.solve_right(vector([1, 1, 0])) + (1, 1) + sage: A.solve_right(vector([1, 1, 1])) + Traceback (most recent call last): + ... + ValueError: matrix equation has no solutions + + TESTS:: + + sage: n = 128 + sage: m = 128 + sage: A = random_matrix(GF(2), n, m) + sage: B = A * random_vector(GF(2), m) + sage: A * A.solve_right(B) == B + True + sage: m = 64 + sage: A = random_matrix(GF(2), n, m) + sage: B = A * random_vector(GF(2), m) + sage: A * A.solve_right(B) == B + True + sage: m = 256 + sage: A = random_matrix(GF(2), n, m) + sage: B = A * random_vector(GF(2), m) + sage: A * A.solve_right(B) == B + True + """ + cdef Matrix_mod2_dense X # the solution + + cdef mzd_t *B_entries = (B)._entries + cdef rci_t rows = self._entries.nrows + if self._entries.nrows < self._entries.ncols: + rows = self._entries.ncols # mzd_solve_left requires ncols <= nrows + + cdef mzd_t *lhs = mzd_init(rows, self._entries.ncols) + mzd_copy(lhs, self._entries) + cdef mzd_t *rhs = mzd_init(rows, B_entries.ncols) + mzd_copy(rhs, B_entries) + + sig_on() + # although it is called mzd_solve_left, it does the same thing as solve_right + ret = mzd_solve_left(lhs, rhs, 0, check) + sig_off() + mzd_free(lhs) + + if ret == 0: + # solution is placed in rhs + X = self.new_matrix(nrows=self._entries.ncols, ncols=B_entries.ncols) + rhs.nrows = self._entries.ncols + mzd_copy(X._entries, rhs) + mzd_free(rhs) + return X + else: + mzd_free(rhs) + raise ValueError("matrix equation has no solutions") + def _right_kernel_matrix(self, **kwds): r""" From d1d21f8244f90e85373fb0866b9481ea220ec013 Mon Sep 17 00:00:00 2001 From: maple3142 Date: Thu, 24 Oct 2024 01:47:54 +0800 Subject: [PATCH 009/210] Fix code style --- src/sage/matrix/matrix_mod2_dense.pyx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix_mod2_dense.pyx b/src/sage/matrix/matrix_mod2_dense.pyx index 0dd000d6ba9..deeb45cf50b 100644 --- a/src/sage/matrix/matrix_mod2_dense.pyx +++ b/src/sage/matrix/matrix_mod2_dense.pyx @@ -1918,7 +1918,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse mzd_free(A) self.cache('rank', r) return r - + def _solve_right_general(self, B, check=True): """ Solve the matrix equation AX = B for X using the M4RI library. @@ -1938,7 +1938,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse Traceback (most recent call last): ... ValueError: matrix equation has no solutions - + TESTS:: sage: n = 128 @@ -1987,7 +1987,6 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse mzd_free(rhs) raise ValueError("matrix equation has no solutions") - def _right_kernel_matrix(self, **kwds): r""" Return a pair that includes a matrix of basis vectors From 5a68faea4ad47449a1eea896253d97d671cdcd86 Mon Sep 17 00:00:00 2001 From: maple3142 Date: Thu, 24 Oct 2024 13:26:11 +0800 Subject: [PATCH 010/210] Fix Matrix_mod2_dense solve_right signal handling --- src/sage/matrix/matrix_mod2_dense.pyx | 30 ++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/sage/matrix/matrix_mod2_dense.pyx b/src/sage/matrix/matrix_mod2_dense.pyx index deeb45cf50b..4cce0464dd4 100644 --- a/src/sage/matrix/matrix_mod2_dense.pyx +++ b/src/sage/matrix/matrix_mod2_dense.pyx @@ -1970,22 +1970,24 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse cdef mzd_t *rhs = mzd_init(rows, B_entries.ncols) mzd_copy(rhs, B_entries) - sig_on() - # although it is called mzd_solve_left, it does the same thing as solve_right - ret = mzd_solve_left(lhs, rhs, 0, check) - sig_off() - mzd_free(lhs) + cdef int ret + try: + sig_on() + # although it is called mzd_solve_left, it does the same thing as solve_right + ret = mzd_solve_left(lhs, rhs, 0, check) + sig_off() - if ret == 0: - # solution is placed in rhs - X = self.new_matrix(nrows=self._entries.ncols, ncols=B_entries.ncols) - rhs.nrows = self._entries.ncols - mzd_copy(X._entries, rhs) - mzd_free(rhs) - return X - else: + if ret == 0: + # solution is placed in rhs + X = self.new_matrix(nrows=self._entries.ncols, ncols=B_entries.ncols) + rhs.nrows = self._entries.ncols + mzd_copy(X._entries, rhs) + return X + else: + raise ValueError("matrix equation has no solutions") + finally: + mzd_free(lhs) mzd_free(rhs) - raise ValueError("matrix equation has no solutions") def _right_kernel_matrix(self, **kwds): r""" From 8f598195dfa260401193a8068a2450fd09f283c6 Mon Sep 17 00:00:00 2001 From: maple3142 Date: Thu, 24 Oct 2024 15:34:01 +0800 Subject: [PATCH 011/210] Fix Matrix_mod2_dense solve_right empty matrix --- src/sage/matrix/matrix_mod2_dense.pyx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix_mod2_dense.pyx b/src/sage/matrix/matrix_mod2_dense.pyx index 4cce0464dd4..d2f7e49c58a 100644 --- a/src/sage/matrix/matrix_mod2_dense.pyx +++ b/src/sage/matrix/matrix_mod2_dense.pyx @@ -1958,9 +1958,13 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse sage: A * A.solve_right(B) == B True """ - cdef Matrix_mod2_dense X # the solution - cdef mzd_t *B_entries = (B)._entries + + cdef Matrix_mod2_dense X # the solution + X = self.new_matrix(nrows=self._entries.ncols, ncols=B_entries.ncols) + if self._entries.nrows == 0 or self._entries.ncols == 0: + # special case: empty matrix + return X cdef rci_t rows = self._entries.nrows if self._entries.nrows < self._entries.ncols: rows = self._entries.ncols # mzd_solve_left requires ncols <= nrows @@ -1979,7 +1983,6 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse if ret == 0: # solution is placed in rhs - X = self.new_matrix(nrows=self._entries.ncols, ncols=B_entries.ncols) rhs.nrows = self._entries.ncols mzd_copy(X._entries, rhs) return X From a2486ee4b04286de737b759ec47382cc8a560840 Mon Sep 17 00:00:00 2001 From: maple3142 Date: Thu, 24 Oct 2024 15:41:12 +0800 Subject: [PATCH 012/210] Fix Matrix_mod2_dense solve_right empty matrix --- src/sage/matrix/matrix_mod2_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_mod2_dense.pyx b/src/sage/matrix/matrix_mod2_dense.pyx index d2f7e49c58a..a92abdd94db 100644 --- a/src/sage/matrix/matrix_mod2_dense.pyx +++ b/src/sage/matrix/matrix_mod2_dense.pyx @@ -1962,7 +1962,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse cdef Matrix_mod2_dense X # the solution X = self.new_matrix(nrows=self._entries.ncols, ncols=B_entries.ncols) - if self._entries.nrows == 0 or self._entries.ncols == 0: + if self._entries.ncols == 0 or B_entries.ncols == 0: # special case: empty matrix return X cdef rci_t rows = self._entries.nrows From 88ca4ca9f9bd00c81c373ea5b360da8338c266cb Mon Sep 17 00:00:00 2001 From: maple3142 Date: Thu, 24 Oct 2024 17:31:22 +0800 Subject: [PATCH 013/210] Fix Matrix_mod2_dense solve_right empty matrix --- src/sage/matrix/matrix_mod2_dense.pyx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/matrix/matrix_mod2_dense.pyx b/src/sage/matrix/matrix_mod2_dense.pyx index a92abdd94db..0bdbd4d11d2 100644 --- a/src/sage/matrix/matrix_mod2_dense.pyx +++ b/src/sage/matrix/matrix_mod2_dense.pyx @@ -1964,6 +1964,8 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse X = self.new_matrix(nrows=self._entries.ncols, ncols=B_entries.ncols) if self._entries.ncols == 0 or B_entries.ncols == 0: # special case: empty matrix + if B != 0: + raise ValueError("matrix equation has no solutions") return X cdef rci_t rows = self._entries.nrows if self._entries.nrows < self._entries.ncols: From b2178bfe76d51ccaad43bcb4ba47bfe712fc6157 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 29 Oct 2024 13:33:34 +0100 Subject: [PATCH 014/210] provide the tilde species of a species --- src/sage/rings/species.py | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 7bc55e6ccb5..9b4194300fe 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1539,6 +1539,55 @@ def is_atomic(self): """ return self.is_molecular() and len(self.support()[0]) == 1 + def tilde(self): + r""" + Return the tilde species of ``self``. + + The tilde species `\tilde F` of a species `F` has as + structures the set of pairs `(s, a)`, consisting of an + `F`-structure `s` and an automorphism `a` of `s`. + + We use https://mathoverflow.net/a/480852 to compute it. + + EXAMPLES:: + + sage: from sage.rings.species import AtomicSpecies, MolecularSpecies, PolynomialSpecies + sage: M = MolecularSpecies("X") + sage: P = PolynomialSpecies(QQ, "X") + sage: sortkey = lambda x: (len(x[1]), sum(x[1].coefficients()), str(x[0])) + sage: n=4; table(sorted([(m, P.monomial(m).tilde()) for m in M.subset(n)], key=sortkey)) + X^4 X^4 + X^2*E_2 2*X^2*E_2 + {((1,2)(3,4),)} 2*{((1,2)(3,4),)} + X*C_3 3*X*C_3 + C_4 4*C_4 + E_2^2 4*E_2^2 + Pb_4 4*Pb_4 + X*E_3 X*E_3 + X^2*E_2 + X*C_3 + Eo_4 Eo_4 + 2*X*C_3 + Pb_4 + P_4 2*P_4 + E_2^2 + Pb_4 + C_4 + E_4 E_4 + E_2^2 + X*C_3 + P_4 + C_4 + + sage: P. = PolynomialSpecies(QQ) + sage: E2 = PolynomialSpecies(QQ, "X")(SymmetricGroup(2)) + sage: E2(X*Y).tilde() + 2*E_2(XY) + """ + P = self.parent() + M = P._indices + P_one = P.one() + one = ZZ.one() + result = P.zero() + for m, c in self: + result_m = P_one + for a, e in m: + G, pi = a.permutation_group() + result_a = P.sum(P(G.centralizer(g), pi) + for g in G.conjugacy_classes_representatives()) + result_m *= result_a ** e + result += c * result_m + return result + def hadamard_product(self, other): r""" Compute the hadamard product of ``self`` and ``other``. From 7d74a60413f286a1bc1182208c0a5df9c43e6c2c Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Tue, 29 Oct 2024 17:43:55 +0100 Subject: [PATCH 015/210] Add new functions to libbraiding interface --- src/sage/libs/braiding.pyx | 55 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/sage/libs/braiding.pyx b/src/sage/libs/braiding.pyx index fb856c918c9..000738be432 100644 --- a/src/sage/libs/braiding.pyx +++ b/src/sage/libs/braiding.pyx @@ -41,6 +41,11 @@ cdef extern from "braiding.h" namespace "Braiding": int thurstontype(int n, list[int] word) int Rigidity_ext(int n, list[int] word) list[list[list[list[int]]]] SlidingCircuits(int n, list[int] word) + list[list[list[int]]] SendToSSS(int n, list[int] word) + list[list[list[int]]] SendToUSS(int n, list[int] word) + list[list[list[int]]] SendToSC(int n, list[int] word) + list[list[list[int]]] Trajectory(int n, list[int] word) + list[list[list[list[int]]]] CyclicSlidings(int n, list[int] word) def conjugatingbraid(braid1, braid2): @@ -383,3 +388,53 @@ def sliding_circuits(braid): cdef list[list[list[list[int]]]] rop = SlidingCircuits(nstrands, l) sig_off() return rop + +def send_to_sss(braid): + r""" + Returns an element of the braid's SSS and the conjugating braid. + """ + nstrands = braid.parent().strands() + l = braid.Tietze() + sig_on() + cdef list[list[list[int]]] rop = SendToSSS(nstrands, l) + sig_off() + return rop + +def send_to_uss(braid): + r""" + Returns an element of the braid's USS and the conjugating braid. + """ + nstrands = braid.parent().strands() + l = braid.Tietze() + sig_on() + cdef list[list[list[int]]] rop = SendToUSS(nstrands, l) + sig_off() + return rop + +def send_to_sc(braid): + r""" + Returns an element of the braid's SC and the conjugating braid. + """ + nstrands = braid.parent().strands() + l = braid.Tietze() + sig_on() + cdef list[list[list[int]]] rop = SendToSC(nstrands, l) + sig_off() + return rop + +def trajectory(braid): + nstrands = braid.parent().strands() + l = braid.Tietze() + sig_on() + cdef list[list[list[int]]] rop = Trajectory(nstrands, l) + sig_off() + return rop + +def cyclic_slidings(braid): + nstrands = braid.parent().strands() + l = braid.Tietze() + sig_on() + cdef list[list[list[list[int]]]] rop = CyclicSlidings(nstrands, l) + sig_off() + return rop + From e41243058444a0c05c11a2b638fbb2f38e9b934b Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Tue, 29 Oct 2024 19:43:41 +0100 Subject: [PATCH 016/210] upgrade to libbraiding v1.3 and add new functions --- build/pkgs/libbraiding/checksums.ini | 4 +- build/pkgs/libbraiding/package-version.txt | 2 +- src/sage/groups/braid.py | 92 +++++++++++++++++- src/sage/libs/braiding.pyx | 105 ++++++++++++++++++++- 4 files changed, 196 insertions(+), 7 deletions(-) diff --git a/build/pkgs/libbraiding/checksums.ini b/build/pkgs/libbraiding/checksums.ini index 5a956e027bf..d48af2f9e18 100644 --- a/build/pkgs/libbraiding/checksums.ini +++ b/build/pkgs/libbraiding/checksums.ini @@ -1,4 +1,4 @@ tarball=libbraiding-VERSION-actually-VERSION.tar.gz -sha1=b7e13778784fe1e36e7c0cbd7a4c234a090cd1b2 -sha256=73087d1145ace719eafeda1db1c28b5fe1c981b7e784dc59f2b1d6fc4ff75f80 +sha1=bb56d66b438e2deee7e5af4e08bba2b3b0411210 +sha256=428e8b22a42e5539e511619ac61242e088642054bacae1daef174667ecf19000 upstream_url=https://github.com/miguelmarco/libbraiding/releases/download/VERSION/libbraiding-VERSION.tar.gz diff --git a/build/pkgs/libbraiding/package-version.txt b/build/pkgs/libbraiding/package-version.txt index 5625e59da88..7e32cd56983 100644 --- a/build/pkgs/libbraiding/package-version.txt +++ b/build/pkgs/libbraiding/package-version.txt @@ -1 +1 @@ -1.2 +1.3 diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index 8945175cf7a..e6464841ad4 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -96,7 +96,8 @@ lazy_import('sage.libs.braiding', ['leftnormalform', 'rightnormalform', 'centralizer', 'supersummitset', 'greatestcommondivisor', 'leastcommonmultiple', 'conjugatingbraid', 'ultrasummitset', - 'thurston_type', 'rigidity', 'sliding_circuits'], + 'thurston_type', 'rigidity', 'sliding_circuits', 'send_to_sss', + 'send_to_uss', 'send_to_sc', 'trajectory', 'cyclic_slidings' ], feature=sage__libs__braiding()) lazy_import('sage.knots.knot', 'Knot') @@ -2239,6 +2240,95 @@ def colored_jones_polynomial(self, N, variab=None, try_inverse=True): self._cj_with_q[N] = cj.subs({q: 1/q}) if use_inverse else cj return self.colored_jones_polynomial(N, variab, try_inverse) + def send_to_sss(self): + r""" + Return an element of the braid's super summit set, an the conjugating + braid. + + EXAMPLES:: + + sage: B = BraidGroup(4) + sage: b = B([1, 2, 1, 2, 3, -1, 2, 1, 3]) + sage: b.send_to_sss() + (s0*s2*s0*s1*s2*s1*s0, s0^-1*s1^-1*s0^-1*s2^-1*s1^-1*s0^-1*s1*s0*s2*s1*s0) + + """ + to_sss = send_to_sss(self) + B = self.parent() + return tuple(B._element_from_libbraiding(b) for b in to_sss) + + def send_to_uss(self): + r""" + Return an element of the braid's ultra summit set, an the conjugating + braid. + + EXAMPLES:: + + sage: B = BraidGroup(4) + sage: b = B([1, 2, 1, 2, 3, -1, 2, -1, 3]) + sage: b.send_to_uss() + (s0*s1*s0*s2*s1, s0^-1*s1^-1*s0^-1*s2^-1*s1^-1*s0^-1*s1*s2*s1^2*s0) + + """ + to_uss = send_to_uss(self) + B = self.parent() + return tuple(B._element_from_libbraiding(b) for b in to_uss) + + def send_to_sc(self): + r""" + Return an element of the braid's sliding circuits, an the conjugating + braid. + + EXAMPLES:: + + sage: B = BraidGroup(4) + sage: b = B([1, 2, 1, 2, 3, -1, 2, -1, 3]) + sage: b.send_to_sc() + (s0*s1*s0*s2*s1, s0^2*s1*s2) + + """ + to_sc = send_to_sc(self) + B = self.parent() + return tuple(B._element_from_libbraiding(b) for b in to_sc) + + def trajectory(self): + r""" + Return the braid's trajectory. + + EXAMPLES:: + + sage: B = BraidGroup(4) + sage: b = B([1, 2, 1, 2, 3, -1, 2, -1, 3]) + sage: b.trajectory() + [s0^-1*s1^-1*s0^-1*s2^-1*s1^-1*s2*s0*s1*s2*s1*s0^2*s1*s2^2, + s0*s1*s2^3, + s0*s1*s2*s1^2, + s0*s1*s0*s2*s1] + + """ + traj = trajectory(self) + B = self.parent() + return [B._element_from_libbraiding(b) for b in traj] + + def cyclic_slidings(self): + r""" + Return the the braid's cyclic slidings. + + OUTPUT: The braid's cyclic slidings. Each cyclic sliding is a list of braids. + + EXAMPLES:: + + sage: B = BraidGroup(4) + sage: b = B([1, 2, 1, 2, 3, -1, 2, 1]) + sage: b.cyclic_slidings() + [[s0*s2*s1*s0*s1*s2, s0*s1*s2*s1*s0^2, s1*s0*s2^2*s1*s0], + [s0*s1*s2*s1^2*s0, s0*s1*s2*s1*s0*s2, s1*s0*s2*s0*s1*s2]] + + """ + cs = cyclic_slidings(self) + B = self.parent() + return [[B._element_from_libbraiding(b) for b in t] for t in cs] + class RightQuantumWord: """ diff --git a/src/sage/libs/braiding.pyx b/src/sage/libs/braiding.pyx index 000738be432..8958abfd8f2 100644 --- a/src/sage/libs/braiding.pyx +++ b/src/sage/libs/braiding.pyx @@ -391,7 +391,24 @@ def sliding_circuits(braid): def send_to_sss(braid): r""" - Returns an element of the braid's SSS and the conjugating braid. + Return an element of the braid's super summit set and the conjugating braid. + + INPUT: + + - ``braid`` -- a braid + + OUTPUT: + + A list with two braids, the first one is an element of ``braid`` super summit + set, the second one is the corresponding conjugating braid. + + EXAMPLES:: + + sage: B = BraidGroup(4) + sage: d = B([1, 2, 1, 2, 3, -1, 2,- 3]) + sage: send_to_sss(d) + [[[0], [1, 2, 1, 3]], [[-1], [1, 2, 3, 2]]] + """ nstrands = braid.parent().strands() l = braid.Tietze() @@ -402,7 +419,24 @@ def send_to_sss(braid): def send_to_uss(braid): r""" - Returns an element of the braid's USS and the conjugating braid. + Return an element of the braid's ultra summit set and the conjugating braid. + + INPUT: + + - ``braid`` -- a braid + + OUTPUT: + + A list with two braids, the first one is an element of ``braid`` ultra summit + set, the second one is the corresponding conjugating braid. + + EXAMPLES:: + + sage: B = BraidGroup(4) + sage: d = B([1, 2, 1, 2, 3, -1, 2,- 1]) + sage: send_to_uss(d) + [[[0], [1, 2, 3, 2]], [[0], [1]]] + """ nstrands = braid.parent().strands() l = braid.Tietze() @@ -413,7 +447,25 @@ def send_to_uss(braid): def send_to_sc(braid): r""" - Returns an element of the braid's SC and the conjugating braid. + Return an element of the braid's sliding circuits and the conjugating braid. + + INPUT: + + - ``braid`` -- a braid + + OUTPUT: + + A list with two braids, the first one is an element of ``braid`` sliding + circuits, the second one is the corresponding conjugating braid. + + EXAMPLES:: + + sage: B = BraidGroup(4) + sage: d = B([1, 2, 1, 2, 3, -1, 2, 2]) + sage: send_to_sc(d) + [[[0], [1, 2, 3, 2], [2, 1]], [[0], [1]]] + + """ nstrands = braid.parent().strands() l = braid.Tietze() @@ -423,6 +475,29 @@ def send_to_sc(braid): return rop def trajectory(braid): + r""" + Return the braid's trajectory. + + INPUT: + + - ``braid`` -- a braid + + OUTPUT: + + A list of braids, formed by the ``braid```trajectory. + + EXAMPLES:: + + sage: B = BraidGroup(4) + sage: d = B([1, 2, 1, 2, 3, -1, 2, 2]) + sage: trajectory(d) + [[[0], [1, 3], [1, 2, 3, 2]], + [[0], [1, 2, 3, 2, 1], [3]], + [[0], [1, 2, 3, 2], [2, 1]], + [[0], [2, 1, 3], [1, 2, 3]]] + + + """ nstrands = braid.parent().strands() l = braid.Tietze() sig_on() @@ -431,6 +506,30 @@ def trajectory(braid): return rop def cyclic_slidings(braid): + r""" + Return the cyclic slidings of the braid. + + INPUT: + + - ``braid```-- a braid + + OUTPUT: + + A list of lists of braids, given by the input's cyclic slidings. + + EXAMPLES:: + + sage: B = BraidGroup(4) + sage: d = B([1, 2, 1, 2, 3, -1, 2, 2]) + sage: cyclic_slidings(d) + [[[[0], [1, 2, 3, 2], [2, 1]], + [[0], [1, 2, 3, 2, 1], [3]], + [[0], [2, 1, 3], [1, 2, 3]]], + [[[0], [1, 3, 2, 1], [2, 3]], + [[0], [1, 2, 3, 2, 1], [1]], + [[0], [2, 1, 3], [3, 2, 1]]]] + + """ nstrands = braid.parent().strands() l = braid.Tietze() sig_on() From 72c12acdea4c79620e9be09a95c8be976b3f1e3a Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Tue, 29 Oct 2024 20:33:51 +0100 Subject: [PATCH 017/210] Fix linting --- src/sage/libs/braiding.pyx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sage/libs/braiding.pyx b/src/sage/libs/braiding.pyx index 8958abfd8f2..8feca132984 100644 --- a/src/sage/libs/braiding.pyx +++ b/src/sage/libs/braiding.pyx @@ -389,6 +389,7 @@ def sliding_circuits(braid): sig_off() return rop + def send_to_sss(braid): r""" Return an element of the braid's super summit set and the conjugating braid. @@ -417,6 +418,7 @@ def send_to_sss(braid): sig_off() return rop + def send_to_uss(braid): r""" Return an element of the braid's ultra summit set and the conjugating braid. @@ -445,6 +447,7 @@ def send_to_uss(braid): sig_off() return rop + def send_to_sc(braid): r""" Return an element of the braid's sliding circuits and the conjugating braid. @@ -474,6 +477,7 @@ def send_to_sc(braid): sig_off() return rop + def trajectory(braid): r""" Return the braid's trajectory. @@ -505,6 +509,7 @@ def trajectory(braid): sig_off() return rop + def cyclic_slidings(braid): r""" Return the cyclic slidings of the braid. @@ -536,4 +541,3 @@ def cyclic_slidings(braid): cdef list[list[list[list[int]]]] rop = CyclicSlidings(nstrands, l) sig_off() return rop - From 66b81a0025b95593437742e80a37eefd77aaed04 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Wed, 30 Oct 2024 09:56:23 +0100 Subject: [PATCH 018/210] Address reviewer's comments --- src/sage/groups/braid.py | 25 ++++++++++--------------- src/sage/libs/braiding.pyx | 2 +- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index e6464841ad4..5a4b45c6c45 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -2240,9 +2240,9 @@ def colored_jones_polynomial(self, N, variab=None, try_inverse=True): self._cj_with_q[N] = cj.subs({q: 1/q}) if use_inverse else cj return self.colored_jones_polynomial(N, variab, try_inverse) - def send_to_sss(self): + def super_summit_set_element(self): r""" - Return an element of the braid's super summit set, an the conjugating + Return an element of the braid's super summit set and the conjugating braid. EXAMPLES:: @@ -2251,15 +2251,14 @@ def send_to_sss(self): sage: b = B([1, 2, 1, 2, 3, -1, 2, 1, 3]) sage: b.send_to_sss() (s0*s2*s0*s1*s2*s1*s0, s0^-1*s1^-1*s0^-1*s2^-1*s1^-1*s0^-1*s1*s0*s2*s1*s0) - """ to_sss = send_to_sss(self) B = self.parent() - return tuple(B._element_from_libbraiding(b) for b in to_sss) + return tuple([B._element_from_libbraiding(b) for b in to_sss]) - def send_to_uss(self): + def ultra_summit_set_element(self): r""" - Return an element of the braid's ultra summit set, an the conjugating + Return an element of the braid's ultra summit set and the conjugating braid. EXAMPLES:: @@ -2268,15 +2267,14 @@ def send_to_uss(self): sage: b = B([1, 2, 1, 2, 3, -1, 2, -1, 3]) sage: b.send_to_uss() (s0*s1*s0*s2*s1, s0^-1*s1^-1*s0^-1*s2^-1*s1^-1*s0^-1*s1*s2*s1^2*s0) - """ to_uss = send_to_uss(self) B = self.parent() - return tuple(B._element_from_libbraiding(b) for b in to_uss) + return tuple([B._element_from_libbraiding(b) for b in to_uss]) - def send_to_sc(self): + def sliding_circuits_element(self): r""" - Return an element of the braid's sliding circuits, an the conjugating + Return an element of the braid's sliding circuits, and the conjugating braid. EXAMPLES:: @@ -2285,11 +2283,10 @@ def send_to_sc(self): sage: b = B([1, 2, 1, 2, 3, -1, 2, -1, 3]) sage: b.send_to_sc() (s0*s1*s0*s2*s1, s0^2*s1*s2) - """ to_sc = send_to_sc(self) B = self.parent() - return tuple(B._element_from_libbraiding(b) for b in to_sc) + return tuple([B._element_from_libbraiding(b) for b in to_sc]) def trajectory(self): r""" @@ -2304,7 +2301,6 @@ def trajectory(self): s0*s1*s2^3, s0*s1*s2*s1^2, s0*s1*s0*s2*s1] - """ traj = trajectory(self) B = self.parent() @@ -2312,7 +2308,7 @@ def trajectory(self): def cyclic_slidings(self): r""" - Return the the braid's cyclic slidings. + Return the braid's cyclic slidings. OUTPUT: The braid's cyclic slidings. Each cyclic sliding is a list of braids. @@ -2323,7 +2319,6 @@ def cyclic_slidings(self): sage: b.cyclic_slidings() [[s0*s2*s1*s0*s1*s2, s0*s1*s2*s1*s0^2, s1*s0*s2^2*s1*s0], [s0*s1*s2*s1^2*s0, s0*s1*s2*s1*s0*s2, s1*s0*s2*s0*s1*s2]] - """ cs = cyclic_slidings(self) B = self.parent() diff --git a/src/sage/libs/braiding.pyx b/src/sage/libs/braiding.pyx index 8feca132984..cdefd5d2867 100644 --- a/src/sage/libs/braiding.pyx +++ b/src/sage/libs/braiding.pyx @@ -516,7 +516,7 @@ def cyclic_slidings(braid): INPUT: - - ``braid```-- a braid + - ``braid`` -- a braid OUTPUT: From 2ca962729e32029b8a7395b5fceb3faf75e9e852 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Thu, 31 Oct 2024 11:06:29 +0530 Subject: [PATCH 019/210] added maximal_barrier() --- src/sage/graphs/matching_covered_graph.py | 189 ++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 12bcfc59d4d..bca2cff256c 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1794,6 +1794,195 @@ def get_matching(self): """ return self._matching + @doc_index('Barriers and canonical partition') + def maximal_barrier(self, vertex): + r""" + Return the (unique) maximal barrier containing the vertex. + + We use the following theorem. + + .. RUBRIC:: Theorem ([LM2024]_): + + Let `u` and `v` be any two vertices in a matchable graph `G`. Then the + graph `G - u - v` is matchable if and only if there is no barrier of + `G` which contains both `u` and `v`. + + And in order to find the vertices that do not lie in the maximal + barrier containing the provided vertex in linear time we take + inspiration of the `M` alternating tree seach method ([LR2004]_). + + INPUT: + + - ``vertex`` -- a vertex of the graph + + OUTPUT: + + - A :exc:`~ValueError` is returned if ``vertex`` is not a vertex of the + graph, otherwise a set of vertices that constitute the (unique) + maximal barrier containing the vertex is returned. + + EXAMPLES: + + The graph `K_4 \odot K_{3, 3}` is matching covered. Show the set of + vertices in the (unique) maximal barrier containing the vertex `2`:: + + sage: G = Graph([ + ....: (0, 2), (0, 3), (0, 4), (1, 2), + ....: (1, 3), (1, 4), (2, 5), (3, 6), + ....: (4, 7), (5, 6), (5, 7), (6, 7) + ....: ]) + sage: H = MatchingCoveredGraph(G) + sage: B = H.maximal_barrier(2) + sage: B + {2, 3, 4} + + Let `B` be a maximal barrier of a matching covered graph `G` (which is, + of course, a matchable graph). The graph, `J := G - B` has no even + component:: + + sage: J = G.copy() + sage: J.delete_vertices(B) + sage: all(len(K)%2 != 0 for K in J.connected_components()) + ... + True + + Let `B` be a maximal barrier in a matching covered graph `G` and let + `M` be a perfect matching of `G`. If `K` is an odd component of + `J := G - B`, then `M \cap \partial_G(K)` has precisely one edge and if + `v` is the end of that edge in `V(K)`, then `M \cap E(K)` is a perfect + matching of `K - v`:: + + sage: K = J.subgraph(vertices=(J.connected_components())[0]) + sage: # Let F := \partial_G(K) and T := M \cap F + sage: F = [edge for edge in G.edge_iterator() + ....: if (edge[0] in K and edge[1] not in K) + ....: or (edge[0] not in K and edge[1] in K) + ....: ] + sage: M = H.get_matching() + sage: T = [edge for edge in F if edge in M] + sage: len(T) == 1 + True + sage: v = T[0][0] if T[0][0] in K else T[0][1] + sage: # Let N := M \cap E(K) and L := K - v + sage: N = Graph([edge for edge in K.edge_iterator() if edge in M]) + sage: L = K.copy() + sage: L.delete_vertex(v) + sage: # Check if N is a perfect matching of L + sage: L.order() == 2*N.size() + True + + Let `B` be a maximal barrier of a matching covered graph `G` (which is, + of course, a matchable graph). The graph induced by each component of + `G - B` is factor critical:: + + sage: all((K.subgraph(vertices=connected_component)).is_factor_critical() + ....: for connected_component in K.connected_components() + ....: ) + True + + For a bicritical graph (for instance, the Petersen graph), for each + vertex the maximal barrier is a singleton set containing only that + vertex:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: u = 0 + sage: set([u]) == G.maximal_barrier(u) + True + + In a bipartite matching covered graph (for instance, the Hexahedral + graph), for a vertex, the maximal barrier is the set of vertices of + the color class that the particular vertex belongs to. In other words, + there are precisely two maximal barriers in a bipartite matching + covered graph, that is, the vertex sets of the individual color class:: + + sage: G = graphs.HexahedralGraph() + sage: H = MatchingCoveredGraph(G) + sage: A, _ = H.bipartite_sets() + sage: # needs random + sage: import random + sage: a = random.choice(list(A)) + sage: A == H.maximal_barrier(a) + True + + Maximal barriers of matching covered graph constitute a partition of + its vertex set:: + + sage: S = set() + sage: for v in H: + ....: B = tuple(sorted(list(H.maximal_barrier(v)))) + ....: S.add(B) + sage: S = list(S) + sage: # Check that S is a partition of the vertex set of H + sage: # Part 1: Check if S spans the vertex set of H + sage: sorted([u for B in S for u in B]) == sorted(list(H)) + True + sage: # Part 2: Check if each maximal barrier in S is disjoint + sage: is_disjoint = True + sage: for i in range(len(S)): + ....: for j in range(i+1, len(S)): + ....: c = [v for v in S[i] if v in S[j]] + ....: is_disjoint = (len(c) == 0) + sage: is_disjoint + True + + TESTS: + + Providing with a nonexistent vertex:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: G.maximal_barrier('') + Traceback (most recent call last): + ... + ValueError: vertex not in the graph + sage: G.maximal_barrier(100) + Traceback (most recent call last): + ... + ValueError: vertex 100 not in the graph + + REFERENCES: + + - [LZ2004]_ + - [LM2024]_ + + .. SEEALSO:: + + :meth:`~sage.graphs.graph.Graph.is_factor_critical`, + :meth:`~sage.graphs.graph.Graph.is_matching_covered`, + :meth:`~sage.graphs.graph.Graph.is_bicritical` + + """ + if vertex not in self: + raise ValueError('vertex {} not in the graph'.format(vertex)) + + G = Graph(self, multiedges=False) + M = Graph(self.get_matching()) + B = set([vertex]) + + # u: The M neighbor of vertex + u = next(M.neighbor_iterator(vertex)) + vertex_neighbors = [] + + for v in G.neighbor_iterator(vertex): + vertex_neighbors.append(v) + + # Goal: Find the vertices w such that G - w - vertex is matchable. + # In other words, there exists an odd length M-alternating vertex-w + # path in G, starting and ending with edges in M. Alternatively, there + # exists an even length M-alternating u-w path in the graph G - vertex + # starting with an edge not in M and ending with and edge in M. + + # even: The set of all such vertex w + from sage.graphs.matching import M_alternating_even_mark + even = M_alternating_even_mark(G=G, matching=M, vertex=u) + + for v in G: + if v not in even: + B.add(v) + + return B + @doc_index('Miscellaneous methods') def update_matching(self, matching): r""" From 9b68c4a12030f98a438ce8a3f95b9579c72983ab Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 1 Nov 2024 18:00:08 +0530 Subject: [PATCH 020/210] updated the documentation --- src/sage/graphs/matching_covered_graph.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index bca2cff256c..4d19c8748b4 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1801,7 +1801,7 @@ def maximal_barrier(self, vertex): We use the following theorem. - .. RUBRIC:: Theorem ([LM2024]_): + .. RUBRIC:: Theorem [LM2024]_: Let `u` and `v` be any two vertices in a matchable graph `G`. Then the graph `G - u - v` is matchable if and only if there is no barrier of @@ -1809,7 +1809,7 @@ def maximal_barrier(self, vertex): And in order to find the vertices that do not lie in the maximal barrier containing the provided vertex in linear time we take - inspiration of the `M` alternating tree seach method ([LR2004]_). + inspiration of the `M` alternating tree seach method [LR2004]_. INPUT: From 6cfacd3b0ad7ea3f2c520203fa5fa12aa5ed6d04 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 1 Nov 2024 18:27:54 +0530 Subject: [PATCH 021/210] updated the TODO list --- src/sage/graphs/matching_covered_graph.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 4d19c8748b4..18bb2812f48 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -36,8 +36,6 @@ - ``canonical_partition()`` | Return the canonical partition of the (matching covered) graph. - - ``maximal_barrier()`` | Return the (unique) maximal barrier of the - (matching covered) graph containing the (provided) vertex. Bricks, braces and tight cut decomposition: From b1b8d0277d8833b3093d558e6e74577db0d2a03d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 4 Nov 2024 08:15:55 +0100 Subject: [PATCH 022/210] check for E302 --- src/conftest.py | 1 + src/doc/ja/tutorial/japanesesupport.py | 2 ++ src/sage/algebras/splitting_algebra.py | 2 ++ src/sage/arith/misc.py | 2 ++ src/sage/doctest/control.py | 1 + src/sage/doctest/external.py | 24 +++++++++++++++++++ src/sage/doctest/reporting.py | 2 ++ src/sage/doctest/util.py | 2 ++ src/sage/features/__init__.py | 1 + src/sage/features/dvipng.py | 1 + src/sage/features/ffmpeg.py | 1 + src/sage/features/fricas.py | 2 ++ src/sage/features/gap.py | 1 + src/sage/features/giac.py | 2 ++ src/sage/features/igraph.py | 1 + src/sage/features/imagemagick.py | 2 ++ src/sage/features/kenzo.py | 1 + src/sage/features/latex.py | 1 + src/sage/features/msolve.py | 2 ++ src/sage/features/palp.py | 2 ++ src/sage/features/pdf2svg.py | 1 + src/sage/features/poppler.py | 2 ++ src/sage/features/symengine_py.py | 1 + src/sage/games/quantumino.py | 5 ++++ src/sage/graphs/domination.py | 2 ++ .../homology_vector_space_with_basis.py | 1 + src/sage/interacts/library.py | 1 + src/sage/interfaces/ecm.py | 1 + src/sage/knots/knot.py | 2 ++ src/sage/libs/eclib/constructor.py | 1 + src/sage/libs/eclib/interface.py | 1 + src/sage/libs/pari/__init__.py | 1 + src/sage/libs/singular/standard_options.py | 2 ++ src/sage/matroids/dual_matroid.py | 1 + src/sage/modules/with_basis/representation.py | 1 + src/sage/monoids/indexed_free_monoid.py | 3 +++ .../numerical/backends/cvxpy_backend_test.py | 1 + .../backends/generic_backend_test.py | 1 + .../backends/glpk_exact_backend_test.py | 1 + .../backends/interactivelp_backend_test.py | 1 + .../numerical/backends/logging_backend.py | 4 ++++ .../numerical/backends/scip_backend_test.py | 1 + .../numerical/interactive_simplex_method.py | 5 ++++ src/sage/numerical/knapsack.py | 2 ++ src/sage/probability/random_variable.py | 5 ++++ .../elliptic_curves/ell_finite_field.py | 1 + src/tox.ini | 2 +- 47 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/conftest.py b/src/conftest.py index 6bc7ee2e3fd..951d2fddfad 100644 --- a/src/conftest.py +++ b/src/conftest.py @@ -162,6 +162,7 @@ def pytest_addoption(parser): dest="doctest", ) + @pytest.fixture(autouse=True, scope="session") def add_imports(doctest_namespace: dict[str, Any]): """ diff --git a/src/doc/ja/tutorial/japanesesupport.py b/src/doc/ja/tutorial/japanesesupport.py index 6d954e3ddc9..f19aa9953e1 100644 --- a/src/doc/ja/tutorial/japanesesupport.py +++ b/src/doc/ja/tutorial/japanesesupport.py @@ -2,6 +2,7 @@ import re __RGX = re.compile(r'([^!-~])[\n\r\t]+([^!-~])') + def trunc_whitespace(app, doctree, docname): from docutils.nodes import Text, paragraph if not app.config.japanesesupport_trunc_whitespace: @@ -15,6 +16,7 @@ def trunc_whitespace(app, doctree, docname): #newtext = newtext.strip() node.parent.replace(node, Text(newtext)) + def setup(app): app.add_config_value('japanesesupport_trunc_whitespace', True, True) app.connect("doctree-resolved", trunc_whitespace) diff --git a/src/sage/algebras/splitting_algebra.py b/src/sage/algebras/splitting_algebra.py index 43d72ed7470..e018b0f3db6 100644 --- a/src/sage/algebras/splitting_algebra.py +++ b/src/sage/algebras/splitting_algebra.py @@ -126,6 +126,8 @@ def monomial_coefficients(self): # ------------------------------------------------------------------------------------------------------------------ # Parent class of the splitting algebra # -------------------------------------------------------------------------------------------------------- + + class SplittingAlgebra(PolynomialQuotientRing_domain): r""" For a given monic polynomial `p(t)` of degree `n` over a commutative diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 745d5fcbbe7..3ffb0205782 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -6375,6 +6375,7 @@ def dedekind_psi(N): N = Integer(N) return Integer(N * prod(1 + 1 / p for p in N.prime_divisors())) + def smooth_part(x, base): r""" Given an element ``x`` of a Euclidean domain and a factor base ``base``, @@ -6423,6 +6424,7 @@ def smooth_part(x, base): from sage.structure.factorization import Factorization return Factorization(fs) + def coprime_part(x, base): r""" Given an element ``x`` of a Euclidean domain and a factor base ``base``, diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index fff35be8307..05dde014fec 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -59,6 +59,7 @@ auto_optional_tags = set() + class DocTestDefaults(SageObject): """ This class is used for doctesting the Sage doctest module. diff --git a/src/sage/doctest/external.py b/src/sage/doctest/external.py index 56727bd79f6..7aa6dff7343 100644 --- a/src/sage/doctest/external.py +++ b/src/sage/doctest/external.py @@ -45,6 +45,7 @@ # software xxx is available to Sage. prefix = 'has_' + def has_internet(): """ Test if Internet is available. @@ -61,6 +62,7 @@ def has_internet(): from sage.features.internet import Internet return Internet().is_present() + def has_latex(): """ Test if Latex is available. @@ -74,6 +76,7 @@ def has_latex(): from sage.features.latex import latex return latex().is_present() + def has_xelatex(): """ Test if xelatex is available. @@ -87,6 +90,7 @@ def has_xelatex(): from sage.features.latex import xelatex return xelatex().is_present() + def has_pdflatex(): """ Test if pdflatex is available. @@ -100,6 +104,7 @@ def has_pdflatex(): from sage.features.latex import pdflatex return pdflatex().is_present() + def has_lualatex(): """ Test if lualatex is available. @@ -113,6 +118,7 @@ def has_lualatex(): from sage.features.latex import lualatex return lualatex().is_present() + def has_magma(): """ Test if Magma is available. @@ -126,6 +132,7 @@ def has_magma(): from sage.features.interfaces import Magma return Magma().is_present() + def has_matlab(): """ Test if Matlab is available. @@ -139,6 +146,7 @@ def has_matlab(): from sage.features.interfaces import Matlab return Matlab().is_present() + def has_mathematica(): """ Test if Mathematica is available. @@ -152,6 +160,7 @@ def has_mathematica(): from sage.features.interfaces import Mathematica return Mathematica().is_present() + def has_maple(): """ Test if Maple is available. @@ -165,6 +174,7 @@ def has_maple(): from sage.features.interfaces import Maple return Maple().is_present() + def has_macaulay2(): """ Test if Macaulay2 is available. @@ -178,6 +188,7 @@ def has_macaulay2(): from sage.features.interfaces import Macaulay2 return Macaulay2().is_present() + def has_octave(): """ Test if Octave is available. @@ -191,6 +202,7 @@ def has_octave(): from sage.features.interfaces import Octave return Octave().is_present() + def has_pandoc(): """ Test if pandoc is available. @@ -204,6 +216,7 @@ def has_pandoc(): from sage.features.pandoc import Pandoc return Pandoc().is_present() + def has_scilab(): """ Test if Scilab is available. @@ -221,6 +234,7 @@ def has_scilab(): except Exception: return False + def has_cplex(): """ Test if CPLEX is available. @@ -234,6 +248,7 @@ def has_cplex(): from sage.features.mip_backends import CPLEX return CPLEX().is_present() + def has_gurobi(): """ Test if Gurobi is available. @@ -247,6 +262,7 @@ def has_gurobi(): from sage.features.mip_backends import Gurobi return Gurobi().is_present() + def has_graphviz(): """ Test if graphviz (dot, twopi, neato) are available. @@ -260,6 +276,7 @@ def has_graphviz(): from sage.features.graphviz import Graphviz return Graphviz().is_present() + def has_ffmpeg(): """ Test if ffmpeg is available. @@ -273,6 +290,7 @@ def has_ffmpeg(): from sage.features.ffmpeg import FFmpeg return FFmpeg().is_present() + def has_imagemagick(): """ Test if ImageMagick (command magick or convert) is available. @@ -286,6 +304,7 @@ def has_imagemagick(): from sage.features.imagemagick import ImageMagick return ImageMagick().is_present() + def has_dvipng(): """ Test if dvipng is available. @@ -299,6 +318,7 @@ def has_dvipng(): from sage.features.dvipng import dvipng return dvipng().is_present() + def has_pdf2svg(): """ Test if pdf2svg is available. @@ -312,6 +332,7 @@ def has_pdf2svg(): from sage.features.pdf2svg import pdf2svg return pdf2svg().is_present() + def has_rubiks(): """ Test if the rubiks package (``cu2``, ``cubex``, ``dikcube``, @@ -326,6 +347,7 @@ def has_rubiks(): from sage.features.rubiks import Rubiks return Rubiks().is_present() + def has_4ti2(): """ Test if the 4ti2 package is available. @@ -339,6 +361,7 @@ def has_4ti2(): from sage.features.four_ti_2 import FourTi2 return FourTi2().is_present() + def external_features(): r""" Generate the features that are only to be tested if ``--optional=external`` is used. @@ -363,6 +386,7 @@ def external_features(): yield CPLEX() yield Gurobi() + def external_software() -> list[str]: """ Return the alphabetical list of external software supported by this module. diff --git a/src/sage/doctest/reporting.py b/src/sage/doctest/reporting.py index e6bfd52bf33..54742cd6c1e 100644 --- a/src/sage/doctest/reporting.py +++ b/src/sage/doctest/reporting.py @@ -50,6 +50,7 @@ from sage.doctest.sources import DictAsObject from .external import available_software + def signal_name(sig): """ Return a string describing a signal number. @@ -91,6 +92,7 @@ def signal_name(sig): return "bus error" return "signal %s" % sig + class DocTestReporter(SageObject): """ This class reports to the users on the results of doctests. diff --git a/src/sage/doctest/util.py b/src/sage/doctest/util.py index ed831598e65..e17df277c1f 100644 --- a/src/sage/doctest/util.py +++ b/src/sage/doctest/util.py @@ -26,6 +26,7 @@ from time import time as walltime from os import sysconf, times + def count_noun(number, noun, plural=None, pad_number=False, pad_noun=False): """ EXAMPLES:: @@ -614,6 +615,7 @@ def make_recording_dict(D, st, gt): ans.got = gt return ans + class NestedName: """ Class used to construct fully qualified names based on indentation level. diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index e02015a5710..ac4a0bcd97f 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -418,6 +418,7 @@ def is_hidden(self): return True return False + class FeatureNotPresentError(RuntimeError): r""" A missing feature error. diff --git a/src/sage/features/dvipng.py b/src/sage/features/dvipng.py index 68bcdcb5a04..4ae0c7a01cf 100644 --- a/src/sage/features/dvipng.py +++ b/src/sage/features/dvipng.py @@ -14,6 +14,7 @@ from . import Executable + class dvipng(Executable): r""" A :class:`~sage.features.Feature` describing the presence of ``dvipng``. diff --git a/src/sage/features/ffmpeg.py b/src/sage/features/ffmpeg.py index 0d3ff8e4232..8214e4d6ff3 100644 --- a/src/sage/features/ffmpeg.py +++ b/src/sage/features/ffmpeg.py @@ -14,6 +14,7 @@ from . import Executable, FeatureTestResult + class FFmpeg(Executable): r""" A :class:`~sage.features.Feature` describing the presence of :ref:`ffmpeg `. diff --git a/src/sage/features/fricas.py b/src/sage/features/fricas.py index 539b3b027dd..15c346248ae 100644 --- a/src/sage/features/fricas.py +++ b/src/sage/features/fricas.py @@ -16,6 +16,7 @@ import subprocess from . import Executable, FeatureTestResult + class FriCAS(Executable): r""" A :class:`~sage.features.Feature` which checks for the :ref:`fricas ` binary. @@ -62,5 +63,6 @@ def is_functional(self): return FeatureTestResult(self, True) + def all_features(): return [FriCAS()] diff --git a/src/sage/features/gap.py b/src/sage/features/gap.py index 609cb37c263..6a6f20b30a8 100644 --- a/src/sage/features/gap.py +++ b/src/sage/features/gap.py @@ -16,6 +16,7 @@ from .join_feature import JoinFeature from .sagemath import sage__libs__gap + class GapPackage(Feature): r""" A :class:`~sage.features.Feature` describing the presence of a GAP package. diff --git a/src/sage/features/giac.py b/src/sage/features/giac.py index 6f9fe2ccfba..67403a332be 100644 --- a/src/sage/features/giac.py +++ b/src/sage/features/giac.py @@ -5,6 +5,7 @@ from . import Executable, FeatureTestResult + class Giac(Executable): r""" A :class:`~sage.features.Feature` describing the presence of :ref:`giac `. @@ -26,5 +27,6 @@ def __init__(self): Executable.__init__(self, 'giac', executable='giac', spkg='giac', type='standard') + def all_features(): return [Giac()] diff --git a/src/sage/features/igraph.py b/src/sage/features/igraph.py index 9bb61c28454..bd349ec730d 100644 --- a/src/sage/features/igraph.py +++ b/src/sage/features/igraph.py @@ -40,5 +40,6 @@ def __init__(self): [PythonModule('igraph', spkg='python_igraph', url='http://igraph.org')]) + def all_features(): return [python_igraph()] diff --git a/src/sage/features/imagemagick.py b/src/sage/features/imagemagick.py index 866d0aed95e..fa63616b596 100644 --- a/src/sage/features/imagemagick.py +++ b/src/sage/features/imagemagick.py @@ -21,6 +21,7 @@ from . import Executable, FeatureTestResult from .join_feature import JoinFeature + class Magick(Executable): r""" A :class:`~sage.features.Feature` describing the presence of ``magick`` or the deprecated ``convert``. @@ -134,5 +135,6 @@ def __init__(self): spkg='imagemagick', url='https://www.imagemagick.org/') + def all_features(): return [ImageMagick()] diff --git a/src/sage/features/kenzo.py b/src/sage/features/kenzo.py index b5d83b06972..3d2efaf50d6 100644 --- a/src/sage/features/kenzo.py +++ b/src/sage/features/kenzo.py @@ -18,6 +18,7 @@ from . import Feature, FeatureTestResult + class Kenzo(Feature): r""" A :class:`~sage.features.Feature` describing the presence of :ref:`Kenzo `. diff --git a/src/sage/features/latex.py b/src/sage/features/latex.py index 271800beece..46173f7484b 100644 --- a/src/sage/features/latex.py +++ b/src/sage/features/latex.py @@ -208,6 +208,7 @@ def __init__(self): Executable.__init__(self, 'dvips', executable='dvips', url='https://tug.org/texinfohtml/dvips.html') + class TeXFile(StaticFile): r""" A :class:`sage.features.Feature` describing the presence of a TeX file. diff --git a/src/sage/features/msolve.py b/src/sage/features/msolve.py index bc66da45044..24215a7c57c 100644 --- a/src/sage/features/msolve.py +++ b/src/sage/features/msolve.py @@ -22,6 +22,7 @@ from . import Executable from . import FeatureTestResult + class msolve(Executable): r""" A :class:`~sage.features.Feature` describing the presence of :ref:`msolve `. @@ -64,5 +65,6 @@ def is_functional(self): reason="output of msolve -h not recognized") return FeatureTestResult(self, True) + def all_features(): return [msolve()] diff --git a/src/sage/features/palp.py b/src/sage/features/palp.py index 9e3324c495b..b20f44104d6 100644 --- a/src/sage/features/palp.py +++ b/src/sage/features/palp.py @@ -43,6 +43,7 @@ def __init__(self, palpprog, suff=None): executable=f"{palpprog}.x", spkg='palp', type='standard') + class Palp(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of :ref:`PALP `. @@ -61,5 +62,6 @@ def __init__(self): for suff in (None, 4, 5, 6, 11)], description='PALP') + def all_features(): return [Palp()] diff --git a/src/sage/features/pdf2svg.py b/src/sage/features/pdf2svg.py index 41014eb8e5c..92d9f563b5b 100644 --- a/src/sage/features/pdf2svg.py +++ b/src/sage/features/pdf2svg.py @@ -14,6 +14,7 @@ from . import Executable + class pdf2svg(Executable): r""" A :class:`~sage.features.Feature` describing the presence of :ref:`pdf2svg `. diff --git a/src/sage/features/poppler.py b/src/sage/features/poppler.py index a6da8343f53..436506e0b36 100644 --- a/src/sage/features/poppler.py +++ b/src/sage/features/poppler.py @@ -32,6 +32,7 @@ from . import Executable + class pdftocairo(Executable): r""" A :class:`sage.features.Feature` describing the presence of @@ -54,5 +55,6 @@ def __init__(self): Executable.__init__(self, "pdftocairo", executable='pdftocairo', url='https://poppler.freedesktop.org/') + def all_features(): return [pdftocairo()] diff --git a/src/sage/features/symengine_py.py b/src/sage/features/symengine_py.py index 96a64ca60b3..e822e252eda 100644 --- a/src/sage/features/symengine_py.py +++ b/src/sage/features/symengine_py.py @@ -40,5 +40,6 @@ def __init__(self): [PythonModule('symengine', spkg='symengine_py', url='https://pypi.org/project/symengine')]) + def all_features(): return [symengine_py()] diff --git a/src/sage/games/quantumino.py b/src/sage/games/quantumino.py index e40dc47f407..0a6abafd2fd 100644 --- a/src/sage/games/quantumino.py +++ b/src/sage/games/quantumino.py @@ -205,6 +205,7 @@ pentaminos.append(Polyomino([(0,0,0), (0,1,0), (1,1,0), (1,2,0), (1,2,1)], color='purple')) pentaminos.append(Polyomino([(0,1,0), (1,0,0), (1,1,0), (1,1,1), (1,2,0)], color='gray')) + def show_pentaminos(box=(5,8,2)): r""" Show the 17 3-D pentaminos included in the game and the `5 \times 8 @@ -245,6 +246,8 @@ def show_pentaminos(box=(5,8,2)): ############################## # Class QuantuminoState ############################## + + class QuantuminoState(SageObject): r""" A state of the Quantumino puzzle. @@ -386,6 +389,8 @@ def show3d(self, size=0.85): ############################## # Class QuantuminoSolver ############################## + + class QuantuminoSolver(SageObject): r""" Return the Quantumino solver for the given box where one of the diff --git a/src/sage/graphs/domination.py b/src/sage/graphs/domination.py index 37c0ca5fb51..1803e91bb2c 100644 --- a/src/sage/graphs/domination.py +++ b/src/sage/graphs/domination.py @@ -475,6 +475,7 @@ def neighbors_iter(x): # Prevent finding twice a solution p.add_constraint(p.sum(b[u] for u in dom) <= best - 1) + def dominating_set(g, k=1, independent=False, total=False, connected=False, value_only=False, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" @@ -587,6 +588,7 @@ def dominating_set(g, k=1, independent=False, total=False, connected=False, valu # Enumeration of minimal dominating set as described in [BDHPR2019]_ # ============================================================================== + def _parent(G, dom, V_prev): r""" Return a subset of dom that is irredundant in ``V_prev``. diff --git a/src/sage/homology/homology_vector_space_with_basis.py b/src/sage/homology/homology_vector_space_with_basis.py index 60f2ccc77f2..ee30f144282 100644 --- a/src/sage/homology/homology_vector_space_with_basis.py +++ b/src/sage/homology/homology_vector_space_with_basis.py @@ -1434,6 +1434,7 @@ def sum_indices(k, i_k_plus_one, S_k_plus_one): return [[i_k] + l for i_k in range(S_k, i_k_plus_one) for l in sum_indices(k-1, i_k, S_k)] + def is_GF2(R): r""" Return ``True`` iff ``R`` is isomorphic to the field `\GF{2}`. diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 7aa5ac779d9..a41ba32b393 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -496,6 +496,7 @@ def quadratic_equation(A, B, C): r"\frac{-%s\pm\sqrt{%s}}{%s} = %s$" html(calc % (B, dis1, A, B, dis2, (2*A), sol)) + @library_interact( a0=lambda: slider(0, 360, 1, 30, label='A'), a1=lambda: slider(0, 360, 1, 180, label='B'), diff --git a/src/sage/interfaces/ecm.py b/src/sage/interfaces/ecm.py index 7d1ac74b7c1..74d51dbb51e 100644 --- a/src/sage/interfaces/ecm.py +++ b/src/sage/interfaces/ecm.py @@ -57,6 +57,7 @@ from sage.env import SAGE_ECMBIN + class ECM(SageObject): def __init__(self, B1=10, B2=None, **kwds): diff --git a/src/sage/knots/knot.py b/src/sage/knots/knot.py index aaa01cdade9..607c73085aa 100644 --- a/src/sage/knots/knot.py +++ b/src/sage/knots/knot.py @@ -30,6 +30,8 @@ from sage.categories.monoids import Monoids # We need Link to be first in the MRO in order to use its equality, hash, etc. + + class Knot(Link, Element, metaclass=InheritComparisonClasscallMetaclass): r""" A knot. diff --git a/src/sage/libs/eclib/constructor.py b/src/sage/libs/eclib/constructor.py index 79d28b90c1c..37df4eb935b 100644 --- a/src/sage/libs/eclib/constructor.py +++ b/src/sage/libs/eclib/constructor.py @@ -1,5 +1,6 @@ "Cremona modular symbols" + def CremonaModularSymbols(level, sign=0, cuspidal=False, verbose=0): """ Return the space of Cremona modular symbols with given level, sign, etc. diff --git a/src/sage/libs/eclib/interface.py b/src/sage/libs/eclib/interface.py index a5e65a37d4d..511acfec33e 100644 --- a/src/sage/libs/eclib/interface.py +++ b/src/sage/libs/eclib/interface.py @@ -31,6 +31,7 @@ from .mwrank import _Curvedata, _two_descent, _mw, parse_point_list + class mwrank_EllipticCurve(SageObject): r""" The :class:`mwrank_EllipticCurve` class represents an elliptic diff --git a/src/sage/libs/pari/__init__.py b/src/sage/libs/pari/__init__.py index ccb18792918..1702291536d 100644 --- a/src/sage/libs/pari/__init__.py +++ b/src/sage/libs/pari/__init__.py @@ -173,6 +173,7 @@ 3.60546360143265208591582056420772677481026899659802474544 # 32-bit """ + def _get_pari_instance(): """ TESTS:: diff --git a/src/sage/libs/singular/standard_options.py b/src/sage/libs/singular/standard_options.py index 476961b2f09..3870dc959fd 100644 --- a/src/sage/libs/singular/standard_options.py +++ b/src/sage/libs/singular/standard_options.py @@ -6,6 +6,7 @@ - Martin Albrecht """ + class LibSingularGBDefaultContext: def __init__(self): """ @@ -97,6 +98,7 @@ def __exit__(self, typ, value, tb): """ self.libsingular_option_context.__exit__(typ,value,tb) + def libsingular_gb_standard_options(func): r""" Decorator to force a reduced Singular groebner basis. diff --git a/src/sage/matroids/dual_matroid.py b/src/sage/matroids/dual_matroid.py index d4dce31ddc2..3c7c92e6c9c 100644 --- a/src/sage/matroids/dual_matroid.py +++ b/src/sage/matroids/dual_matroid.py @@ -53,6 +53,7 @@ from sage.matroids.matroid import Matroid + class DualMatroid(Matroid): r""" Dual of a matroid. diff --git a/src/sage/modules/with_basis/representation.py b/src/sage/modules/with_basis/representation.py index 5271c7a6b38..09f2cd9d4df 100644 --- a/src/sage/modules/with_basis/representation.py +++ b/src/sage/modules/with_basis/representation.py @@ -27,6 +27,7 @@ from sage.modules.free_module_element import vector from sage.modules.with_basis.subquotient import SubmoduleWithBasis, QuotientModuleWithBasis + class Representation_abstract: """ Abstract base class for representations of semigroups. diff --git a/src/sage/monoids/indexed_free_monoid.py b/src/sage/monoids/indexed_free_monoid.py index 69b67e260f7..8f6efea8487 100644 --- a/src/sage/monoids/indexed_free_monoid.py +++ b/src/sage/monoids/indexed_free_monoid.py @@ -674,6 +674,7 @@ def dict(self): """ return copy(self._monomial) + class IndexedMonoid(Parent, IndexedGenerators, UniqueRepresentation): """ Base class for monoids with an indexed set of generators. @@ -859,6 +860,7 @@ def monoid_generators(self): gens = monoid_generators + class IndexedFreeMonoid(IndexedMonoid): """ Free monoid with an indexed set of generators. @@ -939,6 +941,7 @@ def gen(self, x): except (ValueError, TypeError, NotImplementedError): # Backup (e.g., if it is a string) return self.element_class(self, ((x, ZZ.one()),)) + class IndexedFreeAbelianMonoid(IndexedMonoid): """ Free abelian monoid with an indexed set of generators. diff --git a/src/sage/numerical/backends/cvxpy_backend_test.py b/src/sage/numerical/backends/cvxpy_backend_test.py index 1f5f030248e..d186a1054ce 100644 --- a/src/sage/numerical/backends/cvxpy_backend_test.py +++ b/src/sage/numerical/backends/cvxpy_backend_test.py @@ -3,6 +3,7 @@ from sage.numerical.backends.generic_backend import GenericBackend from sage.numerical.mip import MixedIntegerLinearProgram + @pytest.importorskip("cvxpy") class TestCVXPYBackend(GenericBackendTests): diff --git a/src/sage/numerical/backends/generic_backend_test.py b/src/sage/numerical/backends/generic_backend_test.py index 2b5411fb64e..64c9eb44670 100644 --- a/src/sage/numerical/backends/generic_backend_test.py +++ b/src/sage/numerical/backends/generic_backend_test.py @@ -3,6 +3,7 @@ from sage.structure.sage_object import SageObject from sage.structure.sage_object_test import SageObjectTests + class GenericBackendTests(SageObjectTests): @pytest.fixture diff --git a/src/sage/numerical/backends/glpk_exact_backend_test.py b/src/sage/numerical/backends/glpk_exact_backend_test.py index 125e041f29e..67b169baa82 100644 --- a/src/sage/numerical/backends/glpk_exact_backend_test.py +++ b/src/sage/numerical/backends/glpk_exact_backend_test.py @@ -3,6 +3,7 @@ from sage.numerical.backends.generic_backend import GenericBackend from sage.numerical.mip import MixedIntegerLinearProgram + class TestGLPKExactBackend(GenericBackendTests): @pytest.fixture diff --git a/src/sage/numerical/backends/interactivelp_backend_test.py b/src/sage/numerical/backends/interactivelp_backend_test.py index 5523c40ce1f..d0e4b091563 100644 --- a/src/sage/numerical/backends/interactivelp_backend_test.py +++ b/src/sage/numerical/backends/interactivelp_backend_test.py @@ -3,6 +3,7 @@ from sage.numerical.backends.generic_backend import GenericBackend from sage.numerical.mip import MixedIntegerLinearProgram + class TestInteractiveLPBackend(GenericBackendTests): @pytest.fixture diff --git a/src/sage/numerical/backends/logging_backend.py b/src/sage/numerical/backends/logging_backend.py index d2d7bd98299..a7acf57341f 100644 --- a/src/sage/numerical/backends/logging_backend.py +++ b/src/sage/numerical/backends/logging_backend.py @@ -20,6 +20,7 @@ from sage.numerical.backends.generic_backend import GenericBackend + def _format_function_call(fn_name, *v, **k): """ Return a Python function call as a string. @@ -33,6 +34,7 @@ def _format_function_call(fn_name, *v, **k): args = [ repr(a) for a in v ] + [ "%s=%r" % (arg,val) for arg, val in k.items() ] return "{}({})".format(fn_name, ", ".join(args)) + def _make_wrapper(backend, attr): """ Return a wrapper for the backend method named by ``attr`` that does the logging. @@ -90,6 +92,7 @@ def m(self, *args, **kwdargs): update_wrapper(m, getattr(backend, attr)) return m + class LoggingBackend(GenericBackend): """ See :class:`LoggingBackendFactory` for documentation. @@ -232,6 +235,7 @@ def _test_{name}(cls, tester=None, **options): from sage.rings.rational_field import QQ + def LoggingBackendFactory(solver=None, printing=True, doctest_file=None, test_method_file=None, test_method=None, base_ring=QQ): """ diff --git a/src/sage/numerical/backends/scip_backend_test.py b/src/sage/numerical/backends/scip_backend_test.py index 136d3ce914b..f10f6edee46 100644 --- a/src/sage/numerical/backends/scip_backend_test.py +++ b/src/sage/numerical/backends/scip_backend_test.py @@ -3,6 +3,7 @@ from sage.numerical.backends.generic_backend import GenericBackend from sage.numerical.mip import MixedIntegerLinearProgram + @pytest.importorskip("pyscipopt") class TestSCIPBackend(GenericBackendTests): diff --git a/src/sage/numerical/interactive_simplex_method.py b/src/sage/numerical/interactive_simplex_method.py index a89da826c77..6c55c27192a 100644 --- a/src/sage/numerical/interactive_simplex_method.py +++ b/src/sage/numerical/interactive_simplex_method.py @@ -213,6 +213,7 @@ # will have to be left. generate_real_LaTeX = False + def _assemble_arrayl(lines, stretch=None): r""" Return ``lines`` assembled in a left-justified array. @@ -442,6 +443,7 @@ def variable(R, v): current_style = 'UAlberta' + def default_variable_name(variable): r""" Return default variable name for the current :func:`style`. @@ -465,6 +467,7 @@ def default_variable_name(variable): """ return available_styles[current_style][variable] + def style(new_style=None): r""" Set or get the current style of problems and dictionaries. @@ -3704,6 +3707,7 @@ def update(self): 5000 """ + class LPDictionary(LPAbstractDictionary): r""" Construct a dictionary for an LP problem. @@ -4265,6 +4269,7 @@ def update(self): random_dictionary = LPDictionary.random_element + class LPRevisedDictionary(LPAbstractDictionary): r""" Construct a revised dictionary for an LP problem. diff --git a/src/sage/numerical/knapsack.py b/src/sage/numerical/knapsack.py index 9f9d06fcd3b..8776799d338 100644 --- a/src/sage/numerical/knapsack.py +++ b/src/sage/numerical/knapsack.py @@ -98,6 +98,7 @@ from sage.rings.integer import Integer from sage.structure.sage_object import SageObject + class Superincreasing(SageObject): r""" A class for super-increasing sequences. @@ -545,6 +546,7 @@ def subset_sum(self, N): else: return [] + def knapsack(seq, binary=True, max=1, value_only=False, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" diff --git a/src/sage/probability/random_variable.py b/src/sage/probability/random_variable.py index cb5c0426c5a..ce66f36bdb3 100644 --- a/src/sage/probability/random_variable.py +++ b/src/sage/probability/random_variable.py @@ -26,6 +26,7 @@ ################################################################################ ################################################################################ + def is_ProbabilitySpace(S): from sage.misc.superseded import deprecation deprecation(38184, @@ -33,6 +34,7 @@ def is_ProbabilitySpace(S): "use 'isinstance(..., ProbabilitySpace_generic)' instead.") return isinstance(S, ProbabilitySpace_generic) + def is_DiscreteProbabilitySpace(S): from sage.misc.superseded import deprecation deprecation(38184, @@ -40,6 +42,7 @@ def is_DiscreteProbabilitySpace(S): "use 'isinstance(..., DiscreteProbabilitySpace)' instead.") return isinstance(S, DiscreteProbabilitySpace) + def is_RandomVariable(X): from sage.misc.superseded import deprecation deprecation(38184, @@ -47,6 +50,7 @@ def is_RandomVariable(X): "use 'isinstance(..., RandomVariable_generic)' instead.") return isinstance(X, RandomVariable_generic) + def is_DiscreteRandomVariable(X): from sage.misc.superseded import deprecation deprecation(38184, @@ -299,6 +303,7 @@ def translation_correlation(self, other, map): ################################################################################ ################################################################################ + class ProbabilitySpace_generic(RandomVariable_generic): r""" A probability space. diff --git a/src/sage/schemes/elliptic_curves/ell_finite_field.py b/src/sage/schemes/elliptic_curves/ell_finite_field.py index 905cc63e149..7e22d8bd48f 100755 --- a/src/sage/schemes/elliptic_curves/ell_finite_field.py +++ b/src/sage/schemes/elliptic_curves/ell_finite_field.py @@ -2942,6 +2942,7 @@ def find_q(m, m4_fac, D): seen.add(Et) yield Et + def EllipticCurve_with_prime_order(N): r""" Given a prime number ``N``, find another prime number `p` and construct an diff --git a/src/tox.ini b/src/tox.ini index b6548bc55a4..ad9a990b9ca 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -180,7 +180,7 @@ description = # W605: invalid escape sequence ‘x’ # See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes deps = pycodestyle -commands = pycodestyle --select E111,E21,E221,E222,E225,E227,E228,E25,E271,E275,E303,E305,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/} +commands = pycodestyle --select E111,E21,E221,E222,E225,E227,E228,E25,E271,E275,E302,E303,E305,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/} pycodestyle --select E111,E271,E301,E302,E303,E305,E306,E401,E502,E703,E712,E713,E714,E72,W29,W391,W605, --filename *.pyx {posargs:{toxinidir}/sage/} [pycodestyle] From fb4580a0ca0a7e170859d38a7517ca435f6f3a4e Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 4 Nov 2024 15:15:33 +0530 Subject: [PATCH 023/210] added the definition of barrier --- src/sage/graphs/matching_covered_graph.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 18bb2812f48..a1e21271734 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1797,6 +1797,12 @@ def maximal_barrier(self, vertex): r""" Return the (unique) maximal barrier containing the vertex. + For a matching covered graph `G`, a subset `B` of the vertex set `V` is + a barrier if `|B| = o(G - B)`, where `|B|` denotes the cardinality of + the set `B` and `o(G - B)` denotes the number of odd components in the + graph `G - B`. And a barrier `B` is a maximal barrier if `C` is not a + barrier for each `C` such that `B \subset C \subseteq V`. + We use the following theorem. .. RUBRIC:: Theorem [LM2024]_: From 47fc5589bcd7c7a7dbd52a6eee7b40fb27a2e1da Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 4 Nov 2024 15:17:21 +0530 Subject: [PATCH 024/210] updated the description --- src/sage/graphs/matching_covered_graph.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index a1e21271734..4eeceaa3b72 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1803,7 +1803,8 @@ def maximal_barrier(self, vertex): graph `G - B`. And a barrier `B` is a maximal barrier if `C` is not a barrier for each `C` such that `B \subset C \subseteq V`. - We use the following theorem. + In a matching covered graph, each vertex belongs to a unique maximal + barrier, which is a consequence of the following theorem. .. RUBRIC:: Theorem [LM2024]_: From 29241e1d96aa90c3d9774e4a4b534cd2b125e4fd Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 4 Nov 2024 15:19:55 +0530 Subject: [PATCH 025/210] updated maximal_barrier() --- src/sage/graphs/matching_covered_graph.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 4eeceaa3b72..5de958c6b99 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1967,10 +1967,6 @@ def maximal_barrier(self, vertex): # u: The M neighbor of vertex u = next(M.neighbor_iterator(vertex)) - vertex_neighbors = [] - - for v in G.neighbor_iterator(vertex): - vertex_neighbors.append(v) # Goal: Find the vertices w such that G - w - vertex is matchable. # In other words, there exists an odd length M-alternating vertex-w @@ -1982,9 +1978,7 @@ def maximal_barrier(self, vertex): from sage.graphs.matching import M_alternating_even_mark even = M_alternating_even_mark(G=G, matching=M, vertex=u) - for v in G: - if v not in even: - B.add(v) + B.update(v for v in G if v not in even) return B From 8c01910590284bfbc006dafa3ef1569a23712e94 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 4 Nov 2024 15:20:47 +0530 Subject: [PATCH 026/210] updated .. SEEALSO:: --- src/sage/graphs/matching_covered_graph.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 5de958c6b99..97ad0c98d51 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1953,10 +1953,9 @@ def maximal_barrier(self, vertex): .. SEEALSO:: - :meth:`~sage.graphs.graph.Graph.is_factor_critical`, - :meth:`~sage.graphs.graph.Graph.is_matching_covered`, - :meth:`~sage.graphs.graph.Graph.is_bicritical` - + - :meth:`~sage.graphs.graph.Graph.is_bicritical` + - :meth:`~sage.graphs.graph.Graph.is_matching_covered` + - :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.canonical_partition` """ if vertex not in self: raise ValueError('vertex {} not in the graph'.format(vertex)) From 4e47c8c10470962b700b2309b219463d273d9d49 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 4 Nov 2024 15:30:29 +0530 Subject: [PATCH 027/210] added canonical_partition() --- src/sage/graphs/matching_covered_graph.py | 79 +++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 97ad0c98d51..c921277f021 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1542,6 +1542,85 @@ def allows_loops(self): """ return False + @doc_index('Barriers and canonical partition') + def canonical_partition(self): + r""" + Return the canonical partition of the (matching covered) graph. + + For a matching covered graph `G`, a subset `B` of the vertex set `V` is + a barrier if `|B| = o(G - B)`, where `|B|` denotes the cardinality of + the set `B` and `o(G - B)` denotes the number of odd components in the + graph `G - B`. And a barrier `B` is a maximal barrier if `C` is not a + barrier for each `C` such that `B \subset C \subseteq V`. + + Note that in a matching covered graph, each vertex belongs to a unique + maximal barrier. The maximal barriers of a matching covered graph + partitons its vertex set and the partition of the vertex set of a + matching covered graph into its maximal barriers is called as its + *canonical* *partition*. + + OUTPUT: + + - A list of sets that constitute a (canonical) partition of the vertex + set, wherein each set is a (unique) maximal barrier of the (matching + covered) graph. + + EXAMPLES: + + Show the maximal barrier of the graph `K_4 \odot K_{3, 3}`:: + + sage: G = Graph([ + ....: (0, 2), (0, 3), (0, 4), (1, 2), + ....: (1, 3), (1, 4), (2, 5), (3, 6), + ....: (4, 7), (5, 6), (5, 7), (6, 7) + ....: ]) + sage: H = MatchingCoveredGraph(G) + sage: H.canonical_partition() + [{0}, {1}, {2, 3, 4}, {5}, {6}, {7}] + + For a bicritical graph (for instance, the Petersen graph), the + canonical parition constitutes of only singleton sets each containing + an individual vertex:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: G.canonical_partition() + [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}] + + For a bipartite matching covered graph (for instance, the Hexahedral + graph), the canonical partition consists of two sets each of which + corresponds to the individual color class:: + + sage: H = graphs.HexahedralGraph() + sage: G = MatchingCoveredGraph(H) + sage: G.canonical_partition() + [{0, 2, 5, 7}, {1, 3, 4, 6}] + sage: B = BipartiteGraph(H) + sage: list(B.bipartition()) == G.canonical_partition() + True + + REFERENCES: + + - [LM2024]_ + + .. SEEALSO:: + + - :meth:`~sage.graphs.graph.Graph.is_bicritical` + - :meth:`~sage.graphs.graph.Graph.is_matching_covered` + - :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.maximal_barrier` + """ + visited = set() + + maximal_barriers = [] + for v in self: + if v not in visited: + B = self.maximal_barrier(v) + for u in B: + visited.add(u) + maximal_barriers.append(B) + + return sorted(maximal_barriers, key=lambda s: min(s)) + @doc_index('Overwritten methods') def delete_vertex(self, vertex, in_order=False): r""" From 9c532c5fcdbc2820d191887fa77bdb4477fcba2d Mon Sep 17 00:00:00 2001 From: maple3142 Date: Tue, 5 Nov 2024 01:45:32 +0800 Subject: [PATCH 028/210] Add special case to Matrix_mod2_dense solve_right --- src/sage/matrix/matrix_mod2_dense.pyx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_mod2_dense.pyx b/src/sage/matrix/matrix_mod2_dense.pyx index 0bdbd4d11d2..055359e6fd0 100644 --- a/src/sage/matrix/matrix_mod2_dense.pyx +++ b/src/sage/matrix/matrix_mod2_dense.pyx @@ -1957,6 +1957,16 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse sage: B = A * random_vector(GF(2), m) sage: A * A.solve_right(B) == B True + sage: matrix(GF(2), 2, 0).solve_right(matrix(GF(2), 2, 2)) == matrix(GF(2), 0, 2) + True + sage: matrix(GF(2), 2, 0).solve_right(matrix(GF(2), 2, 2) + 1) + Traceback (most recent call last): + ... + ValueError: matrix equation has no solutions + sage: matrix(GF(2), 2, 0).solve_right(matrix(GF(2), 2, 2) + 1, check=False) == matrix(GF(2), 0, 2) + True + sage: matrix(GF(2), 2, 2).solve_right(matrix(GF(2), 2, 0)) == matrix(GF(2), 2, 0) + True """ cdef mzd_t *B_entries = (B)._entries @@ -1964,7 +1974,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse X = self.new_matrix(nrows=self._entries.ncols, ncols=B_entries.ncols) if self._entries.ncols == 0 or B_entries.ncols == 0: # special case: empty matrix - if B != 0: + if check and B != 0: raise ValueError("matrix equation has no solutions") return X cdef rci_t rows = self._entries.nrows From 09548b0232e63cf44c2935f3eba0e209d493dc27 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 06:11:42 +0530 Subject: [PATCH 029/210] updated the TODO list --- src/sage/graphs/matching_covered_graph.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index c921277f021..5439851976b 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -32,11 +32,6 @@ - ``delete_edge()`` | Delete the edge from ``u`` to ``v``. - ``delete_edges()`` | Delete edges from an iterable container. - Barriers and canonical partition: - - - ``canonical_partition()`` | Return the canonical partition of the - (matching covered) graph. - Bricks, braces and tight cut decomposition: - ``bricks_and_braces()`` | Return the list of (underlying simple graph of) From 3663de5ec49fbfa67652ffb1cdf8f3876009a33e Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 06:12:15 +0530 Subject: [PATCH 030/210] corrected a typo --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 5439851976b..7da2c41597d 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1550,7 +1550,7 @@ def canonical_partition(self): Note that in a matching covered graph, each vertex belongs to a unique maximal barrier. The maximal barriers of a matching covered graph - partitons its vertex set and the partition of the vertex set of a + partitions its vertex set and the partition of the vertex set of a matching covered graph into its maximal barriers is called as its *canonical* *partition*. From 6b7daf9affa7cf3e85be021ff154c914ef3b233f Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 06:13:58 +0530 Subject: [PATCH 031/210] updated the code of canonical_partition() --- src/sage/graphs/matching_covered_graph.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 7da2c41597d..d0207efdce5 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1610,11 +1610,10 @@ def canonical_partition(self): for v in self: if v not in visited: B = self.maximal_barrier(v) - for u in B: - visited.add(u) + visited.update(B) maximal_barriers.append(B) - return sorted(maximal_barriers, key=lambda s: min(s)) + return maximal_barriers @doc_index('Overwritten methods') def delete_vertex(self, vertex, in_order=False): From f3a37062a265271bbbb8900637fa22632c68ebb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 12:05:16 +0100 Subject: [PATCH 032/210] moving "is_integrally_closed" to the category setup. --- src/sage/categories/fields.py | 11 ++++--- src/sage/categories/integral_domains.py | 19 +++++++++++ src/sage/categories/rings.py | 22 +++++++++++++ src/sage/rings/integer_ring.pyx | 16 --------- src/sage/rings/number_field/order.py | 6 ++-- src/sage/rings/ring.pyx | 43 ------------------------- 6 files changed, 52 insertions(+), 65 deletions(-) diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index e1f5c3d68f6..98251904607 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -206,11 +206,12 @@ def is_field(self, proof=True): """ return True - def is_integrally_closed(self): + def is_integrally_closed(self) -> bool: r""" - Return ``True``, as per :meth:`IntegralDomain.is_integrally_closed`: - for every field `F`, `F` is its own field of fractions, - hence every element of `F` is integral over `F`. + Return whether ``self`` is integrally closed. + + For every field `F`, `F` is its own field of fractions. + Therefore every element of `F` is integral over `F`. EXAMPLES:: @@ -222,6 +223,8 @@ def is_integrally_closed(self): Finite Field of size 5 sage: Z5.is_integrally_closed() True + sage: Frac(ZZ['x,y']).is_integrally_closed() + True """ return True diff --git a/src/sage/categories/integral_domains.py b/src/sage/categories/integral_domains.py index 173a14cf25f..1a051fcd350 100644 --- a/src/sage/categories/integral_domains.py +++ b/src/sage/categories/integral_domains.py @@ -1,6 +1,25 @@ # sage_setup: distribution = sagemath-categories r""" Integral domains + +TEST: + +A few doctest for the method ``is_integrally_closed``:: + + sage: ZZ.is_integrally_closed() + True + sage: QQ.is_integrally_closed() + True + sage: QQbar.is_integrally_closed() # needs sage.rings.number_field + True + sage: GF(5).is_integrally_closed() + True + sage: Z5 = Integers(5); Z5 + Ring of integers modulo 5 + sage: Z5.is_integrally_closed() + False + +Note that this returns ``False`` is the answer is not known. """ # **************************************************************************** # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 8db71edfb9c..2f483fb76a4 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -423,6 +423,28 @@ def is_integral_domain(self, proof=True) -> bool: return False + def is_integrally_closed(self) -> bool: + r""" + Return whether this ring is integrally closed. + + This is the default implementation that returns ``False``. + + EXAMPLES:: + + sage: x = polygen(ZZ, 'x') + sage: K. = NumberField(x^2 + 189*x + 394) + sage: R = K.order(2*a) + sage: R.is_integrally_closed() + False + sage: R + Order of conductor 2 generated by 2*a in Number Field in a with defining polynomial x^2 + 189*x + 394 + sage: S = K.maximal_order(); S + Maximal Order generated by a in Number Field in a with defining polynomial x^2 + 189*x + 394 + sage: S.is_integrally_closed() + True + """ + return False + def is_noetherian(self): """ Return ``True`` if this ring is Noetherian. diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index 2b2ec33294c..67bcf61c3a8 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -1142,22 +1142,6 @@ cdef class IntegerRing_class(CommutativeRing): """ return 1 - def is_integrally_closed(self): - """ - Return that the integer ring is, in fact, integrally closed. - - .. NOTE:: - - This should rather be inherited from the category - of ``DedekindDomains``. - - EXAMPLES:: - - sage: ZZ.is_integrally_closed() - True - """ - return True - def completion(self, p, prec, extras = {}): r""" Return the metric completion of the integers at the prime `p`. diff --git a/src/sage/rings/number_field/order.py b/src/sage/rings/number_field/order.py index 9dee6a8a481..fd5662048df 100644 --- a/src/sage/rings/number_field/order.py +++ b/src/sage/rings/number_field/order.py @@ -631,9 +631,11 @@ def is_noetherian(self): """ return True - def is_integrally_closed(self): + def is_integrally_closed(self) -> bool: r""" - Return ``True`` if this ring is integrally closed, i.e., is equal + Return whether this ring is integrally closed. + + This is true if and only if it is equal to the maximal order. EXAMPLES:: diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index f92aa7c0d27..0aa79a5f80a 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -1018,37 +1018,6 @@ cdef class IntegralDomain(CommutativeRing): CommutativeRing.__init__(self, base_ring, names=names, normalize=normalize, category=category) - def is_integrally_closed(self): - r""" - Return ``True`` if this ring is integrally closed in its field of - fractions; otherwise return ``False``. - - When no algorithm is implemented for this, then this - function raises a :exc:`NotImplementedError`. - - Note that ``is_integrally_closed`` has a naive implementation - in fields. For every field `F`, `F` is its own field of fractions, - hence every element of `F` is integral over `F`. - - EXAMPLES:: - - sage: ZZ.is_integrally_closed() - True - sage: QQ.is_integrally_closed() - True - sage: QQbar.is_integrally_closed() # needs sage.rings.number_field - True - sage: GF(5).is_integrally_closed() - True - sage: Z5 = Integers(5); Z5 - Ring of integers modulo 5 - sage: Z5.is_integrally_closed() - Traceback (most recent call last): - ... - AttributeError: 'IntegerModRing_generic_with_category' object has no attribute 'is_integrally_closed'... - """ - raise NotImplementedError - def is_field(self, proof=True): r""" Return ``True`` if this ring is a field. @@ -1228,18 +1197,6 @@ cdef class Field(CommutativeRing): """ return True - def is_integrally_closed(self): - """ - Return ``True`` since fields are trivially integrally closed in - their fraction field (since they are their own fraction field). - - EXAMPLES:: - - sage: Frac(ZZ['x,y']).is_integrally_closed() - True - """ - return True - def krull_dimension(self): """ Return the Krull dimension of this field, which is 0. From 72cf71003ed49c44a4fd3cf746413bb24530350d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 13:27:20 +0100 Subject: [PATCH 033/210] fix doctest --- src/doc/en/thematic_tutorials/coercion_and_categories.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index 5e9fcf77db6..5eeddc3a7f6 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -132,7 +132,6 @@ This base class provides a lot more methods than a general parent:: 'integral_closure', 'is_commutative', 'is_field', - 'is_integrally_closed', 'krull_dimension', 'localization', 'ngens', From 0f19b618359e77906efd16336fe18cea2ca6c039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 13:30:23 +0100 Subject: [PATCH 034/210] doc details --- src/sage/categories/integral_domains.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/categories/integral_domains.py b/src/sage/categories/integral_domains.py index 1a051fcd350..c76f9f0ca00 100644 --- a/src/sage/categories/integral_domains.py +++ b/src/sage/categories/integral_domains.py @@ -4,7 +4,7 @@ TEST: -A few doctest for the method ``is_integrally_closed``:: +A few tests for the method ``is_integrally_closed``:: sage: ZZ.is_integrally_closed() True @@ -19,7 +19,7 @@ sage: Z5.is_integrally_closed() False -Note that this returns ``False`` is the answer is not known. +Note that this returns ``False`` if the answer is not known. """ # **************************************************************************** # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) From 1d02dbfa8a54b9273c4a2813b793d0db405d69b1 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 20:58:49 +0530 Subject: [PATCH 035/210] updated maximal_barrier() --- src/sage/graphs/matching_covered_graph.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index d0207efdce5..77de3fa6976 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2033,12 +2033,9 @@ def maximal_barrier(self, vertex): if vertex not in self: raise ValueError('vertex {} not in the graph'.format(vertex)) - G = Graph(self, multiedges=False) - M = Graph(self.get_matching()) - B = set([vertex]) - # u: The M neighbor of vertex - u = next(M.neighbor_iterator(vertex)) + matching = self.get_matching() + u = next((a if b == vertex else b) for a, b, *_ in matching if vertex in [a, b]) # Goal: Find the vertices w such that G - w - vertex is matchable. # In other words, there exists an odd length M-alternating vertex-w @@ -2048,9 +2045,11 @@ def maximal_barrier(self, vertex): # even: The set of all such vertex w from sage.graphs.matching import M_alternating_even_mark - even = M_alternating_even_mark(G=G, matching=M, vertex=u) + even = M_alternating_even_mark(G=self, matching=matching, + vertex=u) - B.update(v for v in G if v not in even) + B = set([vertex]) + B.update(v for v in self if v not in even) return B From 7816d7a6b81ef291e6d3df25965eba4557f555b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 19:38:28 +0100 Subject: [PATCH 036/210] change the default to NotImplementedError --- src/sage/categories/integral_domains.py | 6 ++++-- src/sage/categories/rings.py | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sage/categories/integral_domains.py b/src/sage/categories/integral_domains.py index c76f9f0ca00..4dd66a9277b 100644 --- a/src/sage/categories/integral_domains.py +++ b/src/sage/categories/integral_domains.py @@ -17,9 +17,11 @@ sage: Z5 = Integers(5); Z5 Ring of integers modulo 5 sage: Z5.is_integrally_closed() - False + Traceback (most recent call last): + ... + NotImplementedError -Note that this returns ``False`` if the answer is not known. +Note that this raises a :exc:`NotImplementedError` if the answer is not known. """ # **************************************************************************** # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 2f483fb76a4..77894634f99 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -427,7 +427,8 @@ def is_integrally_closed(self) -> bool: r""" Return whether this ring is integrally closed. - This is the default implementation that returns ``False``. + This is the default implementation that + raises a :exc:`NotImplementedError`. EXAMPLES:: @@ -443,7 +444,7 @@ def is_integrally_closed(self) -> bool: sage: S.is_integrally_closed() True """ - return False + raise NotImplementedError def is_noetherian(self): """ From baecf8cfe833aff051aca9a49cbe7d38e1716915 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 7 Nov 2024 11:14:23 -0500 Subject: [PATCH 037/210] src/sage/env.py: don't pass if mismatched SAGE_ROOT is None MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this file we test that SAGE_ROOT in a subprocess is the same as SAGE_ROOT in the parent. There is a special case for when SAGE_ROOT is None, but that special case can pass if only one of the SAGE_ROOT variables is None and the other is not -- contrary to the intent of the test. Here we extend the special case to ensure that both SAGE_ROOT variables are None if one of them is. Thanks to Gonzalo Tornaría for the suggestion. --- src/sage/env.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sage/env.py b/src/sage/env.py index 2be366c6f3e..84dbcf086f3 100644 --- a/src/sage/env.py +++ b/src/sage/env.py @@ -2,16 +2,21 @@ r""" Sage Runtime Environment -Verify that importing ``sage.all`` works in Sage's Python without any ``SAGE_`` -environment variables, and has the same ``SAGE_ROOT`` and ``SAGE_LOCAL`` -(see also :issue:`29446`):: +Verify that importing ``sage.all`` works in Sage's Python without any +``SAGE_`` environment variables, and has the same ``SAGE_ROOT`` and +``SAGE_LOCAL`` (see also :issue:`29446`). If ``SAGE_ROOT`` is a path, +we normalize it, but keep in mind that ``SAGE_ROOT`` may also be +``None``:: sage: env = {k:v for (k,v) in os.environ.items() if not k.startswith("SAGE_")} sage: from subprocess import check_output sage: module_name = "sage.all" # hide .all import from the linter sage: cmd = f"from {module_name} import SAGE_ROOT, SAGE_LOCAL;" sage: cmd += "from os.path import samefile;" - sage: cmd += f"s1 = samefile(SAGE_ROOT, '{SAGE_ROOT}') if SAGE_ROOT else True;" + sage: if SAGE_ROOT is None: + ....: cmd += "s1 = SAGE_ROOT is None;" + ....: else: + ....: cmd += f"s1 = samefile(SAGE_ROOT, '{SAGE_ROOT}');" sage: cmd += f"s2 = samefile(SAGE_LOCAL, '{SAGE_LOCAL}');" sage: cmd += "print(s1 and s2);" sage: out = check_output([sys.executable, "-c", cmd], env=env).decode().strip() # long time From 3afc01149296f560432a96ce359743e9b66cd3ca Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:49:23 +0700 Subject: [PATCH 038/210] Fast conversion from numpy ndarray to vector --- src/sage/modules/vector_mod2_dense.pyx | 58 ++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/sage/modules/vector_mod2_dense.pyx b/src/sage/modules/vector_mod2_dense.pyx index 35286c51457..263123cdec9 100644 --- a/src/sage/modules/vector_mod2_dense.pyx +++ b/src/sage/modules/vector_mod2_dense.pyx @@ -40,6 +40,8 @@ TESTS:: # https://www.gnu.org/licenses/ # **************************************************************************** +cimport numpy as np + from sage.rings.finite_rings.integer_mod cimport IntegerMod_int, IntegerMod_abstract from sage.rings.integer cimport Integer from sage.rings.rational cimport Rational @@ -49,6 +51,21 @@ cimport sage.modules.free_module_element as free_module_element from sage.libs.m4ri cimport * + +ctypedef fused numpy_integral: + np.int8_t + np.int32_t + np.int64_t + + +cdef _set_from_numpy_unsafe(mzd_t* entries, np.ndarray[numpy_integral, ndim=1] x): + """ + Internal function. Caller are responsible for checking the two arrays have the same length. + """ + for i in range(len(x)): + mzd_write_bit(entries, 0, i, x[i] & 1) + + cdef class Vector_mod2_dense(free_module_element.FreeModuleElement): cdef _new_c(self): """ @@ -192,8 +209,49 @@ cdef class Vector_mod2_dense(free_module_element.FreeModuleElement): TypeError: can...t initialize vector from nonzero non-list sage: (GF(2)**0).zero_vector() () + + Check construction from numpy arrays:: + + sage: # needs numpy + sage: import numpy + sage: VS = VectorSpace(GF(2),3) + sage: VS(numpy.array([0,-3,7], dtype=numpy.int8)) + (0, 1, 1) + sage: VS(numpy.array([0,-3,7], dtype=numpy.int32)) + (0, 1, 1) + sage: VS(numpy.array([0,-3,7], dtype=numpy.int64)) + (0, 1, 1) + sage: VS(numpy.array([False,True,False], dtype=bool)) + (0, 1, 0) """ cdef Py_ssize_t i + cdef np.ndarray[np.npy_bool, ndim=1] x_bool + try: + import numpy + except ImportError: + pass + else: + if isinstance(x, np.ndarray): + if x.ndim != 1: + raise TypeError("numpy array must have dimension 1") + if x.shape[0] != self._degree: + raise TypeError("numpy array must have the right length") + if x.dtype == numpy.int8: + _set_from_numpy_unsafe(self._entries, x) + return + if x.dtype == numpy.int32: + _set_from_numpy_unsafe(self._entries, x) + return + if x.dtype == numpy.int64: + _set_from_numpy_unsafe(self._entries, x) + return + if x.dtype == numpy.bool_: + x_bool = x + for i in range(self._degree): + mzd_write_bit(self._entries, 0, i, x_bool[i]) + return + # inefficient fallback + x = x.tolist() if isinstance(x, (list, tuple)): if len(x) != self._degree: raise TypeError("x must be a list of the right length") From 90053d4889e6a560c5bb473a7dddb3d3a91011a5 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:03:14 +0700 Subject: [PATCH 039/210] Move all numpy-related functions to numpy_util and lazy import --- src/sage/modules/numpy_util.pyx | 65 ++++++++++++++++++++++++++ src/sage/modules/vector_mod2_dense.pyx | 57 +++++++--------------- 2 files changed, 82 insertions(+), 40 deletions(-) create mode 100644 src/sage/modules/numpy_util.pyx diff --git a/src/sage/modules/numpy_util.pyx b/src/sage/modules/numpy_util.pyx new file mode 100644 index 00000000000..1b1384205ca --- /dev/null +++ b/src/sage/modules/numpy_util.pyx @@ -0,0 +1,65 @@ +# sage.doctest: optional - numpy +r""" +Utility functions for numpy. +""" + +cimport numpy as np +import numpy as np +from sage.libs.m4ri cimport * +from libc.stdint cimport uintptr_t + + +ctypedef fused numpy_integral: + np.int8_t + np.int32_t + np.int64_t + + +cdef set_mzd_from_numpy_unsafe(mzd_t* entries, np.ndarray[numpy_integral, ndim=1] x): + """ + Internal function. + Caller are responsible for checking the two arrays have the same length. + """ + for i in range(len(x)): + mzd_write_bit(entries, 0, i, x[i] & 1) + + +def set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x): + """ + Set the entries in ``entries`` from numpy array ``x``. + + INPUT: + + - ``entries_addr`` -- must be a ``mzd_t*`` casted to ``uintptr_t``; the casting + is necessary to pass it through Python boundary because of lazy import + + - ``degree`` -- the length of the array + + - ``x`` -- a numpy array of integers or booleans, or any other object (in which + case this function will return ``False``) + + OUTPUT: ``True`` if successful, ``False`` otherwise. May throw ``ValueError``. + """ + cdef Py_ssize_t i + cdef np.ndarray[np.npy_bool, ndim=1] x_bool + cdef mzd_t* entries = entries_addr + if isinstance(x, np.ndarray): + if x.ndim != 1: + raise ValueError("numpy array must have dimension 1") + if x.shape[0] != degree: + raise ValueError("numpy array must have the right length") + if x.dtype == np.int8: + set_mzd_from_numpy_unsafe(entries, x) + return True + if x.dtype == np.int32: + set_mzd_from_numpy_unsafe(entries, x) + return True + if x.dtype == np.int64: + set_mzd_from_numpy_unsafe(entries, x) + return True + if x.dtype == np.bool_: + x_bool = x + for i in range(degree): + mzd_write_bit(entries, 0, i, x_bool[i]) + return True + return False diff --git a/src/sage/modules/vector_mod2_dense.pyx b/src/sage/modules/vector_mod2_dense.pyx index 263123cdec9..f73d35c1a8b 100644 --- a/src/sage/modules/vector_mod2_dense.pyx +++ b/src/sage/modules/vector_mod2_dense.pyx @@ -40,32 +40,16 @@ TESTS:: # https://www.gnu.org/licenses/ # **************************************************************************** -cimport numpy as np - from sage.rings.finite_rings.integer_mod cimport IntegerMod_int, IntegerMod_abstract from sage.rings.integer cimport Integer from sage.rings.rational cimport Rational from sage.structure.element cimport Element, Vector from sage.structure.richcmp cimport rich_to_bool cimport sage.modules.free_module_element as free_module_element +from libc.stdint cimport uintptr_t from sage.libs.m4ri cimport * - -ctypedef fused numpy_integral: - np.int8_t - np.int32_t - np.int64_t - - -cdef _set_from_numpy_unsafe(mzd_t* entries, np.ndarray[numpy_integral, ndim=1] x): - """ - Internal function. Caller are responsible for checking the two arrays have the same length. - """ - for i in range(len(x)): - mzd_write_bit(entries, 0, i, x[i] & 1) - - cdef class Vector_mod2_dense(free_module_element.FreeModuleElement): cdef _new_c(self): """ @@ -223,35 +207,28 @@ cdef class Vector_mod2_dense(free_module_element.FreeModuleElement): (0, 1, 1) sage: VS(numpy.array([False,True,False], dtype=bool)) (0, 1, 0) + sage: VS(numpy.array([[1]])) + Traceback (most recent call last): + ... + ValueError: numpy array must have dimension 1 + sage: VS(numpy.array([1,2,3,4])) + Traceback (most recent call last): + ... + ValueError: numpy array must have the right length + + Make sure it's reasonably fast:: + + sage: VS = VectorSpace(GF(2),2*10^7) + sage: v = VS(numpy.random.randint(0, 1, size=VS.dimension())) # around 300ms """ - cdef Py_ssize_t i - cdef np.ndarray[np.npy_bool, ndim=1] x_bool try: import numpy except ImportError: pass else: - if isinstance(x, np.ndarray): - if x.ndim != 1: - raise TypeError("numpy array must have dimension 1") - if x.shape[0] != self._degree: - raise TypeError("numpy array must have the right length") - if x.dtype == numpy.int8: - _set_from_numpy_unsafe(self._entries, x) - return - if x.dtype == numpy.int32: - _set_from_numpy_unsafe(self._entries, x) - return - if x.dtype == numpy.int64: - _set_from_numpy_unsafe(self._entries, x) - return - if x.dtype == numpy.bool_: - x_bool = x - for i in range(self._degree): - mzd_write_bit(self._entries, 0, i, x_bool[i]) - return - # inefficient fallback - x = x.tolist() + from .numpy_util import set_mzd_from_numpy + if set_mzd_from_numpy(self._entries, self._degree, x): + return if isinstance(x, (list, tuple)): if len(x) != self._degree: raise TypeError("x must be a list of the right length") From 0c3b5ddd2afb262d97b36fb8a2a18699b51b07ea Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 15:06:29 +0700 Subject: [PATCH 040/210] Fix warning on test --- src/sage/modules/vector_mod2_dense.pyx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/modules/vector_mod2_dense.pyx b/src/sage/modules/vector_mod2_dense.pyx index f73d35c1a8b..cac2785d4c7 100644 --- a/src/sage/modules/vector_mod2_dense.pyx +++ b/src/sage/modules/vector_mod2_dense.pyx @@ -218,6 +218,8 @@ cdef class Vector_mod2_dense(free_module_element.FreeModuleElement): Make sure it's reasonably fast:: + sage: # needs numpy + sage: import numpy sage: VS = VectorSpace(GF(2),2*10^7) sage: v = VS(numpy.random.randint(0, 1, size=VS.dimension())) # around 300ms """ From 5b2e5e330514fadd7b3885de70c8fbdcf87ff619 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 15:10:31 +0700 Subject: [PATCH 041/210] Fix test situation where numpy is available but numpy_util is not --- src/sage/modules/vector_mod2_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modules/vector_mod2_dense.pyx b/src/sage/modules/vector_mod2_dense.pyx index cac2785d4c7..a998597b23e 100644 --- a/src/sage/modules/vector_mod2_dense.pyx +++ b/src/sage/modules/vector_mod2_dense.pyx @@ -225,10 +225,10 @@ cdef class Vector_mod2_dense(free_module_element.FreeModuleElement): """ try: import numpy + from .numpy_util import set_mzd_from_numpy except ImportError: pass else: - from .numpy_util import set_mzd_from_numpy if set_mzd_from_numpy(self._entries, self._degree, x): return if isinstance(x, (list, tuple)): From 1ca7846734c9c391cbadcfdf576b1da7f7d2183f Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 19:02:14 +0700 Subject: [PATCH 042/210] Try to add pxd file, see if it works --- src/sage/modules/numpy_util.pxd | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/sage/modules/numpy_util.pxd diff --git a/src/sage/modules/numpy_util.pxd b/src/sage/modules/numpy_util.pxd new file mode 100644 index 00000000000..e69de29bb2d From daecebaf05d6c7b207b6a0918f86784724f2ad7b Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 19:49:45 +0700 Subject: [PATCH 043/210] Revert "Fix test situation where numpy is available but numpy_util is not" This reverts commit 5b2e5e330514fadd7b3885de70c8fbdcf87ff619. --- src/sage/modules/vector_mod2_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modules/vector_mod2_dense.pyx b/src/sage/modules/vector_mod2_dense.pyx index a998597b23e..cac2785d4c7 100644 --- a/src/sage/modules/vector_mod2_dense.pyx +++ b/src/sage/modules/vector_mod2_dense.pyx @@ -225,10 +225,10 @@ cdef class Vector_mod2_dense(free_module_element.FreeModuleElement): """ try: import numpy - from .numpy_util import set_mzd_from_numpy except ImportError: pass else: + from .numpy_util import set_mzd_from_numpy if set_mzd_from_numpy(self._entries, self._degree, x): return if isinstance(x, (list, tuple)): From 2e8ad27a850a49134d031f83f10d34aeaf6b07a8 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 19:50:39 +0700 Subject: [PATCH 044/210] Try to add the function signature to pxd file --- src/sage/modules/numpy_util.pxd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sage/modules/numpy_util.pxd b/src/sage/modules/numpy_util.pxd index e69de29bb2d..03272f62bba 100644 --- a/src/sage/modules/numpy_util.pxd +++ b/src/sage/modules/numpy_util.pxd @@ -0,0 +1,4 @@ +from libc.stdint cimport uintptr_t +from sage.libs.m4ri cimport * + +def set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) From f9448cac31859078e26abe6bae9bf0b223f6d661 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 19:53:41 +0700 Subject: [PATCH 045/210] Fix build --- src/sage/modules/numpy_util.pxd | 2 +- src/sage/modules/numpy_util.pyx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/modules/numpy_util.pxd b/src/sage/modules/numpy_util.pxd index 03272f62bba..e090a25d304 100644 --- a/src/sage/modules/numpy_util.pxd +++ b/src/sage/modules/numpy_util.pxd @@ -1,4 +1,4 @@ from libc.stdint cimport uintptr_t from sage.libs.m4ri cimport * -def set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) +cpdef int set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) except -1 diff --git a/src/sage/modules/numpy_util.pyx b/src/sage/modules/numpy_util.pyx index 1b1384205ca..d670abc4eed 100644 --- a/src/sage/modules/numpy_util.pyx +++ b/src/sage/modules/numpy_util.pyx @@ -24,7 +24,7 @@ cdef set_mzd_from_numpy_unsafe(mzd_t* entries, np.ndarray[numpy_integral, ndim=1 mzd_write_bit(entries, 0, i, x[i] & 1) -def set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x): +cpdef int set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) except -1: """ Set the entries in ``entries`` from numpy array ``x``. From 49e7c14d6483fedb733a3ed74126c194c03cfc0f Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 20:19:44 +0700 Subject: [PATCH 046/210] Rollback to 0c3b5ddd2afb262d97b36fb8a2a18699b51b07ea --- src/sage/modules/numpy_util.pxd | 4 ---- src/sage/modules/numpy_util.pyx | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 100644 src/sage/modules/numpy_util.pxd diff --git a/src/sage/modules/numpy_util.pxd b/src/sage/modules/numpy_util.pxd deleted file mode 100644 index e090a25d304..00000000000 --- a/src/sage/modules/numpy_util.pxd +++ /dev/null @@ -1,4 +0,0 @@ -from libc.stdint cimport uintptr_t -from sage.libs.m4ri cimport * - -cpdef int set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) except -1 diff --git a/src/sage/modules/numpy_util.pyx b/src/sage/modules/numpy_util.pyx index d670abc4eed..1b1384205ca 100644 --- a/src/sage/modules/numpy_util.pyx +++ b/src/sage/modules/numpy_util.pyx @@ -24,7 +24,7 @@ cdef set_mzd_from_numpy_unsafe(mzd_t* entries, np.ndarray[numpy_integral, ndim=1 mzd_write_bit(entries, 0, i, x[i] & 1) -cpdef int set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) except -1: +def set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x): """ Set the entries in ``entries`` from numpy array ``x``. From 915ace93f3772b939f576361135df7a3b3bc98d7 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 20:23:01 +0700 Subject: [PATCH 047/210] Actually fix meson build (hopefully) --- src/sage/modules/meson.build | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/modules/meson.build b/src/sage/modules/meson.build index bc505da9372..48aecfdf0f2 100644 --- a/src/sage/modules/meson.build +++ b/src/sage/modules/meson.build @@ -76,7 +76,10 @@ foreach name, pyx : extension_data ) endforeach -extension_data_cpp = {'vector_mod2_dense': files('vector_mod2_dense.pyx')} +extension_data_cpp = { + 'numpy_util' : files('numpy_util.pyx'), + 'vector_mod2_dense': files('vector_mod2_dense.pyx'), +} foreach name, pyx : extension_data_cpp py.extension_module( From 1830861c5130d30b891e8c643308e1ceb91ce2b5 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 21:19:38 +0700 Subject: [PATCH 048/210] Fix flaky simplicial set test --- src/sage/categories/simplicial_sets.py | 32 +++++++++++++++----------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/sage/categories/simplicial_sets.py b/src/sage/categories/simplicial_sets.py index 65e526d8688..05e9bc221c1 100644 --- a/src/sage/categories/simplicial_sets.py +++ b/src/sage/categories/simplicial_sets.py @@ -444,29 +444,31 @@ def covering_map(self, character): sage: # needs sage.graphs sage.groups sage: S1 = simplicial_sets.Sphere(1) - sage: W = S1.wedge(S1) + sage: S1_ = simplicial_sets.Sphere(1) + sage: S1_.n_cells(1)[0].rename("sigma_1'") + sage: W = S1.wedge(S1_) sage: G = CyclicPermutationGroup(3) sage: a, b = W.n_cells(1) sage: C = W.covering_map({a : G.gen(0), b : G.one()}); C Simplicial set morphism: From: Simplicial set with 9 non-degenerate simplices To: Wedge: (S^1 v S^1) - Defn: [(*, ()), (*, (1,2,3)), (*, (1,3,2)), (sigma_1, ()), - (sigma_1, ()), (sigma_1, (1,2,3)), (sigma_1, (1,2,3)), - (sigma_1, (1,3,2)), (sigma_1, (1,3,2))] - --> [*, *, *, sigma_1, sigma_1, sigma_1, sigma_1, sigma_1, sigma_1] + Defn: [(*, ()), (*, (1,2,3)), (*, (1,3,2)), (sigma_1', ()), + (sigma_1', (1,2,3)), (sigma_1', (1,3,2)), (sigma_1, ()), + (sigma_1, (1,2,3)), (sigma_1, (1,3,2))] + --> [*, *, *, sigma_1', sigma_1', sigma_1', sigma_1, sigma_1, sigma_1] sage: C.domain() Simplicial set with 9 non-degenerate simplices sage: C.domain().face_data() {(*, ()): None, (*, (1,2,3)): None, (*, (1,3,2)): None, + (sigma_1', ()): ((*, ()), (*, ())), + (sigma_1', (1,2,3)): ((*, (1,2,3)), (*, (1,2,3))), + (sigma_1', (1,3,2)): ((*, (1,3,2)), (*, (1,3,2))), (sigma_1, ()): ((*, (1,2,3)), (*, ())), - (sigma_1, ()): ((*, ()), (*, ())), (sigma_1, (1,2,3)): ((*, (1,3,2)), (*, (1,2,3))), - (sigma_1, (1,2,3)): ((*, (1,2,3)), (*, (1,2,3))), - (sigma_1, (1,3,2)): ((*, ()), (*, (1,3,2))), - (sigma_1, (1,3,2)): ((*, (1,3,2)), (*, (1,3,2)))} + (sigma_1, (1,3,2)): ((*, ()), (*, (1,3,2)))} """ from sage.topology.simplicial_set import AbstractSimplex, SimplicialSet from sage.topology.simplicial_set_morphism import SimplicialSetMorphism @@ -531,7 +533,9 @@ def cover(self, character): sage: # needs sage.graphs sage.groups sage: S1 = simplicial_sets.Sphere(1) - sage: W = S1.wedge(S1) + sage: S1_ = simplicial_sets.Sphere(1) + sage: S1_.n_cells(1)[0].rename("sigma_1'") + sage: W = S1.wedge(S1_) sage: G = CyclicPermutationGroup(3) sage: (a, b) = W.n_cells(1) sage: C = W.cover({a : G.gen(0), b : G.gen(0)^2}) @@ -539,12 +543,12 @@ def cover(self, character): {(*, ()): None, (*, (1,2,3)): None, (*, (1,3,2)): None, + (sigma_1', ()): ((*, (1,3,2)), (*, ())), + (sigma_1', (1,2,3)): ((*, ()), (*, (1,2,3))), + (sigma_1', (1,3,2)): ((*, (1,2,3)), (*, (1,3,2))), (sigma_1, ()): ((*, (1,2,3)), (*, ())), - (sigma_1, ()): ((*, (1,3,2)), (*, ())), (sigma_1, (1,2,3)): ((*, (1,3,2)), (*, (1,2,3))), - (sigma_1, (1,2,3)): ((*, ()), (*, (1,2,3))), - (sigma_1, (1,3,2)): ((*, ()), (*, (1,3,2))), - (sigma_1, (1,3,2)): ((*, (1,2,3)), (*, (1,3,2)))} + (sigma_1, (1,3,2)): ((*, ()), (*, (1,3,2)))} sage: C.homology(1) # needs sage.modules Z x Z x Z x Z sage: C.fundamental_group() From ed00e968934c0403a3654f9010b433aa3803d433 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sat, 9 Nov 2024 17:58:48 +0700 Subject: [PATCH 049/210] Allow specifying arguments to Cython cell_magic --- src/sage/repl/ipython_extension.py | 79 ++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index b6fc42bbb37..afb6d92dc77 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -342,7 +342,7 @@ def cython(self, line, cell): INPUT: - - ``line`` -- ignored + - ``line`` -- parsed as keyword arguments. See :func:`~sage.misc.cython.cython` for details. - ``cell`` -- string; the Cython source code to process @@ -350,19 +350,88 @@ def cython(self, line, cell): EXAMPLES:: + sage: # needs sage.misc.cython sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() - sage: shell.run_cell( # needs sage.misc.cython + sage: shell.run_cell( ....: ''' - ....: %%cython + ....: %%cython -v1 --annotate --no-sage-namespace ....: def f(): ....: print('test') ....: ''') - sage: f() # needs sage.misc.cython + Compiling ....pyx because it changed. + [1/1] Cythonizing ....pyx + sage: f() test + + TESTS: + + See :mod:`sage.repl.interpreter` for explanation of the dummy line. + + Test unrecognized arguments:: + + sage: # needs sage.misc.cython + sage: print("dummy line"); shell.run_cell(''' + ....: %%cython --some-unrecognized-argument + ....: print(1) + ....: ''') + dummy line + ... + ArgumentError...Traceback (most recent call last) + ... + ArgumentError: unrecognized arguments: --some-unrecognized-argument + + Test ``--help`` is disabled:: + + sage: # needs sage.misc.cython + sage: print("dummy line"); shell.run_cell(''' + ....: %%cython --help + ....: print(1) + ....: ''') + dummy line + ... + ArgumentError...Traceback (most recent call last) + ... + ArgumentError: unrecognized arguments: --help + + Test invalid quotes:: + + sage: # needs sage.misc.cython + sage: print("dummy line"); shell.run_cell(''' + ....: %%cython --a=' + ....: print(1) + ....: ''') + dummy line + ... + ValueError...Traceback (most recent call last) + ... + ValueError: No closing quotation """ from sage.misc.cython import cython_compile - return cython_compile(cell) + import shlex + import argparse + + class ExitCatchingArgumentParser(argparse.ArgumentParser): + def error(self, message): + # exit_on_error=False does not work completely in some Python versions + # see https://stackoverflow.com/q/67890157 + raise argparse.ArgumentError(None, message) + + parser = ExitCatchingArgumentParser(prog="%%cython", add_help=False) + parser.add_argument("--verbose", "-v", type=int) + for (arg, arg_short) in [ + ("compile-message", "m"), + ("use-cache", "c"), + ("create-local-c-file", "l"), + ("annotate", "a"), + ("sage-namespace", "s"), + ("create-local-so-file", "o"), + ]: + action = parser.add_argument(f"--{arg}", f"-{arg_short}", action="store_true", default=None) + parser.add_argument(f"--no-{arg}", action="store_false", dest=action.dest, default=None) + + args = parser.parse_args(shlex.split(line)) + return cython_compile(cell, **{k: v for k, v in args.__dict__.items() if v is not None}) @cell_magic def fortran(self, line, cell): From 719319a6c9f2824a218be569b815a53a22ea0aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 10 Nov 2024 10:07:18 +0100 Subject: [PATCH 050/210] adding the ring of quantum-valued polynomials --- src/sage/rings/polynomial/all.py | 2 + .../q_integer_valued_polynomials.py | 1174 +++++++++++++++++ 2 files changed, 1176 insertions(+) create mode 100644 src/sage/rings/polynomial/q_integer_valued_polynomials.py diff --git a/src/sage/rings/polynomial/all.py b/src/sage/rings/polynomial/all.py index 853f422bdc7..f2295443420 100644 --- a/src/sage/rings/polynomial/all.py +++ b/src/sage/rings/polynomial/all.py @@ -54,3 +54,5 @@ # Integer-valued Univariate Polynomial Ring lazy_import('sage.rings.polynomial.integer_valued_polynomials', 'IntegerValuedPolynomialRing') +lazy_import('sage.rings.polynomial.q_integer_valued_polynomials', + 'QuantumValuedPolynomialRing') diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py new file mode 100644 index 00000000000..609784f4074 --- /dev/null +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -0,0 +1,1174 @@ +r""" +Quantum-valued polynomial rings + +AUTHORS: + +- Frédéric Chapoton (2024-03): Initial version +""" +# *************************************************************************** +# Copyright (C) 2024 Frédéric Chapoton +# +# Distributed under the terms of the GNU General Public License (GPL) +# https://www.gnu.org/licenses/ +# *************************************************************************** +from sage.arith.misc import binomial +from sage.categories.algebras import Algebras +from sage.categories.realizations import Category_realization_of_parent +from sage.categories.rings import Rings +from sage.combinat.free_module import CombinatorialFreeModule +from sage.combinat.q_analogues import q_binomial, q_int +from sage.data_structures.blas_dict import linear_combination +from sage.matrix.constructor import matrix +from sage.misc.bindable_class import BindableClass +from sage.misc.cachefunc import cached_method +from sage.modules.free_module_element import vector +from sage.rings.integer_ring import ZZ +from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing +from sage.rings.polynomial.polynomial_ring import polygen +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.rational_field import QQ +from sage.sets.family import Family +from sage.sets.non_negative_integers import NonNegativeIntegers +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation + + +def q_int_x(n): + """ + Return the interpolating polynomial of `q`-integers. + + INPUT: + + - ``n`` -- a positive integer + + EXAMPLES:: + + sage: from sage.rings.polynomial.q_integer_valued_polynomials import q_int_x + sage: q_int_x(3) + q^2*x + q + 1 + """ + ring_q = PolynomialRing(ZZ, 'q') + q = ring_q.gen() + x = polygen(ring_q, 'x') + return q_int(n - 1) + q**(n - 1) * x + + +def q_binomial_x(m, n): + r""" + Return a `q`-analogue of ``binomial(m + x, n)``. + + When evaluated at the `q`-integer `[k]_q`, this gives + the usual `q`-binomial coefficient `[m + k, n]_q`. + + EXAMPLES:: + + sage: from sage.combinat.q_analogues import q_int + sage: from sage.rings.polynomial.q_integer_valued_polynomials import q_binomial_x, q_int_x + sage: q_binomial_x(4,2)(0) == q_binomial(4,2) + True + sage: q_binomial_x(3,2)(1) == q_binomial(4,2) + True + sage: q_binomial_x(3,1) == q_int_x(4) + True + sage: q_binomial_x(2,0).parent() + Univariate Polynomial Ring in x over Fraction Field of + Univariate Polynomial Ring in q over Integer Ring + """ + ring = PolynomialRing(PolynomialRing(ZZ, 'q').fraction_field(), 'x') + if n == 0: + return ring.one() + return ring.prod(q_int_x(m + 2 - i) / q_int(i) for i in range(1, n + 1)) + + +class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): + r""" + The quantum-valued polynomial ring on some generators over a base ring. + + Quantum-valued polynomial rings are commutative and associative + algebras, with a basis indexed by integers. + + The basis used here is given by `B[i] = \binom{i+n}{i}` for `i \in \NN`. + + There is a nice formula for the product, see [HaHo2017]_. + + INPUT: + + - ``R`` -- commutative ring + + REFERENCES: + + - [HaHo2017] Nate Harman and Sam Hopkins, *Quantum integer-valued + polynomials*, J. Alg. Comb. 2017, :doi:`10.1007/s10801-016-0717-3` + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(QQ).S(); F + Quantum-Valued Polynomial Ring over Rational Field + in the shifted basis + + sage: F.gen() + S[1] + + sage: S = QuantumValuedPolynomialRing(ZZ); S + Quantum-Valued Polynomial Ring over Integer Ring + sage: S.base_ring() + Univariate Laurent Polynomial Ring in q over Integer Ring + + Quantum-valued polynomial rings commute with their base ring:: + + sage: K = QuantumValuedPolynomialRing(QQ).S() + sage: a = K.gen() + sage: c = K.monomial(2) + + Quantum-valued polynomial rings are commutative:: + + sage: c^3 * a == c * a * c * c + True + + We can also manipulate elements in the basis and coerce elements from our + base field:: + + sage: F = QuantumValuedPolynomialRing(QQ).S() + sage: B = F.basis() + sage: B[2] * B[3] + (q^-5+q^-4+q^-3)*S[3] - (q^-6+2*q^-5+3*q^-4+3*q^-3+2*q^-2+q^-1)*S[4] + + (q^-6+q^-5+2*q^-4+2*q^-3+2*q^-2+q^-1+1)*S[5] + sage: 1 - B[2] * B[2] / 2 + S[0] - (1/2*q^-3)*S[2] + (1/2*q^-4+q^-3+q^-2+1/2*q^-1)*S[3] + - (1/2*q^-4+1/2*q^-3+q^-2+1/2*q^-1+1/2)*S[4] + """ + def __init__(self, R) -> None: + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(QQ); F + Quantum-Valued Polynomial Ring over Rational Field + sage: TestSuite(F).run() # not tested + + TESTS:: + + sage: QuantumValuedPolynomialRing(24) + Traceback (most recent call last): + ... + TypeError: argument R must be a commutative ring + """ + if R not in Rings().Commutative(): + msg = "argument R must be a commutative ring" + raise TypeError(msg) + laurent = LaurentPolynomialRing(R, 'q') + self._ground_ring = R + cat = Algebras(laurent).Commutative().WithBasis() + Parent.__init__(self, base=laurent, category=cat.WithRealizations()) + + _shorthands = ["B", "S"] + + def _repr_(self) -> str: + r""" + Return the string representation. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(QQ) + sage: F # indirect doctest + Quantum-Valued Polynomial Ring over Rational Field + + sage: QuantumValuedPolynomialRing(ZZ) + Quantum-Valued Polynomial Ring over Integer Ring + """ + base = self.base_ring().base_ring() + return f"Quantum-Valued Polynomial Ring over {base}" + + def a_realization(self): + """ + Return a default realization. + + The Shifted realization is chosen. + + EXAMPLES:: + + sage: QuantumValuedPolynomialRing(QQ).a_realization() + Quantum-Valued Polynomial Ring over Rational Field + in the shifted basis + """ + return self.Shifted() + + class Bases(Category_realization_of_parent): + def super_categories(self) -> list: + r""" + Return the super-categories of ``self``. + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(QQ); A + Quantum-Valued Polynomial Ring over Rational Field + sage: C = A.Bases(); C + Category of bases of Quantum-Valued Polynomial Ring + over Rational Field + sage: C.super_categories() + [Category of realizations of Quantum-Valued Polynomial Ring + over Rational Field, + Join of Category of algebras with basis + over Univariate Laurent Polynomial Ring in q over Rational Field and + Category of filtered algebras + over Univariate Laurent Polynomial Ring in q over Rational Field and + Category of commutative algebras + over Univariate Laurent Polynomial Ring in q over Rational Field and + Category of realizations of unital magmas] + """ + A = self.base() + category = Algebras(A.base_ring()).Commutative().Filtered() + return [A.Realizations(), + category.Realizations().WithBasis()] + + class ParentMethods: + def ground_ring(self): + """ + Return the ring of coefficients. + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(QQ).S() + sage: A.ground_ring() + Rational Field + """ + return self.realization_of()._ground_ring + + def _repr_(self) -> str: + r""" + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(QQ).S() + sage: F # indirect doctest + Quantum-Valued Polynomial Ring over Rational Field + in the shifted basis + """ + real = self.realization_of() + return f"{real} in the {self._realization_name()} basis" + + @cached_method + def one_basis(self): + r""" + Return the number 0, which index the unit of this algebra. + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(QQ).S() + sage: A.one_basis() + 0 + sage: A.one() + S[0] + """ + return self.basis().keys()(0) + + def degree_on_basis(self, m): + r""" + Return the degree of the basis element indexed by ``m``. + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(QQ).S() + sage: A.degree_on_basis(4) + 4 + """ + return ZZ(m) + + def from_polynomial(self, p): + r""" + Convert a polynomial into the ring of quantum-valued polynomials. + + This raises a :exc:`ValueError` if this is not possible. + + INPUT: + + - ``p`` -- a polynomial in ``x`` with coefficients in ``QQ(q)`` + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(ZZ).S() + sage: S = A.basis() + sage: A.from_polynomial((S[1]).polynomial()) + S[1] + sage: A.from_polynomial((S[2]+2*S[3]).polynomial()) + S[2] + 2*S[3] + + sage: A = QuantumValuedPolynomialRing(ZZ).B() + sage: B = A.basis() + sage: A.from_polynomial((B[1]).polynomial()) + B[1] + sage: A.from_polynomial((B[2]+2*B[3]).polynomial()) + B[2] + 2*B[3] + """ + B = self.basis() + poly = self._poly + laurent_polys = self.base_ring() + remain = p.change_variable_name('x') + result = self.zero() + while remain: + N = remain.degree() + base_N = poly(N) + top_coeff = remain.leading_coefficient() / base_N.lc() + denom = top_coeff.denominator() + if denom.is_term(): + numer = top_coeff.numerator() + top_coeff_laurent = laurent_polys(numer) / laurent_polys(denom) + else: + msg = 'not a polynomial with integer values :' + msg += f' {top_coeff} is not a Laurent polynomial' + raise ValueError(msg) + remain += -top_coeff * base_N + result += top_coeff_laurent * B[N] + return result + + def gen(self, i=0): + r""" + Return the generator of the algebra. + + The optional argument is ignored. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(ZZ).S() + sage: F.gen() + S[1] + """ + return self.basis()[1] + + @cached_method + def algebra_generators(self): + r""" + Return the generators of this algebra. + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(ZZ).S(); A + Quantum-Valued Polynomial Ring over Integer Ring + in the shifted basis + sage: A.algebra_generators() + Family (S[1],) + """ + return Family([self.basis()[1]]) + + gens = algebra_generators + + class ElementMethods: + def __call__(self, v): + """ + Return the evaluation at some value ``v``. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(ZZ).S() + sage: B = F.gen() + sage: f = B**2+4*B+6 + sage: f(1/3) + (q^2 + 18*q + 99)/9 + + sage: F = QuantumValuedPolynomialRing(ZZ).B() + sage: B = F.gen() + sage: f = F.monomial(2)+4*B+6 + sage: f(1/3) + (66*q^2 + 66*q - 2)/(9*q^2 + 9*q) + """ + return self.polynomial()(v) + + def polynomial(self): + """ + Convert to a polynomial in `x`. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(ZZ).S() + sage: S = F.gen() + sage: (S+1).polynomial() + q*x + 2 + + sage: F = QuantumValuedPolynomialRing(ZZ).B() + sage: B = F.gen() + sage: (B+1).polynomial() + x + 1 + + TESTS:: + + sage: F.zero().polynomial().parent() + Univariate Polynomial Ring in x over Fraction Field + of Univariate Polynomial Ring in q over Integer Ring + """ + ring = self.parent().ground_ring() + fractions = PolynomialRing(ring, 'q').fraction_field() + R = PolynomialRing(fractions, 'x') + p = self.parent()._poly + return R.sum(c * p(i) for i, c in self) + + def shift(self, j=1): + """ + Shift all indices by `j`. + + INPUT: + + - `j` -- integer (default 1) + + In the binomial basis, the shift by 1 corresponds to + a summation operator from `0` to `x`. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(ZZ).S() + sage: B = F.gen() + sage: (B+1).shift() + S[1] + S[2] + """ + A = self.parent() + return A._from_dict({A._indices(i + j): c for i, c in self}) + + def sum_of_coefficients(self): + """ + Return the sum of coefficients. + + In the shifted basis, this is the evaluation at `x=0`. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(ZZ).S() + sage: B = F.basis() + sage: (B[2]*B[4]).sum_of_coefficients() + 1 + """ + R = self.parent().base_ring() + return R.sum(self._monomial_coefficients.values()) + + class Shifted(CombinatorialFreeModule, BindableClass): + r""" + The quantum-valued polynomial ring in the shifted basis. + + The basis used here is given by `S[i] = \genfrac{[}{]}{0pt}{}{i+x}{i}_q` for `i \in \NN`. + + Assuming `n_1 \leq n_2`, the product of two monomials `S[n_1] \cdot S[n_2]` + is given by the sum + + .. MATH:: + + \sum_{k=0}^{n_1} (-1)^k q^{\binom{k}{2} - n_1 * n_2} \genfrac{[}{]}{0pt}{}{n_1}{k}_q \genfrac{[}{]}{0pt}{}{n_1+n_2-k}{n_1}_q S[n_1 + n_2 - k]. + """ + def __init__(self, A): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(QQ).S(); F + Quantum-Valued Polynomial Ring over Rational Field + in the shifted basis + sage: TestSuite(F).run() # not tested + """ + CombinatorialFreeModule.__init__(self, A.base_ring(), + NonNegativeIntegers(), + category=A.Bases(), + prefix="S", + latex_prefix=r"\mathbb{S}") + + def _an_element_(self): + """ + Return a small element of ``self``. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(QQ).S() + sage: F.an_element() + 2*S[0] + 4*S[2] + """ + NonNeg = self.basis().keys() + ring = self.base_ring() + return self.element_class(self, {NonNeg(0): ring(2), + NonNeg(2): ring(4)}) + + def _realization_name(self) -> str: + r""" + TESTS:: + + sage: F = QuantumValuedPolynomialRing(QQ).S() + sage: F._realization_name() + 'shifted' + """ + return "shifted" + + def product_on_basis(self, n1, n2): + r""" + Return the product of basis elements ``n1`` and ``n2``. + + INPUT: + + - ``n1``, ``n2`` -- integers + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(QQ).S() + sage: A.product_on_basis(0, 1) + S[1] + """ + i = ZZ(n1) + j = ZZ(n2) + if j < i: + j, i = i, j + q = self.base_ring().gen() + return self._from_dict({i + j - k: (-1)**k + * q_binomial(i, k) + * q_binomial(i + j - k, i) + * q**(binomial(k, 2) - i * j) + for k in range(i + 1)}) + + def _from_binomial_basis(self, i): + """ + Convert from the ``binomial(x,k)`` basis. + + INPUT: + + - ``i`` -- an integer + + EXAMPLES:: + + sage: S = QuantumValuedPolynomialRing(ZZ).S() + sage: B = QuantumValuedPolynomialRing(ZZ).B() + sage: b = B.basis() + sage: S(b[3]+1) # indirect doctest + -(q^-6-1)*S[0] + (q^-8+q^-7+q^-6)*S[1] + - (q^-9+q^-8+q^-7)*S[2] + (q^-9)*S[3] + sage: B(_) + B[0] + B[3] + """ + i = ZZ(i) + R = self.base_ring() + q = self.base_ring().gen() + return self._from_dict({k: R((-1)**(i - k) * q_binomial(i, k)) + * q**(-i**2 + binomial(i - k, 2)) + for k in range(i + 1)}) + + def from_h_vector(self, hv): + """ + Convert from some `h`-vector. + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(ZZ).S() + sage: B = A.basis() + sage: ex = B[2] + B[3] + sage: A.from_h_vector(ex.h_vector()) + S[2] + S[3] + + sage: q = A.base_ring().gen() + sage: ex = B[2] + q*B[3] + sage: A.from_h_vector(ex.h_vector()) + S[2] + q*S[3] + """ + B = self.basis() + ring = self.base_ring() + q = ring.gen() + d = len(hv) - 1 + m = matrix(ring, d + 1, d + 1, + lambda j, i: (-1)**(d - j) * q_binomial(d - i, d - j, q) * + q**(-d * (d - i) + binomial(d - j, 2))) + v = vector(ring, [hv[i] for i in range(d + 1)]) + return sum(ring(c) * B[i] for i, c in enumerate(m * v)) + + def _element_constructor_(self, x): + r""" + Convert ``x`` into ``self``. + + INPUT: + + - ``x`` -- an element of the base ring or something convertible + + EXAMPLES:: + + sage: R = QuantumValuedPolynomialRing(QQ).S() + sage: x = R.gen() + sage: R(3) + 3*S[0] + sage: R(x) + S[1] + """ + P = x.parent() + if isinstance(P, QuantumValuedPolynomialRing.Shifted): + if P is self: + return x + if P is not self.base_ring(): + return self.element_class(self, x.monomial_coefficients()) + + # ok, not a quantum-valued polynomial ring element + R = self.base_ring() + # coercion via base ring + x = R(x) + if x == 0: + return self.element_class(self, {}) + return self.from_base_ring_from_one_basis(x) + + def _coerce_map_from_(self, R) -> bool: + r""" + Return whether there is a coercion from ``R`` into ``self``. + + INPUT: + + - ``R`` -- a commutative ring + + The things that coerce into ``self`` are + + - Quantum-Valued Polynomial Rings over a base + with a coercion map into ``self.base_ring()``. + + - Anything with a coercion into ``self.base_ring()``. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(GF(7)).S(); F + Quantum-Valued Polynomial Ring over Finite Field of size 7 + in the shifted basis + + Elements of the quantum-valued polynomial ring canonically coerce in:: + + sage: x = F.gen() + sage: F.coerce(x*x) # indirect doctest + (6*q^-1)*S[1] + (q^-1+1)*S[2] + + Elements of the integers coerce in, since there is a coerce map + from `\ZZ` to GF(7):: + + sage: F.coerce(1) # indirect doctest + S[0] + + There is no coerce map from `\QQ` to `\GF{7}`:: + + sage: F.coerce(2/3) # indirect doctest + Traceback (most recent call last): + ... + TypeError: no canonical coercion from Rational Field to + Quantum-Valued Polynomial Ring over Finite Field of size 7 + in the shifted basis + + Elements of the base ring coerce in:: + + sage: F.coerce(GF(7)(5)) + 5*S[0] + + The quantum-valued polynomial ring over `\ZZ` on `x` coerces in, since + `\ZZ` coerces to `\GF{7}`:: + + sage: G = QuantumValuedPolynomialRing(ZZ).S() + sage: Gx = G.gen() + sage: z = F.coerce(Gx**2); z + -(q^-1)*S[1] + (q^-1+1)*S[2] + sage: z.parent() is F + True + + However, `\GF{7}` does not coerce to `\ZZ`, so the shuffle + algebra over `\GF{7}` does not coerce to the one over `\ZZ`:: + + sage: G.coerce(x^3+x) + Traceback (most recent call last): + ... + TypeError: no canonical coercion from Quantum-Valued Polynomial + Ring over Finite Field of size 7 in the shifted basis + to Quantum-Valued Polynomial Ring over Integer Ring + in the shifted basis + + TESTS:: + + sage: F = QuantumValuedPolynomialRing(ZZ).S() + sage: G = QuantumValuedPolynomialRing(QQ).S() + sage: H = QuantumValuedPolynomialRing(ZZ).S() + sage: F._coerce_map_from_(G) + False + sage: G._coerce_map_from_(F) + True + sage: F._coerce_map_from_(H) + True + sage: F._coerce_map_from_(QQ) + False + sage: G._coerce_map_from_(QQ) + True + sage: F.has_coerce_map_from(PolynomialRing(ZZ, 'x')) + False + """ + # quantum-valued polynomial rings in the same variable + # over any base that coerces in: + if isinstance(R, QuantumValuedPolynomialRing.Shifted): + return self.base_ring().has_coerce_map_from(R.base_ring()) + if isinstance(R, QuantumValuedPolynomialRing.Binomial): + return R.module_morphism(self._from_binomial_basis, + codomain=self) + return self.base_ring().has_coerce_map_from(R) + + def _poly(self, i): + """ + Convert the basis element `S[i]` to a polynomial. + + INPUT: + + - ``i`` -- an integer + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(ZZ).S() + sage: F._poly(4).factor() + (1/(q^6 + 3*q^5 + 5*q^4 + 6*q^3 + 5*q^2 + 3*q + 1)) * + (q*x + 1) * (q^2*x + q + 1) * (q^3*x + q^2 + q + 1) * + (q^4*x + q^3 + q^2 + q + 1) + """ + return q_binomial_x(i, i) + + class Element(CombinatorialFreeModule.Element): + + def umbra(self): + """ + Return the Bernoulli umbra. + + This is the derivative at `-1` of the shift by one. + + This is related to Carlitz's `q`-Bernoulli numbers. + + .. SEEALSO:: :meth:`derivative_at_minus_one` + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(ZZ).S() + sage: B = F.gen() + sage: (B+1).umbra() + (q + 2)/(q + 1) + """ + return self.shift().derivative_at_minus_one() + + def variable_shift(self, k=1): + r""" + Return the image by the shift on variables. + + The shift is the substitution operator + + .. MATH:: + + x \mapsto q x + 1. + + INPUT: + + - `k` -- integer (default: 1) + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(ZZ).S() + sage: S = A.basis() + sage: S[5].variable_shift() + S[0] + q*S[1] + q^2*S[2] + q^3*S[3] + q^4*S[4] + q^5*S[5] + + sage: S[5].variable_shift(-1) + -(q^-5)*S[4] + (q^-5)*S[5] + + TESTS:: + + sage: S[5].variable_shift(0) + S[5] + sage: S[5].variable_shift().variable_shift(-1) + S[5] + sage: S[5].variable_shift(2).variable_shift(-2) + S[5] + sage: S[3].variable_shift(-2) + (q^-5)*S[1] - (q^-6+q^-5)*S[2] + (q^-6)*S[3] + """ + if k == 0: + return self + + A = self.parent() + q = A.base_ring().gen() + + def on_basis(n): + return {A._indices(j): q**(k * j) + * q_binomial(k + n - 1 - j, n - j) + for j in range(n + 1)} + + mc = self._monomial_coefficients + ret = linear_combination((on_basis(index), coeff) + for index, coeff in mc.items()) + return A.element_class(A, ret) + + def derivative_at_minus_one(self): + """ + Return the 'derivative' at -1. + + .. SEEALSO:: :meth:`umbra` + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(ZZ).S() + sage: B = F.gen() + sage: (B+1).derivative_at_minus_one() + 1 + """ + ring = q_int(1).parent() + return ring.sum(c / q_int(i) for i, c in self if i > 0) + + def h_vector(self): + """ + Return the numerator of the generating series of values. + + If ``self`` is an Ehrhart polynomial, this is the h-vector. + + .. SEEALSO:: :meth:`h_polynomial`, :meth:`fraction` + + changement de base vers les (binomial(x+i,d))_{i=0..d} + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(ZZ).S() + sage: ex = A.basis()[4] + sage: ex.h_vector() + (0, 0, 0, 0, 1) + + sage: q = polygen(QQ,'q') + sage: x = polygen(q.parent(),'x') + sage: ex = A.from_polynomial((1+q*x)**3) + sage: ex.h_vector() + (0, q^3, 2*q + 2*q^2, 1) + """ + d = max(self.support()) + ring = self.parent().base_ring() + q = ring.gen() + + def fn(j, i): + return ((-1)**(d - j) * + q**(binomial(d - j + i + 1, 2) - + binomial(i + 1, 2)) * + q_binomial(d - i, d - j)) + m = matrix(ring, d + 1, d + 1, fn) + v = vector(ring, [self.coefficient(i) for i in range(d + 1)]) + return m * v + + def h_polynomial(self): + """ + Return the `h`-vector as a polynomial. + + .. SEEALSO:: :meth:`h_vector`, :meth:`fraction` + + peut-etre pas dans le bon sens ? + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(ZZ).S() + sage: q = polygen(ZZ,'q') + sage: x = polygen(q.parent(),'x') + sage: ex = A.from_polynomial((1+q*x)**3) + sage: ex.h_polynomial() + z^3 + (2*q + 2*q^2)*z^2 + q^3*z + """ + ring = PolynomialRing(self.parent().base_ring(), 'z') + return ring(list(self.h_vector())) + + def fraction(self): + """ + Return the generating series of values as a fraction. + + .. SEEALSO:: :meth:`h_vector`, :meth:`h_polynomial` + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(QQ).S() + sage: ex = A.basis()[4] + sage: ex.fraction().factor() + (-1) * (t - 1)^-1 * (q*t - 1)^-1 * (q^2*t - 1)^-1 * (q^3*t - 1)^-1 * (q^4*t - 1)^-1 + + sage: q = polygen(QQ,'q') + sage: x = polygen(q.parent(), 'x') + sage: ex = A.from_polynomial((1+q*x)**3) + sage: ex.fraction().factor() + (t - 1)^-1 * (q*t - 1)^-1 * (q^2*t - 1)^-1 * (q^3*t - 1)^-1 * (q^3*t^2 + 2*q^2*t + 2*q*t + 1) + sage: ex.fraction().numerator() + q^3*t^2 + 2*q^2*t + 2*q*t + 1 + """ + v = self.h_vector() + d = len(v) + R = PolynomialRing(QQ, 'q,t') + frac_R = R.fraction_field() + q, t = R.gens() + denom = R.prod(1 - q**i * t for i in range(d)) + numer = sum(frac_R(v[i]) * t**(d - 1 - i) for i in range(d)) + return numer / denom + + S = Shifted + + # ===== Another basis for the same algebra ===== + + class Binomial(CombinatorialFreeModule, BindableClass): + r""" + The quantum-valued polynomial ring in the binomial basis. + + The basis used here is given by `B[i] = \genfrac{[}{]}{0pt}{}{x}{i}_q` for `i \in \NN`. + + Assuming `n_1 \leq n_2`, the product of two monomials `B[n_1] \cdot B[n_2]` + is given by the sum + + .. MATH:: + + \sum_{k=0}^{n_1} q^{(k-n_1)(k-n_2)} \genfrac{[}{]}{0pt}{}{n_1}{k}_q \genfrac{[}{]}{0pt}{}{n_1+n_2-k}{n_1}_q B[n_1 + n_2 - k]. + """ + def __init__(self, A) -> None: + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(QQ).B(); F + Quantum-Valued Polynomial Ring over Rational Field + in the binomial basis + sage: TestSuite(F).run() # not tested + """ + CombinatorialFreeModule.__init__(self, A.base_ring(), + NonNegativeIntegers(), + category=A.Bases(), + prefix="B", + latex_prefix=r"\mathbb{B}") + + def _realization_name(self) -> str: + r""" + TESTS:: + + sage: F = QuantumValuedPolynomialRing(QQ).B() + sage: F._realization_name() + 'binomial' + """ + return "binomial" + + def product_on_basis(self, n1, n2): + r""" + Return the product of basis elements ``n1`` and ``n2``. + + INPUT: + + - ``n1``, ``n2`` -- integers + + The formula is taken from Theorem 3.4 in Harman-Hopkins. + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(QQ).B() + sage: A.product_on_basis(0, 1) + B[1] + """ + i = ZZ(n1) + j = ZZ(n2) + if j < i: + j, i = i, j + + q = self.base_ring().gen() + return self._from_dict({i + j - k: + q_binomial(i, k) + * q_binomial(i + j - k, i) + * q**((k - i) * (k - j)) + for k in range(i + 1)}) + + def _from_shifted_basis(self, i): + """ + Convert from the shifted binomial(x+k,k) basis. + + INPUT: + + - ``i`` -- an integer + + EXAMPLES:: + + sage: S = QuantumValuedPolynomialRing(ZZ).S() + sage: B = QuantumValuedPolynomialRing(ZZ).B() + sage: s = S.basis() + sage: B(s[3]+1) # indirect doctest + 2*B[0] + (q+q^2+q^3)*B[1] + (q^4+q^5+q^6)*B[2] + q^9*B[3] + sage: S(_) + S[0] + S[3] + """ + i = ZZ(i) + R = self.base_ring() + q = self.base_ring().gen() + return self._from_dict({k: R(q_binomial(i, k)) + * q**(k**2) + for k in range(i + 1)}) + + def _element_constructor_(self, x): + r""" + Convert ``x`` into ``self``. + + EXAMPLES:: + + sage: R = QuantumValuedPolynomialRing(QQ).B() + sage: x = R.gen() + sage: R(3) + 3*B[0] + sage: R(x) + B[1] + """ + P = x.parent() + if isinstance(P, QuantumValuedPolynomialRing.Binomial): + if P is self: + return x + if P is not self.base_ring(): + return self.element_class(self, x.monomial_coefficients()) + + # ok, not a quantum-valued polynomial ring element + R = self.base_ring() + # coercion via base ring + x = R(x) + if x == 0: + return self.element_class(self, {}) + return self.from_base_ring_from_one_basis(x) + + def _coerce_map_from_(self, R): + r""" + Return whether there is a coercion from ``R`` into ``self``. + + INPUT: + + - ``R`` -- a commutative ring + + The things that coerce into ``self`` are + + - Quantum-Valued Polynomial Rings over a base + with a coercion map into ``self.base_ring()``. + + - Anything with a coercion into ``self.base_ring()``. + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(GF(7)).B(); F + Quantum-Valued Polynomial Ring over Finite Field of size 7 + in the binomial basis + + Elements of the integer-valued polynomial ring canonically coerce + in:: + + sage: x = F.gen() + sage: F.coerce(x*x) # indirect doctest + B[1] + (q+q^2)*B[2] + + Elements of the integers coerce in, since there is a coerce map + from `\ZZ` to `\GF(7)`:: + + sage: F.coerce(1) # indirect doctest + B[0] + + There is no coerce map from `\QQ` to `\GF{7}`:: + + sage: F.coerce(2/3) # indirect doctest + Traceback (most recent call last): + ... + TypeError: no canonical coercion from Rational Field to + Quantum-Valued Polynomial Ring over Finite Field of size 7 + in the binomial basis + + Elements of the base ring coerce in:: + + sage: F.coerce(GF(7)(5)) + 5*B[0] + + The integer-valued polynomial ring over `\ZZ` on `x` coerces in, + since `\ZZ` coerces to `\GF{7}`:: + + sage: G = QuantumValuedPolynomialRing(ZZ).B() + sage: Gx = G.gen() + sage: z = F.coerce(Gx**2); z + B[1] + (q+q^2)*B[2] + sage: z.parent() is F + True + + However, `\GF{7}` does not coerce to `\ZZ`, so the + integer-valued polynomial algebra over `\GF{7}` does not + coerce to the one over `\ZZ`:: + + sage: G.coerce(x^3+x) + Traceback (most recent call last): + ... + TypeError: no canonical coercion from + Quantum-Valued Polynomial Ring over Finite Field of size 7 + in the binomial basis to Quantum-Valued Polynomial Ring + over Integer Ring in the binomial basis + + TESTS:: + + sage: F = QuantumValuedPolynomialRing(ZZ).B() + sage: G = QuantumValuedPolynomialRing(QQ).B() + sage: H = QuantumValuedPolynomialRing(ZZ).B() + sage: F._coerce_map_from_(G) + False + sage: G._coerce_map_from_(F) + True + sage: F._coerce_map_from_(H) + True + sage: F._coerce_map_from_(QQ) + False + sage: G._coerce_map_from_(QQ) + True + sage: F.has_coerce_map_from(PolynomialRing(ZZ,'x')) + False + """ + # quantum-valued polynomial rings over any base + # that coerces in: + if isinstance(R, QuantumValuedPolynomialRing.Binomial): + return self.base_ring().has_coerce_map_from(R.base_ring()) + if isinstance(R, QuantumValuedPolynomialRing.Shifted): + return R.module_morphism(self._from_shifted_basis, + codomain=self) + return self.base_ring().has_coerce_map_from(R) + + def _poly(self, i): + """ + Convert the basis element `B[i]` to a polynomial. + + INPUT: + + - ``i`` -- an integer + + EXAMPLES:: + + sage: F = QuantumValuedPolynomialRing(ZZ).B() + sage: F._poly(4).factor() + (1/(q^12 + 3*q^11 + 5*q^10 + 6*q^9 + 5*q^8 + 3*q^7 + q^6)) * + (x - 1) * x * (x - q - 1) * (x - q^2 - q - 1) + """ + return q_binomial_x(0, i) + + class Element(CombinatorialFreeModule.Element): + def variable_shift(self, k=1): + r""" + Return the image by the shift of variables. + + On polynomials, the action for `k=1` is the shift + on variables `x \mapsto 1 + qx`. + + This implementation follows formula (5.5) in [HaHo2017]_. + + INPUT: + + - `k` -- nonnegative integer (default: 1) + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(ZZ).B() + sage: B = A.basis() + sage: B[5].variable_shift() + B[4] + q^5*B[5] + + TESTS:: + + sage: B[5].variable_shift(0) + B[5] + """ + if k == 0: + return self + + A = self.parent() + q = A.base_ring().gen() + + def on_basis(n): + return {A._indices(j): q**((k + j - n) * j) + * q_binomial(k, n - j) + for j in range(n + 1)} + + mc = self._monomial_coefficients + ret = linear_combination((on_basis(index), coeff) + for index, coeff in mc.items()) + return A.element_class(A, ret) + + B = Binomial From 6b505655b2f84cf69142de10e7ef41922e46cd1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 10 Nov 2024 11:01:13 +0100 Subject: [PATCH 051/210] insert into reference manual --- .../en/reference/polynomial_rings/polynomial_rings_univar.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/en/reference/polynomial_rings/polynomial_rings_univar.rst b/src/doc/en/reference/polynomial_rings/polynomial_rings_univar.rst index 97cff1bb835..021a50f262e 100644 --- a/src/doc/en/reference/polynomial_rings/polynomial_rings_univar.rst +++ b/src/doc/en/reference/polynomial_rings/polynomial_rings_univar.rst @@ -45,3 +45,4 @@ whereas others have multiple bases. sage/rings/polynomial/polynomial_fateman sage/rings/polynomial/integer_valued_polynomials + sage/rings/polynomial/q_integer_valued_polynomials From b11634787bb3bfe5746b9c12b17483fd41e65e9c Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 18:14:49 +0530 Subject: [PATCH 052/210] Overwrote methods concerning loops --- src/sage/graphs/matching_covered_graph.py | 25 ++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 2a9b8916c90..1221ee5f192 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -57,7 +57,6 @@ ``delete_multiedge()`` | Delete all edges from ``u`` to ``v``. ``disjoint_union()`` | Return the disjoint union of ``self`` and ``other``. ``disjunctive_product()`` | Return the disjunctive product of ``self`` and ``other``. - ``has_loops()`` | Return whether there are loops in the matching covered graph. ``is_biconnected()`` | Check if the matching covered graph is biconnected. ``is_block_graph()`` | Check whether the matching covered graph is a block graph. ``is_cograph()`` | Check whether the matching covered graph is cograph. @@ -69,12 +68,8 @@ ``join()`` | Return the join of ``self`` and ``other``. ``lexicographic_product()`` | Return the lexicographic product of ``self`` and ``other``. ``load_afile()`` | Load the matching covered graph specified in the given file into the current object. - ``loop_edges()`` | Return a list of all loops in the matching covered graph. - ``loop_vertices()`` | Return a list of vertices with loops. ``merge_vertices()`` | Merge vertices. - ``number_of_loops()`` | Return the number of edges that are loops. ``random_subgraph()`` | Return a random matching covered subgraph containing each vertex with probability ``p``. - ``remove_loops()`` | Remove loops on vertices in ``vertices``. ``save_afile()`` | Save the graph to file in alist format. ``strong_product()`` | Return the strong product of ``self`` and ``other``. ``subdivide_edge()`` | Subdivide an edge `k` times. @@ -1918,6 +1913,10 @@ def get_matching(self): """ return self._matching + @doc_index('Overwritten methods') + def has_loops(self): + raise NotImplementedError() + @doc_index('Overwritten methods') def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, *, integrality_tolerance=1e-3): @@ -2003,6 +2002,22 @@ def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, raise ValueError('algorithm must be set to \'Edmonds\', ' '\'LP_matching\' or \'LP\'') + @doc_index('Overwritten methods') + def loop_edges(self, labels=True): + raise NotImplementedError() + + @doc_index('Overwritten methods') + def loop_vertices(self): + raise NotImplementedError() + + @doc_index('Overwritten methods') + def number_of_loops(self): + raise NotImplementedError() + + @doc_index('Overwritten methods') + def remove_loops(self, vertices=None): + raise NotImplementedError() + @doc_index('Miscellaneous methods') def update_matching(self, matching): r""" From f6ad99cbc2a7eb53d5e3f145c5e499c9fd65402e Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 18:18:28 +0530 Subject: [PATCH 053/210] Overwrote has_loops() --- src/sage/graphs/matching_covered_graph.py | 82 ++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 1221ee5f192..4426fd5b211 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1915,7 +1915,87 @@ def get_matching(self): @doc_index('Overwritten methods') def has_loops(self): - raise NotImplementedError() + r""" + Check whether thare are loops in the (matching covered) graph. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.has_loops` method in + order to return ``False`` as matching covered graphs are always + free of looped edges. + + OUTPUT: + + - A boolean ``False`` is returned since matching covered graphs, by + definition, are free of self-loops. + + EXAMPLES: + + A matching covered graph, for instance the Petersen graph, is always free + of loops:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: G + Matching covered petersen graph: graph on 10 vertices + sage: G.has_loops() + False + sage: G.allows_loops() + False + sage: G.add_edge(0, 0) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + sage: G.loops() + [] + sage: G.loop_edges() + [] + sage: G.loop_vertices() + [] + sage: G.number_of_loops() + 0 + + A matching covered graph may support multiple edges, still no + loops are allowed:: + + sage: K = graphs.CompleteGraph(2) + sage: G = MatchingCoveredGraph(K) + sage: G.allow_multiple_edges(True) + sage: G + Matching covered complete graph: multi-graph on 2 vertices + sage: G.add_edge(0, 1, 'label') + sage: G.add_edge(0, 0) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + sage: G.edges(sort=False) + [(0, 1, None), (0, 1, 'label')] + sage: G.allows_loops() + False + sage: G.has_loops() + False + sage: G.loops() + [] + sage: G.loop_edges() + [] + sage: G.loop_vertices() + [] + sage: G.number_of_loops() + 0 + + .. SEEALSO:: + + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops` + + """ + return False @doc_index('Overwritten methods') def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, From 7de0b7be9bd2ff347e0eb0362ed50765bf8d5281 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 18:21:35 +0530 Subject: [PATCH 054/210] Overwrote loop_edges() --- src/sage/graphs/matching_covered_graph.py | 94 ++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 4426fd5b211..e6630415f34 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2084,7 +2084,99 @@ def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, @doc_index('Overwritten methods') def loop_edges(self, labels=True): - raise NotImplementedError() + r""" + Return a list of all loops in the (matching covered) graph. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.loop_edges` method + in order to return an empty list as matching covered graphs are + free of looped edges. + + INPUT: + + - ``labels`` -- boolean (default: ``True``); whether returned edges have + labels (``(u,v,l)``) or not (``(u,v)``) + + OUTPUT: + + - A list capturing the edges that are loops in the matching covered + graph; note that, the list is empty since matching covered graphs do + not contain any looped edges. + + EXAMPLES: + + A matching covered graph, for instance the Heawood graph, by + definition, is always free of loops:: + + sage: H = graphs.HeawoodGraph() + sage: G = MatchingCoveredGraph(H) + sage: G + Matching covered heawood graph: graph on 14 vertices + sage: G.has_loops() + False + sage: G.allows_loops() + False + sage: G.add_edge(0, 0) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + sage: G.loops() + [] + sage: G.loop_edges() + [] + sage: G.loop_vertices() + [] + sage: G.number_of_loops() + 0 + + A matching covered graph may support multiple edges, still no + loops are allowed:: + + sage: C = graphs.CycleGraph(4) + sage: G = MatchingCoveredGraph(C) + sage: G.allow_multiple_edges(True) + sage: G + Matching covered cycle graph: multi-graph on 4 vertices + sage: G.add_edge(0, 1, 'label') + sage: G.add_edge(0, 0) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + sage: G.edges(sort=False) + [(0, 1, None), (0, 1, 'label'), (0, 3, None), (1, 2, None), (2, 3, None)] + sage: G.allows_loops() + False + sage: G.has_loops() + False + sage: G.loops() + [] + sage: G.loop_edges() + [] + sage: G.loop_vertices() + [] + sage: G.number_of_loops() + 0 + + One may set the ``label`` to either ``True`` or ``False``:: + + sage: G.loop_edges(labels=False) + [] + sage: G.loops(labels=True) + [] + + .. SEEALSO:: + + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops` + """ + return [] @doc_index('Overwritten methods') def loop_vertices(self): From a5a332fb85330f0587f1426e3b8b4fdc83ca0fc9 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 18:24:06 +0530 Subject: [PATCH 055/210] Overwrote loop_vertices() --- src/sage/graphs/matching_covered_graph.py | 86 ++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index e6630415f34..e73d96367da 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2180,7 +2180,91 @@ def loop_edges(self, labels=True): @doc_index('Overwritten methods') def loop_vertices(self): - raise NotImplementedError() + """ + Return a list of vertices with loops. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.loop_vertices` + method in order to return an empty list as matching covered graphs + are free of vertices that have looped edges. + + OUTPUT: + + - A list capturing the vertices that have loops in the matching covered + graph; note that, the list is empty since matching covered graphs do + not contain any looped edges. + + EXAMPLES: + + A matching covered graph, for instance the Möbius graph of order 8, by + definition, is always free of loops:: + + sage: M = graphs.MoebiusLadderGraph(4) + sage: G = MatchingCoveredGraph(M) + sage: G + Matching covered moebius ladder graph: graph on 8 vertices + sage: G.has_loops() + False + sage: G.allows_loops() + False + sage: G.add_edge(0, 0) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + sage: G.loops() + [] + sage: G.loop_edges() + [] + sage: G.loop_vertices() + [] + sage: G.number_of_loops() + 0 + + A matching covered graph may support multiple edges, still no + loops are allowed:: + + sage: S = graphs.StaircaseGraph(4) + sage: G = MatchingCoveredGraph(S) + sage: G.allow_multiple_edges(True) + sage: G + Matching covered staircase graph: multi-graph on 8 vertices + sage: G.add_edge(0, 1, 'label') + sage: G.add_edge(0, 0) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + sage: G.edges(sort=False) + [(0, 1, None), (0, 1, 'label'), (0, 3, None), (0, 6, None), + (1, 2, None), (1, 4, None), (2, 5, None), (2, 7, None), + (3, 4, None), (3, 6, None), (4, 5, None), (5, 7, None), + (6, 7, None)] + sage: G.allows_loops() + False + sage: G.has_loops() + False + sage: G.loops() + [] + sage: G.loop_edges() + [] + sage: G.loop_vertices() + [] + sage: G.number_of_loops() + 0 + + .. SEEALSO:: + + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops` + + """ + return [] @doc_index('Overwritten methods') def number_of_loops(self): From 8979db1d7c2abbb48ec0dfd82a9e47265a8b5ce2 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 18:26:57 +0530 Subject: [PATCH 056/210] Overwrote loops() --- src/sage/graphs/matching_covered_graph.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index e73d96367da..133d86e32ac 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2266,6 +2266,8 @@ def loop_vertices(self): """ return [] + loops = loop_edges + @doc_index('Overwritten methods') def number_of_loops(self): raise NotImplementedError() From 7acc34d42283ea1c4a906105d0ffcf4e23a8d7eb Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 18:27:55 +0530 Subject: [PATCH 057/210] Overwrote number_of_loops() --- src/sage/graphs/matching_covered_graph.py | 84 ++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 133d86e32ac..77b3654374c 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2270,7 +2270,89 @@ def loop_vertices(self): @doc_index('Overwritten methods') def number_of_loops(self): - raise NotImplementedError() + r""" + Return the number of edges that are loops. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.number_of_loops` + method in order to return 0 as matching covered graphs are free + of looped edges. + + OUTPUT: + + - An integer, 0 is returned, since matching covered graphs do not + contain zero loops. + + EXAMPLES: + + A matching covered graph, for instance the Truncated biwheel graph, + by definition, is always free of loops:: + + sage: T = graphs.TruncatedBiwheelGraph(5) + sage: G = MatchingCoveredGraph(T) + sage: G + Matching covered truncated biwheel graph: graph on 10 vertices + sage: G.has_loops() + False + sage: G.allows_loops() + False + sage: G.add_edge(0, 0) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + sage: G.loops() + [] + sage: G.loop_edges() + [] + sage: G.loop_vertices() + [] + sage: G.number_of_loops() + 0 + + A matching covered graph may support multiple edges, still no + loops are allowed:: + + sage: B = graphs.BiwheelGraph(4) + sage: G = MatchingCoveredGraph(B) + sage: G.allow_multiple_edges(True) + sage: G + Matching covered biwheel graph: multi-graph on 8 vertices + sage: G.add_edge(0, 1, 'label') + sage: G.add_edge(0, 0) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + sage: G.edges(sort=False) + [(0, 1, None), (0, 1, 'label'), (0, 5, None), (0, 7, None), + (1, 2, None), (1, 6, None), (2, 3, None), (2, 7, None), + (3, 4, None), (3, 6, None), (4, 5, None), (4, 7, None), + (5, 6, None)] + sage: G.allows_loops() + False + sage: G.has_loops() + False + sage: G.loops() + [] + sage: G.loop_edges() + [] + sage: G.loop_vertices() + [] + sage: G.number_of_loops() + 0 + + .. SEEALSO:: + + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops` + """ + return 0 @doc_index('Overwritten methods') def remove_loops(self, vertices=None): From d24784855e9dac71a2b0bb0c166a165fa93f2569 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 18:28:54 +0530 Subject: [PATCH 058/210] Overwrote remove_loops() --- src/sage/graphs/matching_covered_graph.py | 92 ++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 77b3654374c..7d035d2de81 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2356,7 +2356,97 @@ def number_of_loops(self): @doc_index('Overwritten methods') def remove_loops(self, vertices=None): - raise NotImplementedError() + r""" + Remove loops on vertices in ``vertices``. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.remove_loops` method + in order to return without any alteration as matching covered + graphs are free of looped edges. + + INPUT: + + - ``vertices`` -- (default: ``None``) iterator container of vertex + labels correponding to which the looped edges are to be removed. If + ``vertices`` is ``None``, remove all loops. + + OUTPUT: + + - Nothing is returned, as a matching covered graph is already devoid of + any loops. + + EXAMPLES: + + A matching covered graph, for instance the Wheel graph of order six, is + always free of loops:: + + sage: W = graphs.WheelGraph(6) + sage: G = MatchingCoveredGraph(W) + sage: G + Matching covered wheel graph: graph on 6 vertices + sage: G.has_loops() + False + sage: G.allows_loops() + False + sage: G.add_edge(0, 0) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + sage: G.loops() + [] + sage: G.loop_edges() + [] + sage: G.loop_vertices() + [] + sage: G.number_of_loops() + 0 + sage: G.remove_loops() + sage: G.edges(sort=True) + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), + (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), + (3, 4, None), (4, 5, None)] + + A matching covered graph may support multiple edges, still no + loops are allowed:: + + sage: K = graphs.CompleteGraph(2) + sage: G = MatchingCoveredGraph(K) + sage: G.allow_multiple_edges(True) + sage: G + Matching covered complete graph: multi-graph on 2 vertices + sage: G.add_edge(0, 1, 'label') + sage: G.add_edge(0, 0) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + sage: G.edges(sort=False) + [(0, 1, None), (0, 1, 'label')] + sage: G.allows_loops() + False + sage: G.has_loops() + False + sage: G.loops() + [] + sage: G.loop_edges() + [] + sage: G.loop_vertices() + [] + sage: G.number_of_loops() + 0 + + .. SEEALSO:: + + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops` + """ + return @doc_index('Miscellaneous methods') def update_matching(self, matching): From 369eeba7cf4ccf43e34c175202c1c8fa35b20f35 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 18:29:39 +0530 Subject: [PATCH 059/210] updated allow_loops() --- src/sage/graphs/matching_covered_graph.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 7d035d2de81..5f5cfbe8a26 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1622,6 +1622,16 @@ def allow_loops(self, new, check=True): Traceback (most recent call last): ... ValueError: loops are not allowed in matching covered graphs + + .. SEEALSO:: + + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allows_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops` """ if new: raise ValueError('loops are not allowed in ' From cca3d4553aaf43561cfc88474bcdb26be42a9ea6 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 18:30:11 +0530 Subject: [PATCH 060/210] updated allows_loops() --- src/sage/graphs/matching_covered_graph.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 5f5cfbe8a26..66dfd8bc072 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1663,6 +1663,16 @@ def allows_loops(self): sage: G = MatchingCoveredGraph(P) sage: G.allows_loops() False + + .. SEEALSO:: + + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.has_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_edges`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loop_vertices`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`, + :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops` """ return False From 0a88de6e80e1533dbd8b93fc5cc4c5cecedf058d Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 19:02:49 +0530 Subject: [PATCH 061/210] updated remove_loops() --- src/sage/graphs/matching_covered_graph.py | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 66dfd8bc072..8b615310e4b 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2455,6 +2455,28 @@ def remove_loops(self, vertices=None): [] sage: G.number_of_loops() 0 + sage: G.remove_loops(vertices=[0, 1]) + sage: G.edges(sort=False) + [(0, 1, None), (0, 1, 'label')] + sage: G.remove_loops(vertices=[0..100]) + + Note that the parameter ``vertices`` must be either ``None`` or an + iterable:: + + sage: G.remove_loops(vertices='') + sage: G.edges(sort=False) + [(0, 1, None), (0, 1, 'label')] + sage: G.remove_loops(vertices=None) + sage: G.edges(sort=False) + [(0, 1, None), (0, 1, 'label')] + sage: G.remove_loops(vertices=0) + Traceback (most recent call last): + ... + TypeError: 'Integer' object is not iterable + sage: G.remove_loops(vertices=False) + Traceback (most recent call last): + ... + TypeError: 'bool' object is not iterable .. SEEALSO:: @@ -2466,6 +2488,12 @@ def remove_loops(self, vertices=None): :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`, :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops` """ + from collections.abc import Iterable + + if vertices is not None and not isinstance(vertices, Iterable): + raise TypeError(f'\'{vertices.__class__.__name__}\' ' + 'object is not iterable') + return @doc_index('Miscellaneous methods') From d78f6043e78bfbf056cdd2af524d8cb67eb02dd9 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 19:03:28 +0530 Subject: [PATCH 062/210] corrected a typo --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 8b615310e4b..e646667d4c7 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1936,7 +1936,7 @@ def get_matching(self): @doc_index('Overwritten methods') def has_loops(self): r""" - Check whether thare are loops in the (matching covered) graph. + Check whether there are loops in the (matching covered) graph. .. NOTE:: From cc07061dbda58513dfeae89e7c40c7e4ae961824 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 19:06:47 +0530 Subject: [PATCH 063/210] corrected the indentation --- src/sage/graphs/matching_covered_graph.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index e646667d4c7..77c461df37e 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2116,8 +2116,8 @@ def loop_edges(self, labels=True): INPUT: - - ``labels`` -- boolean (default: ``True``); whether returned edges have - labels (``(u,v,l)``) or not (``(u,v)``) + - ``labels`` -- boolean (default: ``True``); whether returned edges + have labels (``(u,v,l)``) or not (``(u,v)``). OUTPUT: From e98aae7f87e900328300dbbd819f4cb44f4b6a97 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 19:14:57 +0530 Subject: [PATCH 064/210] updated the indentation --- src/sage/graphs/matching_covered_graph.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 77c461df37e..0d482cf23b6 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2013,7 +2013,6 @@ def has_loops(self): :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`, :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`, :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops` - """ return False @@ -2200,7 +2199,7 @@ def loop_edges(self, labels=True): @doc_index('Overwritten methods') def loop_vertices(self): - """ + r""" Return a list of vertices with loops. .. NOTE:: @@ -2282,7 +2281,6 @@ def loop_vertices(self): :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.loops`, :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.number_of_loops`, :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.remove_loops` - """ return [] From 327222716590b5c4120d7808ad458058820f8c7b Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 19:17:06 +0530 Subject: [PATCH 065/210] updated the doctest of loop_edges() --- src/sage/graphs/matching_covered_graph.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 0d482cf23b6..7550455ae7c 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2133,10 +2133,6 @@ def loop_edges(self, labels=True): sage: G = MatchingCoveredGraph(H) sage: G Matching covered heawood graph: graph on 14 vertices - sage: G.has_loops() - False - sage: G.allows_loops() - False sage: G.add_edge(0, 0) Traceback (most recent call last): ... @@ -2145,10 +2141,6 @@ def loop_edges(self, labels=True): [] sage: G.loop_edges() [] - sage: G.loop_vertices() - [] - sage: G.number_of_loops() - 0 A matching covered graph may support multiple edges, still no loops are allowed:: @@ -2165,18 +2157,10 @@ def loop_edges(self, labels=True): ValueError: loops are not allowed in matching covered graphs sage: G.edges(sort=False) [(0, 1, None), (0, 1, 'label'), (0, 3, None), (1, 2, None), (2, 3, None)] - sage: G.allows_loops() - False - sage: G.has_loops() - False sage: G.loops() [] sage: G.loop_edges() [] - sage: G.loop_vertices() - [] - sage: G.number_of_loops() - 0 One may set the ``label`` to either ``True`` or ``False``:: From 023b05a43ae12b566b4f6df4a3672a311a817ec1 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 19:18:29 +0530 Subject: [PATCH 066/210] updated the doctest of loop_vertices() --- src/sage/graphs/matching_covered_graph.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 7550455ae7c..23038b1e139 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2208,22 +2208,12 @@ def loop_vertices(self): sage: G = MatchingCoveredGraph(M) sage: G Matching covered moebius ladder graph: graph on 8 vertices - sage: G.has_loops() - False - sage: G.allows_loops() - False sage: G.add_edge(0, 0) Traceback (most recent call last): ... ValueError: loops are not allowed in matching covered graphs - sage: G.loops() - [] - sage: G.loop_edges() - [] sage: G.loop_vertices() [] - sage: G.number_of_loops() - 0 A matching covered graph may support multiple edges, still no loops are allowed:: @@ -2243,18 +2233,8 @@ def loop_vertices(self): (1, 2, None), (1, 4, None), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (5, 7, None), (6, 7, None)] - sage: G.allows_loops() - False - sage: G.has_loops() - False - sage: G.loops() - [] - sage: G.loop_edges() - [] sage: G.loop_vertices() [] - sage: G.number_of_loops() - 0 .. SEEALSO:: From a2b4a9df9bef88b01d1a8aee4f246c96584176e4 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 19:19:24 +0530 Subject: [PATCH 067/210] updated the doctest of number_of_loops() --- src/sage/graphs/matching_covered_graph.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 23038b1e139..03cb4915d4f 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2276,18 +2276,10 @@ def number_of_loops(self): sage: G = MatchingCoveredGraph(T) sage: G Matching covered truncated biwheel graph: graph on 10 vertices - sage: G.has_loops() - False - sage: G.allows_loops() - False sage: G.add_edge(0, 0) Traceback (most recent call last): ... ValueError: loops are not allowed in matching covered graphs - sage: G.loops() - [] - sage: G.loop_edges() - [] sage: G.loop_vertices() [] sage: G.number_of_loops() @@ -2311,14 +2303,6 @@ def number_of_loops(self): (1, 2, None), (1, 6, None), (2, 3, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (4, 7, None), (5, 6, None)] - sage: G.allows_loops() - False - sage: G.has_loops() - False - sage: G.loops() - [] - sage: G.loop_edges() - [] sage: G.loop_vertices() [] sage: G.number_of_loops() From ca0f5cc9979691ac78a36dac3c037e0fca822f1e Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 19:20:14 +0530 Subject: [PATCH 068/210] updated the doctest of remove_loops() --- src/sage/graphs/matching_covered_graph.py | 24 ----------------------- 1 file changed, 24 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 03cb4915d4f..6d4bb1ff439 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2352,22 +2352,10 @@ def remove_loops(self, vertices=None): sage: G = MatchingCoveredGraph(W) sage: G Matching covered wheel graph: graph on 6 vertices - sage: G.has_loops() - False - sage: G.allows_loops() - False sage: G.add_edge(0, 0) Traceback (most recent call last): ... ValueError: loops are not allowed in matching covered graphs - sage: G.loops() - [] - sage: G.loop_edges() - [] - sage: G.loop_vertices() - [] - sage: G.number_of_loops() - 0 sage: G.remove_loops() sage: G.edges(sort=True) [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), @@ -2389,18 +2377,6 @@ def remove_loops(self, vertices=None): ValueError: loops are not allowed in matching covered graphs sage: G.edges(sort=False) [(0, 1, None), (0, 1, 'label')] - sage: G.allows_loops() - False - sage: G.has_loops() - False - sage: G.loops() - [] - sage: G.loop_edges() - [] - sage: G.loop_vertices() - [] - sage: G.number_of_loops() - 0 sage: G.remove_loops(vertices=[0, 1]) sage: G.edges(sort=False) [(0, 1, None), (0, 1, 'label')] From 6fe61f8382e355e93c9e38832e21c07c44d4496e Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 19:21:51 +0530 Subject: [PATCH 069/210] updated the doctest of has_loops() --- src/sage/graphs/matching_covered_graph.py | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 6d4bb1ff439..86bb5148378 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1967,14 +1967,6 @@ def has_loops(self): Traceback (most recent call last): ... ValueError: loops are not allowed in matching covered graphs - sage: G.loops() - [] - sage: G.loop_edges() - [] - sage: G.loop_vertices() - [] - sage: G.number_of_loops() - 0 A matching covered graph may support multiple edges, still no loops are allowed:: @@ -1995,15 +1987,11 @@ def has_loops(self): False sage: G.has_loops() False - sage: G.loops() - [] - sage: G.loop_edges() - [] - sage: G.loop_vertices() - [] - sage: G.number_of_loops() - 0 - + sage: G.allow_loops(True) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + .. SEEALSO:: :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`, From d8beed1bb7aa8860c2e9e009e31c0d428f5fd350 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 10 Nov 2024 20:52:49 +0530 Subject: [PATCH 070/210] removed whitespaces from a blankline --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 86bb5148378..2732e0b46a5 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1991,7 +1991,7 @@ def has_loops(self): Traceback (most recent call last): ... ValueError: loops are not allowed in matching covered graphs - + .. SEEALSO:: :meth:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph.allow_loops`, From 85a4b3e9a50a9a1807e5d32cc9afd722fdd81d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 10 Nov 2024 17:32:09 +0100 Subject: [PATCH 071/210] try to fix doc build --- .../rings/polynomial/q_integer_valued_polynomials.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index 609784f4074..950210be3f3 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -4,6 +4,12 @@ AUTHORS: - Frédéric Chapoton (2024-03): Initial version + +REFERENCES: + +.. [HaHo2017] Nate Harman and Sam Hopkins, *Quantum integer-valued + polynomials*, J. Alg. Comb. 2017, :doi:`10.1007/s10801-016-0717-3` + """ # *************************************************************************** # Copyright (C) 2024 Frédéric Chapoton @@ -95,11 +101,6 @@ class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): - ``R`` -- commutative ring - REFERENCES: - - - [HaHo2017] Nate Harman and Sam Hopkins, *Quantum integer-valued - polynomials*, J. Alg. Comb. 2017, :doi:`10.1007/s10801-016-0717-3` - EXAMPLES:: sage: F = QuantumValuedPolynomialRing(QQ).S(); F From 073a0e8ad9491e88af59ca305124dddbf270fc6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 10 Nov 2024 18:36:11 +0100 Subject: [PATCH 072/210] clean up the doc --- .../rings/polynomial/q_integer_valued_polynomials.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index 950210be3f3..bce88dcbc49 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -93,9 +93,8 @@ class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): Quantum-valued polynomial rings are commutative and associative algebras, with a basis indexed by integers. - The basis used here is given by `B[i] = \binom{i+n}{i}` for `i \in \NN`. - - There is a nice formula for the product, see [HaHo2017]_. + This is endowed with two bases, named ``B`` or ``Binomial`` + and ``S`` or ``Shifted``⋅ INPUT: @@ -813,8 +812,6 @@ def h_vector(self): .. SEEALSO:: :meth:`h_polynomial`, :meth:`fraction` - changement de base vers les (binomial(x+i,d))_{i=0..d} - EXAMPLES:: sage: A = QuantumValuedPolynomialRing(ZZ).S() @@ -847,8 +844,6 @@ def h_polynomial(self): .. SEEALSO:: :meth:`h_vector`, :meth:`fraction` - peut-etre pas dans le bon sens ? - EXAMPLES:: sage: A = QuantumValuedPolynomialRing(ZZ).S() @@ -943,7 +938,7 @@ def product_on_basis(self, n1, n2): - ``n1``, ``n2`` -- integers - The formula is taken from Theorem 3.4 in Harman-Hopkins. + The formula is taken from Theorem 3.4 in [HaHo2017]_. EXAMPLES:: From e5f20fd00707c06d1ab92981e12ae25d1c96d171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 10 Nov 2024 21:21:42 +0100 Subject: [PATCH 073/210] try to fix the doc again --- src/sage/rings/polynomial/q_integer_valued_polynomials.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index bce88dcbc49..1f201b27f9e 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -94,7 +94,7 @@ class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): algebras, with a basis indexed by integers. This is endowed with two bases, named ``B`` or ``Binomial`` - and ``S`` or ``Shifted``⋅ + and ``S`` or ``Shifted``. INPUT: From 5ffe9d07d182f6becf8c4a84015e47222129b644 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 11 Nov 2024 07:36:33 +0700 Subject: [PATCH 074/210] More explicit documentation on allowed arguments to %%cython --- src/sage/repl/ipython_extension.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index afb6d92dc77..80108d17722 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -342,7 +342,18 @@ def cython(self, line, cell): INPUT: - - ``line`` -- parsed as keyword arguments. See :func:`~sage.misc.cython.cython` for details. + - ``line`` -- parsed as keyword arguments. The allowed arguments are: + + - ``--verbose N`` / ``-v N`` + - ``--compile-message`` / ``-m`` + - ``--use-cache`` / ``-c`` + - ``--create-local-c-file`` / ``-l`` + - ``--annotate`` / ``-a`` + - ``--sage-namespace`` / ``-s`` + - ``--create-local-so-file`` / ``-o`` + - ``--no-compile-message``, ``--no-use-cache``, etc. (there is no short form for the ``--no-*`` flags) + + See :func:`~sage.misc.cython.cython` for details. - ``cell`` -- string; the Cython source code to process From 42b952874ae0b2aa710d2d867cbc5805b4edf28c Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 11 Nov 2024 14:00:49 +0700 Subject: [PATCH 075/210] Change to UsageError for consistency, and use argparse.BooleanOptionalAction --- src/sage/repl/ipython_extension.py | 38 +++++++++++------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index 80108d17722..a191992b650 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -382,28 +382,20 @@ def cython(self, line, cell): Test unrecognized arguments:: sage: # needs sage.misc.cython - sage: print("dummy line"); shell.run_cell(''' + sage: shell.run_cell(''' ....: %%cython --some-unrecognized-argument ....: print(1) ....: ''') - dummy line - ... - ArgumentError...Traceback (most recent call last) - ... - ArgumentError: unrecognized arguments: --some-unrecognized-argument + UsageError: unrecognized arguments: --some-unrecognized-argument Test ``--help`` is disabled:: sage: # needs sage.misc.cython - sage: print("dummy line"); shell.run_cell(''' + sage: shell.run_cell(''' ....: %%cython --help ....: print(1) ....: ''') - dummy line - ... - ArgumentError...Traceback (most recent call last) - ... - ArgumentError: unrecognized arguments: --help + UsageError: unrecognized arguments: --help Test invalid quotes:: @@ -426,21 +418,19 @@ class ExitCatchingArgumentParser(argparse.ArgumentParser): def error(self, message): # exit_on_error=False does not work completely in some Python versions # see https://stackoverflow.com/q/67890157 - raise argparse.ArgumentError(None, message) + # we raise UsageError to make the interface similar to what happens when e.g. + # IPython's ``%run`` gets unrecognized arguments + from IPython.core.error import UsageError + raise UsageError(message) parser = ExitCatchingArgumentParser(prog="%%cython", add_help=False) parser.add_argument("--verbose", "-v", type=int) - for (arg, arg_short) in [ - ("compile-message", "m"), - ("use-cache", "c"), - ("create-local-c-file", "l"), - ("annotate", "a"), - ("sage-namespace", "s"), - ("create-local-so-file", "o"), - ]: - action = parser.add_argument(f"--{arg}", f"-{arg_short}", action="store_true", default=None) - parser.add_argument(f"--no-{arg}", action="store_false", dest=action.dest, default=None) - + parser.add_argument("-m", "--compile-message", action=argparse.BooleanOptionalAction) + parser.add_argument("-c", "--use-cache", action=argparse.BooleanOptionalAction) + parser.add_argument("-l", "--create-local-c-file", action=argparse.BooleanOptionalAction) + parser.add_argument("-a", "--annotate", action=argparse.BooleanOptionalAction) + parser.add_argument("-s", "--sage-namespace", action=argparse.BooleanOptionalAction) + parser.add_argument("-o", "--create-local-so-file", action=argparse.BooleanOptionalAction) args = parser.parse_args(shlex.split(line)) return cython_compile(cell, **{k: v for k, v in args.__dict__.items() if v is not None}) From 582bc6dbcdbe862752eff30ed5fd7aad47cadeb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 11 Nov 2024 09:05:40 +0100 Subject: [PATCH 076/210] some suggestions done --- src/doc/en/reference/references/index.rst | 6 +- .../q_integer_valued_polynomials.py | 65 ++++++++++++------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 3d548b48511..8be1cf46cb8 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -3207,6 +3207,10 @@ REFERENCES: The Electronic Journal of Combinatorics 11 (2004), #R77. http://www.combinatorics.org/Volume_11/PDF/v11i1r77.pdf +.. [HaHo2017] Nate Harman and Sam Hopkins, + *Quantum integer-valued polynomials*, + J. Alg. Comb. 2017, :doi:`10.1007/s10801-016-0717-3` + .. [Hai1989] M.D. Haiman, *On mixed insertion, symmetry, and shifted Young tableaux*. Journal of Combinatorial Theory, Series A Volume 50, Number 2 (1989), pp. 196-225. @@ -3220,7 +3224,7 @@ REFERENCES: http://www-math.mit.edu/~hajiagha/pp11.ps .. [Han1960] Haim Hanani, - On quadruple systems, + *On quadruple systems*, pages 145--157, vol. 12, Canadian Journal of Mathematics, 1960 diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index 1f201b27f9e..415576db9c3 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -4,19 +4,16 @@ AUTHORS: - Frédéric Chapoton (2024-03): Initial version - -REFERENCES: - -.. [HaHo2017] Nate Harman and Sam Hopkins, *Quantum integer-valued - polynomials*, J. Alg. Comb. 2017, :doi:`10.1007/s10801-016-0717-3` - """ -# *************************************************************************** +# **************************************************************************** # Copyright (C) 2024 Frédéric Chapoton # -# Distributed under the terms of the GNU General Public License (GPL) +# 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.arith.misc import binomial from sage.categories.algebras import Algebras from sage.categories.realizations import Category_realization_of_parent @@ -159,6 +156,7 @@ def __init__(self, R) -> None: raise TypeError(msg) laurent = LaurentPolynomialRing(R, 'q') self._ground_ring = R + self._q = laurent.gen() cat = Algebras(laurent).Commutative().WithBasis() Parent.__init__(self, base=laurent, category=cat.WithRealizations()) @@ -262,6 +260,18 @@ def one_basis(self): """ return self.basis().keys()(0) + def q(self): + """ + Return the variable `q`. + + EXAMPLES:: + + sage: A = QuantumValuedPolynomialRing(QQ).S() + sage: A.q() + q + """ + return self.realization_of()._q + def degree_on_basis(self, m): r""" Return the degree of the basis element indexed by ``m``. @@ -299,6 +309,16 @@ def from_polynomial(self, p): B[1] sage: A.from_polynomial((B[2]+2*B[3]).polynomial()) B[2] + 2*B[3] + + TESTS:: + + sage: A = QuantumValuedPolynomialRing(QQ).B() + sage: q = polygen(QQ,'q') + sage: x = polygen(q.parent(),'x') + sage: A.from_polynomial(x**2/(q+1)+1) + Traceback (most recent call last): + ... + ValueError: not a polynomial with integer values : 1/(q + 1) is not a Laurent polynomial """ B = self.basis() poly = self._poly @@ -511,7 +531,7 @@ def product_on_basis(self, n1, n2): j = ZZ(n2) if j < i: j, i = i, j - q = self.base_ring().gen() + q = self.q() return self._from_dict({i + j - k: (-1)**k * q_binomial(i, k) * q_binomial(i + j - k, i) @@ -539,7 +559,7 @@ def _from_binomial_basis(self, i): """ i = ZZ(i) R = self.base_ring() - q = self.base_ring().gen() + q = self.q() return self._from_dict({k: R((-1)**(i - k) * q_binomial(i, k)) * q**(-i**2 + binomial(i - k, 2)) for k in range(i + 1)}) @@ -563,11 +583,13 @@ def from_h_vector(self, hv): """ B = self.basis() ring = self.base_ring() - q = ring.gen() + q = self.q() d = len(hv) - 1 m = matrix(ring, d + 1, d + 1, - lambda j, i: (-1)**(d - j) * q_binomial(d - i, d - j, q) * - q**(-d * (d - i) + binomial(d - j, 2))) + [(-1)**(d - j) * q_binomial(d - i, d - j, q) * + q**(-d * (d - i) + binomial(d - j, 2)) + for j in range(d + 1) + for i in range(d + 1)]) v = vector(ring, [hv[i] for i in range(d + 1)]) return sum(ring(c) * B[i] for i, c in enumerate(m * v)) @@ -599,7 +621,7 @@ def _element_constructor_(self, x): R = self.base_ring() # coercion via base ring x = R(x) - if x == 0: + if not x: return self.element_class(self, {}) return self.from_base_ring_from_one_basis(x) @@ -717,7 +739,6 @@ def _poly(self, i): return q_binomial_x(i, i) class Element(CombinatorialFreeModule.Element): - def umbra(self): """ Return the Bernoulli umbra. @@ -776,7 +797,7 @@ def variable_shift(self, k=1): return self A = self.parent() - q = A.base_ring().gen() + q = A.q() def on_basis(n): return {A._indices(j): q**(k * j) @@ -827,7 +848,7 @@ def h_vector(self): """ d = max(self.support()) ring = self.parent().base_ring() - q = ring.gen() + q = self.parent().q() def fn(j, i): return ((-1)**(d - j) * @@ -951,7 +972,7 @@ def product_on_basis(self, n1, n2): if j < i: j, i = i, j - q = self.base_ring().gen() + q = self.q() return self._from_dict({i + j - k: q_binomial(i, k) * q_binomial(i + j - k, i) @@ -978,7 +999,7 @@ def _from_shifted_basis(self, i): """ i = ZZ(i) R = self.base_ring() - q = self.base_ring().gen() + q = self.q() return self._from_dict({k: R(q_binomial(i, k)) * q**(k**2) for k in range(i + 1)}) @@ -1007,7 +1028,7 @@ def _element_constructor_(self, x): R = self.base_ring() # coercion via base ring x = R(x) - if x == 0: + if not x: return self.element_class(self, {}) return self.from_base_ring_from_one_basis(x) @@ -1155,7 +1176,7 @@ def variable_shift(self, k=1): return self A = self.parent() - q = A.base_ring().gen() + q = A.q() def on_basis(n): return {A._indices(j): q**((k + j - n) * j) From a8f95b40efbbe5f1d54a54831aabb7d7600206df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 11 Nov 2024 09:13:24 +0100 Subject: [PATCH 077/210] activate TestSuite --- src/sage/rings/polynomial/q_integer_valued_polynomials.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index 415576db9c3..eae1b6fd8e5 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -32,6 +32,7 @@ from sage.rings.rational_field import QQ from sage.sets.family import Family from sage.sets.non_negative_integers import NonNegativeIntegers +from sage.structure.element import parent from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation @@ -85,7 +86,7 @@ def q_binomial_x(m, n): class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): r""" - The quantum-valued polynomial ring on some generators over a base ring. + The quantum-valued polynomial ring over a base ring. Quantum-valued polynomial rings are commutative and associative algebras, with a basis indexed by integers. @@ -142,7 +143,7 @@ def __init__(self, R) -> None: sage: F = QuantumValuedPolynomialRing(QQ); F Quantum-Valued Polynomial Ring over Rational Field - sage: TestSuite(F).run() # not tested + sage: TestSuite(F).run() TESTS:: @@ -610,7 +611,7 @@ def _element_constructor_(self, x): sage: R(x) S[1] """ - P = x.parent() + P = parent(x) if isinstance(P, QuantumValuedPolynomialRing.Shifted): if P is self: return x From 8efd47bdecc1ef1b96c0daa9e20e9e0ecd6468ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 11 Nov 2024 10:15:04 +0100 Subject: [PATCH 078/210] doc --- src/sage/rings/polynomial/q_integer_valued_polynomials.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index eae1b6fd8e5..d16141a599a 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -98,6 +98,9 @@ class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): - ``R`` -- commutative ring + The ring ``R`` is not containing the variable `q`. Instead the + Laurent polynomial ring over ``R`` is used. + EXAMPLES:: sage: F = QuantumValuedPolynomialRing(QQ).S(); F From 704ed9f0e7aaf407a23fef6254e44539deaa89d1 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Mon, 11 Nov 2024 21:12:36 -0500 Subject: [PATCH 079/210] src/sage/groups/libgap_mixin.py: hide info warning for isomorphism checks GAP emits an "InfoWarning" message when it is checking for isomorphism between two groups that are not known to be finite. This message is only shown once, however, because after it checks for finiteness, it knows. We have to keep this in mind during tests. For example, File "src/sage/groups/finitely_presented_named.py", line 485, in sage.groups.finitely_presented_named.AlternatingPresentation Failed example: A1.is_isomorphic(A2), A1.order() Expected: (True, 1) Got: #I Forcing finiteness test (True, 1) These warnings are "normal" and there's nothing for the user to do. This commit hides them for the duration of the isomorphism check. Fixes https://github.com/sagemath/sage/issues/38889 --- src/sage/groups/libgap_mixin.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/sage/groups/libgap_mixin.py b/src/sage/groups/libgap_mixin.py index 3491c9f9db0..b14b050bd3b 100644 --- a/src/sage/groups/libgap_mixin.py +++ b/src/sage/groups/libgap_mixin.py @@ -946,4 +946,16 @@ def is_isomorphic(self, H): sage: F == G, G == H, F == H (False, False, False) """ - return self.gap().IsomorphismGroups(H.gap()) != libgap.fail + # If GAP doesn't know that the groups are finite, it will + # check. This emits an informational warning, and then + # annotates the groups as being finite (assuming they were) so + # that future isomorphism checks are silent. This can lead to + # apparent non-determinism in the output as statements are + # rearranged. There's nothing the user can do about this + # anyway, and it happens in trivial cases like the alternating + # group on one element, so we prefer to hide the warning. + old_warnlevel = libgap.InfoLevel(libgap.InfoWarning) + libgap.SetInfoLevel(libgap.InfoWarning, 0) + result = self.gap().IsomorphismGroups(H.gap()) != libgap.fail + libgap.SetInfoLevel(libgap.InfoWarning, old_warnlevel) + return result From 060f1159dc67f850a07001bed5ec0873a91d9aa0 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Mon, 11 Nov 2024 21:15:16 -0500 Subject: [PATCH 080/210] src/sage/**/*.py: remove GAP warnings from expected output The warning "#I Forcing finiteness test" should no longer be emitted when checking for group isomorphism, so we remove it from the expected output in a few places. Fixes https://github.com/sagemath/sage/issues/38889 --- src/sage/groups/cubic_braid.py | 2 -- src/sage/groups/finitely_presented.py | 4 ---- src/sage/groups/finitely_presented_named.py | 7 ------- src/sage/schemes/curves/projective_curve.py | 1 - 4 files changed, 14 deletions(-) diff --git a/src/sage/groups/cubic_braid.py b/src/sage/groups/cubic_braid.py index e407b9d1326..db826937103 100644 --- a/src/sage/groups/cubic_braid.py +++ b/src/sage/groups/cubic_braid.py @@ -640,7 +640,6 @@ class CubicBraidGroup(UniqueRepresentation, FinitelyPresentedGroup): sage: C3.gens() (t0, t1) sage: U3.is_isomorphic(C3) - #I Forcing finiteness test True sage: U3.as_classical_group() Subgroup generated by [(1,7,6)(3,19,14)(4,15,10)(5,11,18)(12,16,20), @@ -1604,7 +1603,6 @@ def as_permutation_group(self, use_classical=True): sage: C3 = CubicBraidGroup(3) sage: PC3 = C3.as_permutation_group() sage: assert C3.is_isomorphic(PC3) # random (with respect to the occurrence of the info message) - #I Forcing finiteness test sage: PC3.degree() 8 sage: c = C3([2,1-2]) diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index 9b5f7e422d6..b65566ebeb4 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -1080,7 +1080,6 @@ def direct_product(self, H, reduced=False, new_names=True): sage: C7 = G / [G.0**7]; C6 = G / [G.0**6] sage: C14 = G / [G.0**14]; C3 = G / [G.0**3] sage: C7.direct_product(C6).is_isomorphic(C14.direct_product(C3)) - #I Forcing finiteness test True sage: F = FreeGroup(2); D = F / [F([1,1,1,1,1]),F([2,2]),F([1,2])**2] sage: D.direct_product(D).as_permutation_group().is_isomorphic( @@ -1174,7 +1173,6 @@ def semidirect_product(self, H, hom, check=True, reduced=False): sage: alpha = (Q.gens(), [a,b]) sage: S2 = C2.semidirect_product(Q, ([C2.0],[alpha])) sage: S1.is_isomorphic(S2) - #I Forcing finiteness test True Dihedral groups can be constructed as semidirect products @@ -1233,8 +1231,6 @@ def semidirect_product(self, H, hom, check=True, reduced=False): sage: Se2 = D.semidirect_product(C ,id2) sage: Dp1 = C.direct_product(D) sage: Dp1.is_isomorphic(Se1), Dp1.is_isomorphic(Se2) - #I Forcing finiteness test - #I Forcing finiteness test (True, True) Most checks for validity of input are left to GAP to handle:: diff --git a/src/sage/groups/finitely_presented_named.py b/src/sage/groups/finitely_presented_named.py index 940d761ef49..20d847be0dd 100644 --- a/src/sage/groups/finitely_presented_named.py +++ b/src/sage/groups/finitely_presented_named.py @@ -451,7 +451,6 @@ def QuaternionPresentation(): sage: Q.order(), Q.is_abelian() (8, False) sage: Q.is_isomorphic(groups.presentation.DiCyclic(2)) - #I Forcing finiteness test True """ F = FreeGroup(['a','b']) @@ -554,12 +553,6 @@ def BinaryDihedralPresentation(n): ....: P = groups.presentation.BinaryDihedral(n) ....: M = groups.matrix.BinaryDihedral(n) ....: assert P.is_isomorphic(M) - #I Forcing finiteness test - #I Forcing finiteness test - #I Forcing finiteness test - #I Forcing finiteness test - #I Forcing finiteness test - #I Forcing finiteness test """ F = FreeGroup('x,y,z') x,y,z = F.gens() diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index 0729c5a98ad..d9a7321ade4 100755 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -1805,7 +1805,6 @@ def fundamental_group(self): ....: + (x-18*z)*(z^2+11*x*z-x^2)^2) sage: G0 = C.fundamental_group() # needs sirocco sage: G.is_isomorphic(G0) # needs sirocco - #I Forcing finiteness test True sage: C = P.curve(z) sage: C.fundamental_group() # needs sirocco From 0f9ecbd6a9b3641ecc244bf6ce7b235af59135de Mon Sep 17 00:00:00 2001 From: Benjamin Hackl Date: Tue, 12 Nov 2024 13:23:05 +0100 Subject: [PATCH 081/210] allow raising elements of SignGroup to powers from elements in other parents --- src/sage/groups/misc_gps/argument_groups.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sage/groups/misc_gps/argument_groups.py b/src/sage/groups/misc_gps/argument_groups.py index edbdb7b7bad..cc738595eb1 100644 --- a/src/sage/groups/misc_gps/argument_groups.py +++ b/src/sage/groups/misc_gps/argument_groups.py @@ -1462,8 +1462,13 @@ def __pow__(self, exponent): sage: S(-1)^3 # indirect doctest -1 """ + result = self._element_ ** exponent P = self.parent() - return P.element_class(P, self._element_ ** exponent) + try: + result = P.element_class(P, self._element_ ** exponent) + except (ValueError, TypeError): + pass + return result def __invert__(self): r""" From 82f7c17a11431a4eb161a63c1c08c219b929d42c Mon Sep 17 00:00:00 2001 From: Benjamin Hackl Date: Tue, 12 Nov 2024 13:28:04 +0100 Subject: [PATCH 082/210] add explict doctest and additional example to AsymptoticRing.coefficients_of_generating_function --- src/sage/groups/misc_gps/argument_groups.py | 9 +++++++++ src/sage/rings/asymptotic/asymptotic_ring.py | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/sage/groups/misc_gps/argument_groups.py b/src/sage/groups/misc_gps/argument_groups.py index cc738595eb1..8d539c90438 100644 --- a/src/sage/groups/misc_gps/argument_groups.py +++ b/src/sage/groups/misc_gps/argument_groups.py @@ -1461,6 +1461,15 @@ def __pow__(self, exponent): 1 sage: S(-1)^3 # indirect doctest -1 + + Check that the results may live in other parents too:: + + sage: x = SR.var('x') + sage: elem = S(-1)^x; elem # indirect doctest + (-1)^x + sage: elem.parent() + Symbolic Ring + """ result = self._element_ ** exponent P = self.parent() diff --git a/src/sage/rings/asymptotic/asymptotic_ring.py b/src/sage/rings/asymptotic/asymptotic_ring.py index d85f407872f..77fe4bdbfe0 100644 --- a/src/sage/rings/asymptotic/asymptotic_ring.py +++ b/src/sage/rings/asymptotic/asymptotic_ring.py @@ -4415,6 +4415,16 @@ def coefficients_of_generating_function(self, function, singularities, precision ....: 'n', precision=5)) True + Positive and negative singularities:: + + sage: def permutations_odd_cycles(z): + ....: return sqrt((1+z) / (1-z)) + sage: ex = B.coefficients_of_generating_function( + ....: permutations_odd_cycles, (1, -1,), precision=2, + ....: ); ex + sqrt(2)/sqrt(pi)*n^(-1/2) - 1/2*sqrt(1/2)/sqrt(pi)*n^(-3/2)*(-1)^n + + O(n^(-5/2)) + .. WARNING:: Once singular expansions around points other than infinity From 0fa96d5c7a7e10bdd31b8916447f3f7faab6e817 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Tue, 12 Nov 2024 20:21:23 +0700 Subject: [PATCH 083/210] %%cython: Remove infrequent short option --- src/sage/repl/ipython_extension.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index a191992b650..8edb4609d50 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -348,8 +348,8 @@ def cython(self, line, cell): - ``--compile-message`` / ``-m`` - ``--use-cache`` / ``-c`` - ``--create-local-c-file`` / ``-l`` - - ``--annotate`` / ``-a`` - - ``--sage-namespace`` / ``-s`` + - ``--annotate`` + - ``--sage-namespace`` - ``--create-local-so-file`` / ``-o`` - ``--no-compile-message``, ``--no-use-cache``, etc. (there is no short form for the ``--no-*`` flags) @@ -425,12 +425,12 @@ def error(self, message): parser = ExitCatchingArgumentParser(prog="%%cython", add_help=False) parser.add_argument("--verbose", "-v", type=int) - parser.add_argument("-m", "--compile-message", action=argparse.BooleanOptionalAction) - parser.add_argument("-c", "--use-cache", action=argparse.BooleanOptionalAction) - parser.add_argument("-l", "--create-local-c-file", action=argparse.BooleanOptionalAction) - parser.add_argument("-a", "--annotate", action=argparse.BooleanOptionalAction) - parser.add_argument("-s", "--sage-namespace", action=argparse.BooleanOptionalAction) - parser.add_argument("-o", "--create-local-so-file", action=argparse.BooleanOptionalAction) + parser.add_argument("--compile-message", "-m", action=argparse.BooleanOptionalAction) + parser.add_argument("--use-cache", "-c", action=argparse.BooleanOptionalAction) + parser.add_argument("--create-local-c-file", "-l", action=argparse.BooleanOptionalAction) + parser.add_argument("--annotate", action=argparse.BooleanOptionalAction) + parser.add_argument("--sage-namespace", action=argparse.BooleanOptionalAction) + parser.add_argument("--create-local-so-file", "-o", action=argparse.BooleanOptionalAction) args = parser.parse_args(shlex.split(line)) return cython_compile(cell, **{k: v for k, v in args.__dict__.items() if v is not None}) From 531b1d7de662ee53a30a95786f203f5866bb6ce1 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Tue, 12 Nov 2024 22:11:13 +0700 Subject: [PATCH 084/210] Apply suggested changes --- src/sage/repl/ipython_extension.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index 8edb4609d50..a1eec499b8e 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -351,7 +351,7 @@ def cython(self, line, cell): - ``--annotate`` - ``--sage-namespace`` - ``--create-local-so-file`` / ``-o`` - - ``--no-compile-message``, ``--no-use-cache``, etc. (there is no short form for the ``--no-*`` flags) + - ``--no-compile-message``, ``--no-use-cache``, etc. See :func:`~sage.misc.cython.cython` for details. @@ -377,8 +377,6 @@ def cython(self, line, cell): TESTS: - See :mod:`sage.repl.interpreter` for explanation of the dummy line. - Test unrecognized arguments:: sage: # needs sage.misc.cython @@ -397,7 +395,7 @@ def cython(self, line, cell): ....: ''') UsageError: unrecognized arguments: --help - Test invalid quotes:: + Test invalid quotes (see :mod:`sage.repl.interpreter` for explanation of the dummy line):: sage: # needs sage.misc.cython sage: print("dummy line"); shell.run_cell(''' From 86635fe06560122589a95db7c14fb2ba558646ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 13 Nov 2024 17:28:35 +0100 Subject: [PATCH 085/210] a little more doc --- .../rings/polynomial/q_integer_valued_polynomials.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index d16141a599a..954f74139ed 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -1,6 +1,8 @@ r""" Quantum-valued polynomial rings +This provide a `q`-analogue of the :class:`~sage.rings.polynomials.integer_valued_polynomials.IntegerValuedPolynomialRing`. + AUTHORS: - Frédéric Chapoton (2024-03): Initial version @@ -64,6 +66,10 @@ def q_binomial_x(m, n): When evaluated at the `q`-integer `[k]_q`, this gives the usual `q`-binomial coefficient `[m + k, n]_q`. + INPUT: + + - ``m`` and ``n`` -- positive integers + EXAMPLES:: sage: from sage.combinat.q_analogues import q_int @@ -91,7 +97,7 @@ class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): Quantum-valued polynomial rings are commutative and associative algebras, with a basis indexed by integers. - This is endowed with two bases, named ``B`` or ``Binomial`` + This algebra is endowed with two bases, named ``B`` or ``Binomial`` and ``S`` or ``Shifted``. INPUT: @@ -99,7 +105,7 @@ class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): - ``R`` -- commutative ring The ring ``R`` is not containing the variable `q`. Instead the - Laurent polynomial ring over ``R`` is used. + Laurent polynomial ring over ``R`` is built and used. EXAMPLES:: @@ -229,6 +235,8 @@ def ground_ring(self): """ Return the ring of coefficients. + This ring is not supposed to contain the variable `q`. + EXAMPLES:: sage: A = QuantumValuedPolynomialRing(QQ).S() From 578478425a5a5e27f8d8c9c01b1e5720310e444f Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:35:07 +0700 Subject: [PATCH 086/210] Remove more short options --- src/sage/repl/ipython_extension.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index a1eec499b8e..e47eba38179 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -345,12 +345,12 @@ def cython(self, line, cell): - ``line`` -- parsed as keyword arguments. The allowed arguments are: - ``--verbose N`` / ``-v N`` - - ``--compile-message`` / ``-m`` - - ``--use-cache`` / ``-c`` - - ``--create-local-c-file`` / ``-l`` + - ``--compile-message`` + - ``--use-cache`` + - ``--create-local-c-file`` - ``--annotate`` - ``--sage-namespace`` - - ``--create-local-so-file`` / ``-o`` + - ``--create-local-so-file`` - ``--no-compile-message``, ``--no-use-cache``, etc. See :func:`~sage.misc.cython.cython` for details. @@ -423,12 +423,12 @@ def error(self, message): parser = ExitCatchingArgumentParser(prog="%%cython", add_help=False) parser.add_argument("--verbose", "-v", type=int) - parser.add_argument("--compile-message", "-m", action=argparse.BooleanOptionalAction) - parser.add_argument("--use-cache", "-c", action=argparse.BooleanOptionalAction) - parser.add_argument("--create-local-c-file", "-l", action=argparse.BooleanOptionalAction) + parser.add_argument("--compile-message", action=argparse.BooleanOptionalAction) + parser.add_argument("--use-cache", action=argparse.BooleanOptionalAction) + parser.add_argument("--create-local-c-file", action=argparse.BooleanOptionalAction) parser.add_argument("--annotate", action=argparse.BooleanOptionalAction) parser.add_argument("--sage-namespace", action=argparse.BooleanOptionalAction) - parser.add_argument("--create-local-so-file", "-o", action=argparse.BooleanOptionalAction) + parser.add_argument("--create-local-so-file", action=argparse.BooleanOptionalAction) args = parser.parse_args(shlex.split(line)) return cython_compile(cell, **{k: v for k, v in args.__dict__.items() if v is not None}) From cf4fe6ff5a6810589733c536823f44e1c80161d4 Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Thu, 14 Nov 2024 12:06:23 -0500 Subject: [PATCH 087/210] #38967 negative order of generator of AbelianGroup --- src/sage/groups/abelian_gps/abelian_group.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/sage/groups/abelian_gps/abelian_group.py b/src/sage/groups/abelian_gps/abelian_group.py index 0ad20d9d4fa..f69b7560338 100644 --- a/src/sage/groups/abelian_gps/abelian_group.py +++ b/src/sage/groups/abelian_gps/abelian_group.py @@ -365,6 +365,13 @@ def _normalize(n, gens_orders=None, names='f'): Traceback (most recent call last): ... TypeError: unable to convert 's' to an integer + + Verify that :issue:`38967` is fixed:: + + sage: AbelianGroup([-4]) + Traceback (most recent call last): + ... + ValueError: orders of generators cannot be negative but they are (-4,) """ if gens_orders is None: if isinstance(n, (list, tuple)): @@ -376,6 +383,8 @@ def _normalize(n, gens_orders=None, names='f'): if len(gens_orders) < n: gens_orders = [0] * (n - len(gens_orders)) + list(gens_orders) gens_orders = tuple(ZZ(i) for i in gens_orders) + if any(i < 0 for i in gens_orders): + raise ValueError(f'orders of generators cannot be negative but they are {gens_orders}') if len(gens_orders) > n: raise ValueError('gens_orders (='+str(gens_orders)+') must have length n (='+str(n)+')') if isinstance(names, list): From 7c54e210514934d5d449177df945dec70367b394 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 15 Nov 2024 18:47:52 +0700 Subject: [PATCH 088/210] Add numpy_util.pxd file for consistency --- src/sage/modules/numpy_util.pxd | 6 ++++++ src/sage/modules/numpy_util.pyx | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 src/sage/modules/numpy_util.pxd diff --git a/src/sage/modules/numpy_util.pxd b/src/sage/modules/numpy_util.pxd new file mode 100644 index 00000000000..95d84956039 --- /dev/null +++ b/src/sage/modules/numpy_util.pxd @@ -0,0 +1,6 @@ +from libc.stdint cimport uintptr_t +from sage.libs.m4ri cimport * + +cpdef int set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) except -1 +# Note: we don't actually need ``cimport`` to work, which means this header file is not used in practice +# neither do we need ``cpdef`` (``def`` is sufficient) diff --git a/src/sage/modules/numpy_util.pyx b/src/sage/modules/numpy_util.pyx index 1b1384205ca..a3a90446694 100644 --- a/src/sage/modules/numpy_util.pyx +++ b/src/sage/modules/numpy_util.pyx @@ -24,14 +24,15 @@ cdef set_mzd_from_numpy_unsafe(mzd_t* entries, np.ndarray[numpy_integral, ndim=1 mzd_write_bit(entries, 0, i, x[i] & 1) -def set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x): +cpdef int set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) except -1: """ - Set the entries in ``entries`` from numpy array ``x``. + Set the entries in ``entries_addr`` from numpy array ``x``. INPUT: - ``entries_addr`` -- must be a ``mzd_t*`` casted to ``uintptr_t``; the casting - is necessary to pass it through Python boundary because of lazy import + is necessary to pass it through Python boundary because of lazy import. + Do not pass arbitrary integer value here, will crash the program. - ``degree`` -- the length of the array From af3b81b7b27bf560c193b94da744bb08a10ab25c Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Fri, 15 Nov 2024 19:34:51 +0100 Subject: [PATCH 089/210] Fix build of meataxe extension with meson meataxe is not a library, the library is called mtx and is already searched for --- src/meson.build | 2 -- src/sage/libs/meson.build | 2 +- src/sage/matrix/meson.build | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/meson.build b/src/meson.build index 12d82fa91c3..a0e330af0b7 100644 --- a/src/meson.build +++ b/src/meson.build @@ -112,8 +112,6 @@ singular = dependency('Singular') maxima = find_program('maxima', required: true) # Cannot be found via pkg-config ntl = cc.find_library('ntl') -# Cannot be found via pkg-config -meataxe = cc.find_library('meataxe', required: false, disabler: true) # Meson currently ignores include_directories for Cython modules, so we # have to add them manually. diff --git a/src/sage/libs/meson.build b/src/sage/libs/meson.build index 61b36da51f5..2e28ef8ff79 100644 --- a/src/sage/libs/meson.build +++ b/src/sage/libs/meson.build @@ -36,7 +36,7 @@ foreach name, pyx : extension_data if name == 'sirocco' deps += [sirocco] elif name == 'meataxe' - deps += [mtx, meataxe] + deps += [mtx] endif py.extension_module( diff --git a/src/sage/matrix/meson.build b/src/sage/matrix/meson.build index c0841d77f34..d2d6e4abbbd 100644 --- a/src/sage/matrix/meson.build +++ b/src/sage/matrix/meson.build @@ -120,7 +120,7 @@ foreach name, pyx : extension_data zlib, ] if name == 'matrix_gfpn_dense' - dependencies += [mtx, meataxe] + dependencies += [mtx] endif py.extension_module( From def85c5809bc188daffbb4e714dbc1a2a81e82b6 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 14 Nov 2024 23:21:41 +0100 Subject: [PATCH 090/210] support incomparable labels --- src/sage/combinat/set_partition.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/set_partition.py b/src/sage/combinat/set_partition.py index 092e2f9dbb7..5078003c6f2 100644 --- a/src/sage/combinat/set_partition.py +++ b/src/sage/combinat/set_partition.py @@ -73,7 +73,11 @@ def _repr_(self): sage: S([[1,3],[2,4]]) {{1, 3}, {2, 4}} """ - return '{' + ', '.join('{' + repr(sorted(x))[1:-1] + '}' for x in self) + '}' + try: + s = [sorted(x) for x in self] + except TypeError: + s = [sorted(x, key=str) for x in self] + return '{' + ', '.join('{' + repr(x)[1:-1] + '}' for x in s) + '}' def __hash__(self): """ @@ -532,7 +536,7 @@ def pre_conjugate(sp): class SetPartition(AbstractSetPartition, - metaclass=InheritComparisonClasscallMetaclass): + metaclass=InheritComparisonClasscallMetaclass): r""" A partition of a set. @@ -620,7 +624,11 @@ def __init__(self, parent, s, check=True): {} """ self._latex_options = {} - ClonableArray.__init__(self, parent, sorted(map(frozenset, s), key=min), check=check) + try: + s = sorted(map(frozenset, s), key=min) + except TypeError: + s = sorted(map(frozenset, s), key=lambda b: min(str(b))) + ClonableArray.__init__(self, parent, s, check=check) def check(self): """ @@ -2821,7 +2829,11 @@ def __iter__(self): sage: SetPartitions(["a", "b"]).list() [{{'a', 'b'}}, {{'a'}, {'b'}}] """ - for sp in set_partition_iterator(sorted(self._set)): + try: + s = sorted(self._set) + except TypeError: + s = sorted(self._set, key=str) + for sp in set_partition_iterator(s): yield self.element_class(self, sp, check=False) def base_set(self): @@ -3179,7 +3191,11 @@ def __iter__(self): sage: SetPartitions(["a", "b", "c"], 2).list() [{{'a', 'c'}, {'b'}}, {{'a'}, {'b', 'c'}}, {{'a', 'b'}, {'c'}}] """ - for sp in set_partition_iterator_blocks(sorted(self._set), self._k): + try: + s = sorted(self._set) + except TypeError: + s = sorted(self._set, key=str) + for sp in set_partition_iterator_blocks(s, self._k): yield self.element_class(self, sp, check=False) def __contains__(self, x): From cf3cdf35546a0d80525fdbcb389fd65eb371a4a9 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 16 Nov 2024 11:00:48 +0100 Subject: [PATCH 091/210] support left and right actions, default right --- src/sage/rings/species.py | 114 ++++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 30 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index bcda9a9f510..b487eb4692d 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -31,7 +31,7 @@ """ -from itertools import accumulate, chain +from itertools import accumulate, chain, product from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.modules import Modules @@ -730,16 +730,17 @@ def _an_element_(self): Element = AtomicSpeciesElement -def _stabilizer_subgroups(G, X, a): +def _stabilizer_subgroups(G, X, a, side='right', check=True): r""" Return subgroups conjugate to the stabilizer subgroups of the - given (left) group action. + given group action. INPUT: - ``G`` -- the acting group - ``X`` -- the set ``G`` is acting on - - ``a`` -- the (left) action + - ``a`` -- the action, a function `G\times X\to X` if ``side`` is + ``'left'``, `X\times G\to X` if ``side`` is ``'right'`` EXAMPLES:: @@ -747,17 +748,17 @@ def _stabilizer_subgroups(G, X, a): sage: S = SymmetricGroup(4) sage: X = SetPartitions(S.degree(), [2,2]) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) - sage: _stabilizer_subgroups(S, X, a) + sage: _stabilizer_subgroups(S, X, a, side='left') [Permutation Group with generators [(1,2), (1,3)(2,4)]] sage: S = SymmetricGroup(8) sage: X = SetPartitions(S.degree(), [3,3,2]) - sage: _stabilizer_subgroups(S, X, a) + sage: _stabilizer_subgroups(S, X, a, side='left', check=False) [Permutation Group with generators [(7,8), (6,7), (4,5), (1,3)(2,6)(4,7)(5,8), (1,3)]] sage: S = SymmetricGroup(4) sage: X = SetPartitions(S.degree(), 2) - sage: _stabilizer_subgroups(S, X, a) + sage: _stabilizer_subgroups(S, X, a, side='left') [Permutation Group with generators [(1,4), (1,3,4)], Permutation Group with generators [(1,3)(2,4), (1,4)]] @@ -766,19 +767,54 @@ def _stabilizer_subgroups(G, X, a): sage: S = SymmetricGroup([1,2,4,5,3,6]).young_subgroup([4, 2]) sage: X = [pi for pi in SetPartitions(6, [3,3]) if all(sum(1 for e in b if e % 3) == 2 for b in pi)] - sage: _stabilizer_subgroups(S, X, a) + sage: _stabilizer_subgroups(S, X, a, side='left') [Permutation Group with generators [(1,2), (4,5), (1,4)(2,5)(3,6)]] TESTS:: - sage: _stabilizer_subgroups(SymmetricGroup(2), [1], lambda pi, H: H) + sage: _stabilizer_subgroups(SymmetricGroup(2), [1], lambda pi, H: H, side='left') [Permutation Group with generators [(1,2)]] + + sage: _stabilizer_subgroups(SymmetricGroup(2), [1, 1], lambda pi, H: H, side='left') + Traceback (most recent call last): + ... + ValueError: The argument X must be a set, but [1, 1] contains duplicates + + sage: G = SymmetricGroup(3) + sage: X = [1, 2, 3] + sage: _stabilizer_subgroups(G, X, lambda pi, x: pi(x), side='left') + [Permutation Group with generators [(2,3)]] + sage: _stabilizer_subgroups(G, X, lambda x, pi: pi(x), side='right') + Traceback (most recent call last): + ... + ValueError: The given function is not a right group action: g=(1,3,2), h=(2,3), x=1 do not satisfy the condition """ to_gap = {x: i for i, x in enumerate(X, 1)} - X = set(X) # because orbit_decomposition turns X into a set - g_orbits = [orbit_decomposition(X, lambda x: a(g, x)) - for g in G.gens()] + X_set = set(X) # because orbit_decomposition turns X into a set + + if len(X_set) != len(X): + raise ValueError(f"The argument X must be a set, but {X} contains duplicates") + + if side == "left": + if check: + for g, h, x in product(G, G, X): + # Warning: the product in permutation groups is left-to-right composition + if not a(h * g, x) == a(g, a(h, x)): + raise ValueError(f"The given function is not a left group action: g={g}, h={h}, x={x} do not satisfy the condition") + + g_orbits = [orbit_decomposition(X_set, lambda x: a(g, x)) + for g in G.gens()] + elif side == "right": + if check: + for g, h, x in product(G, G, X): + if not a(x, h * g) == a(a(x, g), h): + raise ValueError(f"The given function is not a right group action: g={g}, h={h}, x={x} do not satisfy the condition") + + g_orbits = [orbit_decomposition(X_set, lambda x: a(x, g)) + for g in G.gens()] + else: + raise ValueError(f"The argument side must be 'left' or 'right' but is {side}") gens = [PermutationGroupElement([tuple([to_gap[x] for x in o]) for o in g_orbit]) @@ -873,13 +909,15 @@ def _element_constructor_(self, G, pi=None, check=True): INPUT: - ``G`` -- element of ``self`` (in this case ``pi`` must be - ``None``) permutation group, or pair ``(X, a)`` consisting - of a finite set and a transitive action + ``None``) or permutation group, or triple ``(X, a, side)`` + consisting of a finite set, a transitive action and + a string 'left' or 'right'; the side can be omitted, it is + then assumed to be 'right' - ``pi`` -- ``dict`` mapping sorts to iterables whose union is the domain of ``G`` (if ``G`` is a permutation group) or the domain of the acting symmetric group (if ``G`` is a - pair ``(X, a)``); if `k=1` and ``G`` is a permutation - group, ``pi`` can be omitted + triple ``(X, a, side)``); if `k=1` and ``G`` is a + permutation group, ``pi`` can be omitted - ``check`` -- boolean (default: ``True``); skip input checking if ``False`` @@ -901,11 +939,11 @@ def _element_constructor_(self, G, pi=None, check=True): sage: M = MolecularSpecies("X") sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) sage: X = SetPartitions(4, [2, 2]) - sage: M((X, a), {0: X.base_set()}) + sage: M((X, a, 'left'), {0: X.base_set()}) P_4 sage: X = SetPartitions(8, [4, 2, 2]) - sage: M((X, a), {0: X.base_set()}) + sage: M((X, a, 'left'), {0: X.base_set()}, check=False) E_4*P_4 TESTS:: @@ -922,7 +960,7 @@ def _element_constructor_(self, G, pi=None, check=True): sage: X = SetPartitions(4, 2) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) - sage: M((X, a), {0: [1,2], 1: [3,4]}) + sage: M((X, a, 'left'), {0: [1,2], 1: [3,4]}) Traceback (most recent call last): ... ValueError: action is not transitive @@ -962,18 +1000,25 @@ def _element_constructor_(self, G, pi=None, check=True): ... ValueError: 0 must be a permutation group or a pair (X, a) specifying a group action of the symmetric group on pi=None + """ if parent(G) is self: # pi cannot be None because of framework raise ValueError("cannot reassign sorts to a molecular species") if isinstance(G, tuple): - X, a = G + if len(G) == 2: + X, a = G + side = 'right' + else: + X, a, side = G + if side not in ['left', 'right']: + raise ValueError(f"the side must be 'right' or 'left', but is {side}") dompart = [sorted(pi.get(s, [])) for s in range(self._arity)] S = PermutationGroup([tuple(b) for b in dompart if len(b) > 2] + [(b[0], b[1]) for b in dompart if len(b) > 1], domain=list(chain(*dompart))) - H = _stabilizer_subgroups(S, X, a) + H = _stabilizer_subgroups(S, X, a, side=side, check=check) if len(H) > 1: raise ValueError("action is not transitive") G = H[0] @@ -2072,8 +2117,10 @@ def _element_constructor_(self, G, pi=None, check=True): INPUT: - ``G`` -- element of ``self`` (in this case ``pi`` must be - ``None``), permutation group, or pair ``(X, a)`` consisting - of a finite set and an action + ``None``) or permutation group, or triple ``(X, a, side)`` + consisting of a finite set, an action and a string 'left' + or 'right'; the side can be omitted, it is then assumed to + be 'right' - ``pi`` -- ``dict`` mapping sorts to iterables whose union is the domain of ``G`` (if ``G`` is a permutation group) or the domain of the acting symmetric group (if ``G`` is a @@ -2091,13 +2138,13 @@ def _element_constructor_(self, G, pi=None, check=True): sage: X = SetPartitions(4, 2) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) - sage: P((X, a), {0: [1,2], 1: [3,4]}) + sage: P((X, a, 'left'), {0: [1,2], 1: [3,4]}) E_2(X)*E_2(Y) + X^2*E_2(Y) + E_2(XY) + Y^2*E_2(X) sage: P = PolynomialSpecies(ZZ, ["X"]) sage: X = SetPartitions(4, 2) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) - sage: P((X, a), {0: [1,2,3,4]}) + sage: P((X, a, 'left'), {0: [1,2,3,4]}) X*E_3 + P_4 The species of permutation groups:: @@ -2106,10 +2153,10 @@ def _element_constructor_(self, G, pi=None, check=True): sage: n = 4 sage: S = SymmetricGroup(n) sage: X = S.subgroups() - sage: def act(pi, G): # WARNING: returning H does not work because of equality problems + sage: def act(G, pi): # WARNING: returning H does not work because of equality problems ....: H = S.subgroup(G.conjugate(pi).gens()) ....: return next(K for K in X if K == H) - sage: P((X, act), {0: range(1, n+1)}) + sage: P((X, act), {0: range(1, n+1)}, check=False) 4*E_4 + 4*P_4 + E_2^2 + 2*X*E_3 Create a multisort species given an action:: @@ -2127,7 +2174,7 @@ def _element_constructor_(self, G, pi=None, check=True): ....: if r == t and c == b: ....: return r, c ....: raise ValueError - sage: P((X, lambda g, x: act(x[0], x[1], g)), pi) + sage: P((X, lambda g, x: act(x[0], x[1], g), 'left'), pi) 2*Y*E_2(X) TESTS:: @@ -2157,18 +2204,25 @@ def _element_constructor_(self, G, pi=None, check=True): ValueError: 1/2 must be an element of the base ring, a permutation group or a pair (X, a) specifying a group action of the symmetric group on pi=None + """ if parent(G) is self: # pi cannot be None because of framework raise ValueError("cannot reassign sorts to a polynomial species") if isinstance(G, tuple): - X, a = G + if len(G) == 2: + X, a = G + side = 'right' + else: + X, a, side = G + if side not in ['left', 'right']: + raise ValueError(f"the side must be 'right' or 'left', but is {side}") dompart = [sorted(pi.get(s, [])) for s in range(self._arity)] S = PermutationGroup([tuple(b) for b in dompart if len(b) > 2] + [(b[0], b[1]) for b in dompart if len(b) > 1], domain=list(chain(*dompart))) - Hs = _stabilizer_subgroups(S, X, a) + Hs = _stabilizer_subgroups(S, X, a, side=side, check=check) return self.sum_of_terms((self._indices(H, pi, check=check), ZZ.one()) for H in Hs) From ded10b4e4dd0fb1d77df18cac5f8f923a12c7a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 16 Nov 2024 15:42:34 +0100 Subject: [PATCH 092/210] a few PERF4 suggestions by ruff fixed --- src/sage/modular/abvar/abvar.py | 10 +++++----- src/sage/modular/etaproducts.py | 12 +++++------- src/sage/modular/hecke/algebra.py | 7 ++----- src/sage/modular/hecke/ambient_module.py | 6 ++---- src/sage/modular/hypergeometric_motive.py | 4 ++-- src/sage/modular/modsym/ambient.py | 6 +++--- src/sage/modular/overconvergent/hecke_series.py | 12 ++++-------- src/sage/rings/valuation/valuation.py | 2 +- src/sage/rings/valuation/valuation_space.py | 10 ++++++---- src/sage/rings/valuation/value_group.py | 4 ++-- src/sage/tensor/modules/finite_rank_free_module.py | 2 +- src/sage/tensor/modules/free_module_basis.py | 4 ++-- src/sage/typeset/character_art.py | 13 +++++++------ 13 files changed, 42 insertions(+), 50 deletions(-) diff --git a/src/sage/modular/abvar/abvar.py b/src/sage/modular/abvar/abvar.py index 92b1e9f9abe..c1e0733f38c 100644 --- a/src/sage/modular/abvar/abvar.py +++ b/src/sage/modular/abvar/abvar.py @@ -4501,11 +4501,11 @@ def decomposition(self, simple=True, bound=None): else: X = A.decomposition(bound=bound) for B in X: - for t in divisors(M // N): - D.append(ModularAbelianVariety_modsym(B.degeneracy_map(M, t).image(), - is_simple=True, newform_level=(N, G), - isogeny_number=isogeny_number, - number=(t, M))) + D.extend(ModularAbelianVariety_modsym(B.degeneracy_map(M, t).image(), + is_simple=True, newform_level=(N, G), + isogeny_number=isogeny_number, + number=(t, M)) + for t in divisors(M // N)) isogeny_number += 1 elif A == amb.cuspidal_submodule(): D = [ModularAbelianVariety_modsym(B) diff --git a/src/sage/modular/etaproducts.py b/src/sage/modular/etaproducts.py index a063255c6a6..4b2d1e6ea2d 100644 --- a/src/sage/modular/etaproducts.py +++ b/src/sage/modular/etaproducts.py @@ -541,8 +541,8 @@ def basis(self, reduce=True) -> list: for di in divs: # generate a row of relation matrix row = [Mod(di, 24) - Mod(N, 24), Mod(N // di, 24) - Mod(1, 24)] - for p in primedivs: - row.append(Mod(12 * (N // di).valuation(p), 24)) + row.extend(Mod(12 * (N // di).valuation(p), 24) + for p in primedivs) rows.append(row) M = matrix(IntegerModRing(24), rows) @@ -717,8 +717,8 @@ def AllCusps(N) -> list: if n == 1: c.append(CuspFamily(N, d)) elif n > 1: - for i in range(n): - c.append(CuspFamily(N, d, label=str(i + 1))) + c.extend(CuspFamily(N, d, label=str(i + 1)) + for i in range(n)) return c @@ -1036,9 +1036,7 @@ def _eta_relations_helper(eta1, eta2, degree, qexp_terms, labels, verbose): if verbose: print("Trying all coefficients from q^%s to q^%s inclusive" % (-pole_at_infinity, -pole_at_infinity + qexp_terms - 1)) - rows = [] - for j in range(qexp_terms): - rows.append([]) + rows = [[] for _ in range(qexp_terms)] for i in indices: func = (eta1**i[0] * eta2**i[1]).qexp(qexp_terms) for j in range(qexp_terms): diff --git a/src/sage/modular/hecke/algebra.py b/src/sage/modular/hecke/algebra.py index 383a4e0c035..7c209d146b6 100644 --- a/src/sage/modular/hecke/algebra.py +++ b/src/sage/modular/hecke/algebra.py @@ -91,7 +91,6 @@ def _heckebasis(M): MM = MatrixSpace(QQ, d) S = [] Denom = [] - B = [] B1 = [] for i in range(1, M.hecke_bound() + 1): v = M.hecke_operator(i).matrix() @@ -99,11 +98,9 @@ def _heckebasis(M): Denom.append(den) S.append(v) den = lcm(Denom) - for m in S: - B.append(WW((den * m).list())) + B = [WW((den * m).list()) for m in S] UU = WW.submodule(B) - B = UU.basis() - for u in B: + for u in UU.basis(): u1 = u.list() m1 = M.hecke_algebra()(MM(u1), check=False) B1.append((1 / den) * m1) diff --git a/src/sage/modular/hecke/ambient_module.py b/src/sage/modular/hecke/ambient_module.py index 3ce44fa63ce..0e769d47ace 100644 --- a/src/sage/modular/hecke/ambient_module.py +++ b/src/sage/modular/hecke/ambient_module.py @@ -242,10 +242,8 @@ def decomposition_matrix(self): try: return self.__decomposition_matrix_cache except AttributeError: - rows = [] - for A in self.decomposition(): - for x in A.basis(): - rows.append(x.list()) + rows = [x.list() for A in self.decomposition() + for x in A.basis()] A = matrix_space.MatrixSpace(self.base_ring(), self.rank())(rows) self.__decomposition_matrix_cache = A return self.__decomposition_matrix_cache diff --git a/src/sage/modular/hypergeometric_motive.py b/src/sage/modular/hypergeometric_motive.py index 5418a1fff58..e236d3b7b91 100644 --- a/src/sage/modular/hypergeometric_motive.py +++ b/src/sage/modular/hypergeometric_motive.py @@ -1933,13 +1933,13 @@ def euler_factor(self, t, p, deg=None, cache_p=False): P = PolynomialRing(ZZ, 'T') if t.numerator() % p == 0 or t.denominator() % p == 0: ans = P.one() - for m in set(j for i in self.cyclotomic_data() for j in i): + for m in {j for i in self.cyclotomic_data() for j in i}: ans *= self.euler_factor_tame_contribution(t, p, m, deg) if deg is not None: ans = ans.truncate(deg + 1) return ans # now p is good, or p is tame and t is a p-adic unit - elif (t-1) % p == 0: + elif (t - 1) % p == 0: typ = "mult" d = self.degree() - 1 if d % 2: diff --git a/src/sage/modular/modsym/ambient.py b/src/sage/modular/modsym/ambient.py index beb8509af0f..56e01e8c106 100644 --- a/src/sage/modular/modsym/ambient.py +++ b/src/sage/modular/modsym/ambient.py @@ -1761,9 +1761,9 @@ def factorization(self): else: A._is_simple = True D.append((A, n)) - # The eisenstein part - for E in self.eisenstein_submodule().decomposition(anemic=True): - D.append((E, 1)) + # The Eisenstein part + D.extend((E, 1) for E in + self.eisenstein_submodule().decomposition(anemic=True)) r = self.dimension() s = sum(A.rank() * mult for A, mult in D) diff --git a/src/sage/modular/overconvergent/hecke_series.py b/src/sage/modular/overconvergent/hecke_series.py index f347da9a278..68a4faa47d4 100644 --- a/src/sage/modular/overconvergent/hecke_series.py +++ b/src/sage/modular/overconvergent/hecke_series.py @@ -236,15 +236,11 @@ def low_weight_generators(N, p, m, NN): [q + 116*q^4 + 115*q^5 + 102*q^6 + 121*q^7 + 96*q^8 + 106*q^9 + O(q^10)]], 4) """ M = ModularFormsRing(N, base_ring=Zmod(p)) - b = M.gen_forms(maxweight=8) - - weightbound = max([f.weight() for f in b]) - generators = [] - - for k in range(2, weightbound + 2, 2): - generators.append([f.qexp(NN).change_ring(Zmod(p ** m)) for f in b if f.weight() == k]) - + weightbound = max(f.weight() for f in b) + generators = [[f.qexp(NN).change_ring(Zmod(p ** m)) + for f in b if f.weight() == k] + for k in range(2, weightbound + 2, 2)] return generators, weightbound diff --git a/src/sage/rings/valuation/valuation.py b/src/sage/rings/valuation/valuation.py index 2deeb100ffc..80f2b7bf939 100644 --- a/src/sage/rings/valuation/valuation.py +++ b/src/sage/rings/valuation/valuation.py @@ -770,7 +770,7 @@ def reduce_tree(v, w): reduce_init=[]).run_serial() else: raise NotImplementedError(algorithm) - leafs = set([node.valuation for node in nodes]) + leafs = {node.valuation for node in nodes} for node in nodes: if node.parent is None: continue diff --git a/src/sage/rings/valuation/valuation_space.py b/src/sage/rings/valuation/valuation_space.py index 24e5f598624..d5f5dc8e5ec 100644 --- a/src/sage/rings/valuation/valuation_space.py +++ b/src/sage/rings/valuation/valuation_space.py @@ -1214,14 +1214,16 @@ def _test_mul(self, **options): sage: v = QQ.valuation(5) sage: v._test_mul() """ + from sage.rings.infinity import infinity + from itertools import product tester = self._tester(**options) S = self.domain().some_elements() - from itertools import product + infis = {infinity, -infinity} + for x, y in tester.some_elements(product(S, S)): - from sage.rings.infinity import infinity - if set([self(x), self(y)]) == set([infinity, -infinity]): + if {Sx := self(x), Sy := self(y)} == infis: continue - tester.assertEqual(self(x * y), self(x) + self(y)) + tester.assertEqual(self(x * y), Sx + Sy) def _test_no_infinite_units(self, **options): r""" diff --git a/src/sage/rings/valuation/value_group.py b/src/sage/rings/valuation/value_group.py index f3afd30c413..0ec0a087bac 100644 --- a/src/sage/rings/valuation/value_group.py +++ b/src/sage/rings/valuation/value_group.py @@ -439,7 +439,7 @@ def __classcall__(cls, generators): """ if generators in QQ: generators = [generators] - generators = list(set([QQ.coerce(g) for g in generators if g != 0])) + generators = list({QQ.coerce(g) for g in generators if g != 0}) generators.sort() simplified_generators = generators @@ -450,7 +450,7 @@ def __classcall__(cls, generators): if g == h: continue from sage.rings.semirings.non_negative_integer_semiring import NN - if h/g in NN: + if h / g in NN: simplified_generators.remove(h) break diff --git a/src/sage/tensor/modules/finite_rank_free_module.py b/src/sage/tensor/modules/finite_rank_free_module.py index 9a4e44f0f12..9b8aeb7eeb5 100644 --- a/src/sage/tensor/modules/finite_rank_free_module.py +++ b/src/sage/tensor/modules/finite_rank_free_module.py @@ -1302,7 +1302,7 @@ def __init__( self._dual_exterior_powers = {} # Set of all modules (tensor powers, exterior powers) # that depend on self's bases: - self._all_modules = set([self]) + self._all_modules = {self} # List of known bases on the free module: self._known_bases = [] self._def_basis = None # default basis diff --git a/src/sage/tensor/modules/free_module_basis.py b/src/sage/tensor/modules/free_module_basis.py index f882b88e300..ca3116f2648 100644 --- a/src/sage/tensor/modules/free_module_basis.py +++ b/src/sage/tensor/modules/free_module_basis.py @@ -500,7 +500,7 @@ def __init__(self, basis, symbol, latex_symbol=None, indices=None, Basis_abstract.__init__(self, basis._fmodule, symbol, latex_symbol, indices, latex_indices) # The individual linear forms: - vl = list() + vl = [] fmodule = self._fmodule ring_one = fmodule._ring.one() for i in fmodule.irange(): @@ -719,7 +719,7 @@ def __init__(self, fmodule, symbol, latex_symbol=None, indices=None, # The basis is added to the module list of bases fmodule._known_bases.append(self) # The individual vectors: - vl = list() + vl = [] ring_one = fmodule._ring.one() for i in fmodule.irange(): v = fmodule.element_class(fmodule) diff --git a/src/sage/typeset/character_art.py b/src/sage/typeset/character_art.py index bc64866ed01..950bb2ea392 100644 --- a/src/sage/typeset/character_art.py +++ b/src/sage/typeset/character_art.py @@ -685,8 +685,8 @@ def __add__(self, Nelt): if self._baseline is not None and Nelt._baseline is not None: # left treatement - for line in self._matrix: - new_matrix.append(line + " " * (self._l - len(line))) + new_matrix.extend(line + " " * (self._l - len(line)) + for line in self._matrix) if new_h > self._h: # | new_h > self._h @@ -695,8 +695,9 @@ def __add__(self, Nelt): # | } :: Nelt._baseline - self._baseline # | } if new_baseline > self._baseline: - for k in range(new_baseline - self._baseline): - new_matrix.append(" " * self._l) + l_space = " " * self._l + new_matrix.extend(l_space + for k in range(new_baseline - self._baseline)) # | } new_h > self._h # | } new_h - new_baseline > self._h - self._baseline # ||<-- baseline number of white lines at the top @@ -722,8 +723,8 @@ def __add__(self, Nelt): for j in range(Nelt._h): new_matrix[i + j] += Nelt._matrix[j] else: - for line in self._matrix: - new_matrix.append(line + " " * (self._l - len(line))) + new_matrix.extend(line + " " * (self._l - len(line)) + for line in self._matrix) for i, line_i in enumerate(Nelt._matrix): if i == len(new_matrix): new_matrix.append(" " * self._l + line_i) From a6933337811435c6f1d5b71a58da70ff42ce67d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 16 Nov 2024 15:54:52 +0100 Subject: [PATCH 093/210] minor details in some pyx files in sets --- src/sage/sets/family.pyx | 5 ++- src/sage/sets/finite_set_map_cy.pyx | 10 ++--- src/sage/sets/pythonclass.pyx | 6 +-- src/sage/sets/recursively_enumerated_set.pyx | 44 ++++++++++---------- 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/sage/sets/family.pyx b/src/sage/sets/family.pyx index f87768f3989..0ccc4606ded 100644 --- a/src/sage/sets/family.pyx +++ b/src/sage/sets/family.pyx @@ -337,7 +337,10 @@ def Family(indices, function=None, hidden_keys=[], hidden_function=None, lazy=Fa sage: f = Family(list(range(1,27)), lambda i: chr(i+96)) sage: f - Finite family {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i', 10: 'j', 11: 'k', 12: 'l', 13: 'm', 14: 'n', 15: 'o', 16: 'p', 17: 'q', 18: 'r', 19: 's', 20: 't', 21: 'u', 22: 'v', 23: 'w', 24: 'x', 25: 'y', 26: 'z'} + Finite family {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', + 8: 'h', 9: 'i', 10: 'j', 11: 'k', 12: 'l', 13: 'm', 14: 'n', 15: 'o', + 16: 'p', 17: 'q', 18: 'r', 19: 's', 20: 't', 21: 'u', 22: 'v', 23: 'w', + 24: 'x', 25: 'y', 26: 'z'} sage: f[2] 'b' diff --git a/src/sage/sets/finite_set_map_cy.pyx b/src/sage/sets/finite_set_map_cy.pyx index f41450d5842..73dbdfdd934 100644 --- a/src/sage/sets/finite_set_map_cy.pyx +++ b/src/sage/sets/finite_set_map_cy.pyx @@ -621,11 +621,10 @@ cdef class FiniteSetEndoMap_N(FiniteSetMap_MN): sage: F([1, 0, 2]) * F([2, 1, 0]) [1, 2, 0] """ - assert(self._parent is other._parent), "Parent mismatch" + assert (self._parent is other._parent), "Parent mismatch" if self._parent._action == "right": return self._compose_internal_(other, self._parent) - else: - return other._compose_internal_(self, self._parent) + return other._compose_internal_(self, self._parent) def __pow__(self, n, dummy): """ @@ -679,11 +678,10 @@ cdef class FiniteSetEndoMap_Set(FiniteSetMap_Set): sage: g * f map: a -> c, b -> c, c -> c """ - assert(self._parent is other._parent), "Parent mismatch" + assert (self._parent is other._parent), "Parent mismatch" if self._parent._action == "right": return self._compose_internal_(other, self._parent) - else: - return other._compose_internal_(self, self._parent) + return other._compose_internal_(self, self._parent) def __pow__(self, n, dummy): """ diff --git a/src/sage/sets/pythonclass.pyx b/src/sage/sets/pythonclass.pyx index 02f34931b64..8aab718a39c 100644 --- a/src/sage/sets/pythonclass.pyx +++ b/src/sage/sets/pythonclass.pyx @@ -3,15 +3,15 @@ Set of all objects of a given Python class """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2018 Jeroen Demeyer # # 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 cpython.object cimport Py_EQ, Py_NE from sage.structure.richcmp cimport rich_to_bool diff --git a/src/sage/sets/recursively_enumerated_set.pyx b/src/sage/sets/recursively_enumerated_set.pyx index 3d9d4a00f75..b20fa8cbe8a 100644 --- a/src/sage/sets/recursively_enumerated_set.pyx +++ b/src/sage/sets/recursively_enumerated_set.pyx @@ -286,8 +286,9 @@ from collections import deque def RecursivelyEnumeratedSet(seeds, successors, structure=None, - enumeration=None, max_depth=float("inf"), post_process=None, - facade=None, category=None): + enumeration=None, max_depth=float("inf"), + post_process=None, + facade=None, category=None): r""" Return a recursively enumerated set. @@ -470,7 +471,7 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): A recursively enumerated set (breadth first search) """ assert enumeration in ['naive', 'depth', 'breadth'], \ - "unknown enumeration(={})".format(enumeration) + "unknown enumeration(={})".format(enumeration) self._seeds = seeds self.successors = successors @@ -480,7 +481,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): if post_process is not None: self.post_process = post_process self._graded_component = None - Parent.__init__(self, facade=facade, category=EnumeratedSets().or_subcategory(category)) + Parent.__init__(self, facade=facade, + category=EnumeratedSets().or_subcategory(category)) def __reduce__(self): r""" @@ -1532,10 +1534,7 @@ def search_forest_iterator(roots, children, algorithm='depth'): # (you ask the children for the last node you met). Setting # position on 0 results in a breadth search (enumerate all the # descendants of a node before going on to the next father) - if algorithm == 'depth': - position = -1 - else: - position = 0 + position = -1 if algorithm == 'depth' else 0 # Invariant: # - for breadth first search: stack[i] contains an iterator over the nodes @@ -1555,7 +1554,7 @@ def search_forest_iterator(roots, children, algorithm='depth'): continue yield node - stack.append( iter(children(node)) ) + stack.append(iter(children(node))) class RecursivelyEnumeratedSet_forest(Parent): @@ -1742,8 +1741,8 @@ class RecursivelyEnumeratedSet_forest(Parent): sage: loads(dumps(S)) An enumerated set with a forest structure """ - def __init__(self, roots = None, children = None, post_process = None, - algorithm = 'depth', facade = None, category=None): + def __init__(self, roots=None, children=None, post_process=None, + algorithm='depth', facade=None, category=None): r""" TESTS:: @@ -1759,7 +1758,8 @@ class RecursivelyEnumeratedSet_forest(Parent): if post_process is not None: self.post_process = post_process self._algorithm = algorithm - Parent.__init__(self, facade = facade, category = EnumeratedSets().or_subcategory(category)) + Parent.__init__(self, facade=facade, + category=EnumeratedSets().or_subcategory(category)) __len__ = None @@ -1833,7 +1833,7 @@ class RecursivelyEnumeratedSet_forest(Parent): """ iter = search_forest_iterator(self.roots(), self.children, - algorithm = self._algorithm) + algorithm=self._algorithm) if hasattr(self, "post_process"): iter = _imap_and_filter_none(self.post_process, iter) return iter @@ -2016,7 +2016,7 @@ class RecursivelyEnumeratedSet_forest(Parent): """ stack = [iter(self.roots())] while stack: - position = randint(0,len(stack)-1) + position = randint(0, len(stack) - 1) try: node = next(stack[position]) except StopIteration: @@ -2025,12 +2025,12 @@ class RecursivelyEnumeratedSet_forest(Parent): if node == elt: return True - stack.append( iter(self.children(node)) ) + stack.append(iter(self.children(node))) return False - def map_reduce(self, map_function = None, - reduce_function = None, - reduce_init = None): + def map_reduce(self, map_function=None, + reduce_function=None, + reduce_init=None): r""" Apply a Map/Reduce algorithm on ``self``. @@ -2084,7 +2084,7 @@ class RecursivelyEnumeratedSet_forest(Parent): """ import sage.parallel.map_reduce return sage.parallel.map_reduce.RESetMapReduce( - forest = self, - map_function = map_function, - reduce_function = reduce_function, - reduce_init = reduce_init).run() + forest=self, + map_function=map_function, + reduce_function=reduce_function, + reduce_init=reduce_init).run() From 2533390e1b8b1cca0c34493d8743d3679bdcf2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 16 Nov 2024 16:36:28 +0100 Subject: [PATCH 094/210] avoid using isinstance IntegralDomain in modules --- src/sage/modules/free_module.py | 5 ++--- src/sage/modules/free_quadratic_module.py | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 6b407414030..097db985ede 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -172,7 +172,7 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ ########################################################################### import itertools @@ -185,7 +185,6 @@ import sage.rings.integer import sage.rings.integer_ring import sage.rings.rational_field -from sage.rings.ring import IntegralDomain from sage.categories.commutative_rings import CommutativeRings from sage.categories.fields import Fields from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets @@ -296,7 +295,7 @@ def create_object(self, version, key): and base_ring.is_maximal() and base_ring.class_number() == 1): return FreeModule_ambient_pid(base_ring, rank, sparse=sparse) - if isinstance(base_ring, IntegralDomain) or base_ring in IntegralDomains(): + if base_ring in IntegralDomains(): return FreeModule_ambient_domain(base_ring, rank, sparse=sparse) return FreeModule_ambient(base_ring, rank, sparse=sparse) diff --git a/src/sage/modules/free_quadratic_module.py b/src/sage/modules/free_quadratic_module.py index a209ae79ee4..553f4b0931d 100644 --- a/src/sage/modules/free_quadratic_module.py +++ b/src/sage/modules/free_quadratic_module.py @@ -69,8 +69,9 @@ from sage.categories.commutative_rings import CommutativeRings from sage.categories.principal_ideal_domains import PrincipalIdealDomains +from sage.categories.integral_domains import IntegralDomains from sage.modules import free_module -from sage.rings.ring import Field, IntegralDomain +from sage.rings.ring import Field import sage.matrix.matrix_space import sage.misc.latex as latex @@ -175,7 +176,7 @@ def FreeQuadraticModule(base_ring, rank, inner_product_matrix, M = FreeQuadraticModule_ambient_pid( base_ring, rank, sparse=sparse, inner_product_matrix=inner_product_matrix) - elif isinstance(base_ring, IntegralDomain) or base_ring.is_integral_domain(): + elif base_ring in IntegralDomains(): M = FreeQuadraticModule_ambient_domain( base_ring, rank, sparse=sparse, inner_product_matrix=inner_product_matrix) else: From d1bd1b59b5a00c2e594adc8c9fa0bf795386ff01 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sun, 17 Nov 2024 01:19:25 +0100 Subject: [PATCH 095/210] Python3 build does not find openssl without pkgconf --- build/pkgs/python3/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/python3/dependencies b/build/pkgs/python3/dependencies index c00db7fa1e0..d703ce7ab69 100644 --- a/build/pkgs/python3/dependencies +++ b/build/pkgs/python3/dependencies @@ -1,4 +1,4 @@ -zlib readline sqlite libpng bzip2 liblzma libffi openssl | xz +zlib readline sqlite libpng bzip2 liblzma libffi openssl | xz pkgconf ---------- All lines of this file are ignored except the first. From e04ec69c1438bcbc33b7efb1303bd26f061f8a67 Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Sat, 16 Nov 2024 22:44:03 -0500 Subject: [PATCH 096/210] #38708 has_order for python int --- src/sage/groups/generic.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sage/groups/generic.py b/src/sage/groups/generic.py index 69acc7c654d..f8c9d110b9e 100644 --- a/src/sage/groups/generic.py +++ b/src/sage/groups/generic.py @@ -1502,12 +1502,18 @@ def has_order(P, n, operation='+'): sage: has_order(x, -8) False + Check for :issue:`38708`:: + + sage: has_order(Mod(2,3), int(2), operation='*') + True + .. NOTE:: In some cases, order *testing* can be much faster than *computing* the order using :func:`order_from_multiple`. """ - if isinstance(n, sage.rings.integer.Integer): + if not isinstance(n, sage.structure.factorization_integer.IntegerFactorization): + n = integer_ring.ZZ(n) if n <= 0: return False n = n.factor() From f20bed408679fc6026c50ad81c682ed3c05b6f4b Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Sun, 17 Nov 2024 01:12:36 -0500 Subject: [PATCH 097/210] allow all Factorizations --- src/sage/groups/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/groups/generic.py b/src/sage/groups/generic.py index f8c9d110b9e..5b207f423c6 100644 --- a/src/sage/groups/generic.py +++ b/src/sage/groups/generic.py @@ -1512,7 +1512,7 @@ def has_order(P, n, operation='+'): In some cases, order *testing* can be much faster than *computing* the order using :func:`order_from_multiple`. """ - if not isinstance(n, sage.structure.factorization_integer.IntegerFactorization): + if not isinstance(n, sage.structure.factorization.Factorization): n = integer_ring.ZZ(n) if n <= 0: return False From 60fdd034794f8b6fd7c285658d36f219681e3034 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sun, 17 Nov 2024 16:59:21 +0900 Subject: [PATCH 098/210] Materialize literal-blocks list before modifying nodes --- src/sage_docbuild/conf.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py index 18ce9f7663e..c4d1df3d23b 100644 --- a/src/sage_docbuild/conf.py +++ b/src/sage_docbuild/conf.py @@ -954,7 +954,7 @@ class SagecodeTransform(SphinxTransform): def apply(self): if self.app.builder.tags.has('html') or self.app.builder.tags.has('inventory'): - for node in self.document.findall(nodes.literal_block): + for node in list(self.document.findall(nodes.literal_block)): if node.get('language') is None and node.astext().startswith('sage:'): from docutils.nodes import container as Container, label as Label, literal_block as LiteralBlock, Text from sphinx_inline_tabs._impl import TabContainer @@ -963,7 +963,8 @@ def apply(self): prev_node = node.previous_sibling() if isinstance(node.previous_sibling(), TabContainer): # Make sure not to merge inline tabs for adjacent literal blocks - parent.insert(index, Text('')) + parent.insert(index, nodes.paragraph()) + prev_node = parent[index] index += 1 parent.remove(node) # Tab for Sage code @@ -1102,3 +1103,4 @@ def feature_tags(): for feature in all_features(): if feature.is_present(): yield 'feature_' + feature.name.replace('.', '_') + From fd7ca59ba748f28e7ba9e14b398749372b52d203 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 17 Nov 2024 13:40:30 +0100 Subject: [PATCH 099/210] Fix detection of tdlib and mcqd with meson These are header-only libraries, so find_library doesn't work with them --- src/sage/graphs/graph_decompositions/meson.build | 7 ++++++- src/sage/graphs/meson.build | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph_decompositions/meson.build b/src/sage/graphs/graph_decompositions/meson.build index 0d9778ae2ba..1fc8bc1d765 100644 --- a/src/sage/graphs/graph_decompositions/meson.build +++ b/src/sage/graphs/graph_decompositions/meson.build @@ -1,4 +1,9 @@ -tdlib = cc.find_library('tdlib', required: false, disabler: true) +# tdlib is a header-only library +if cc.has_header('treedec/combinations.hpp') + tdlib = declare_dependency() +else + tdlib = disabler() +endif # Cannot be found via pkg-config rw = cc.find_library('rw') diff --git a/src/sage/graphs/meson.build b/src/sage/graphs/meson.build index d88f1942daf..28fbcaf24ef 100644 --- a/src/sage/graphs/meson.build +++ b/src/sage/graphs/meson.build @@ -1,5 +1,10 @@ bliss = cc.find_library('bliss', required: false, disabler: true) -mcqd = cc.find_library('mcqd', required: false, disabler: true) +# mcqd is a header-only library +if cc.has_header('mcqd.h') + mcqd = declare_dependency() +else + mcqd = disabler() +endif cliquer = cc.find_library('cliquer') # Cannot be found via pkg-config From 2b1fb6fe0b4e48aeb69bc109d82d36335172f594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 17 Nov 2024 17:58:27 +0100 Subject: [PATCH 100/210] some work on deformed Burau matrix --- src/sage/groups/braid.py | 147 ++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 71 deletions(-) diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index 8945175cf7a..654ff1b068a 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -67,31 +67,33 @@ ############################################################################## from itertools import combinations + +from sage.algebras.free_algebra import FreeAlgebra from sage.categories.action import Action from sage.categories.groups import Groups -from sage.combinat.permutation import Permutation -from sage.combinat.permutation import Permutations +from sage.combinat.permutation import Permutation, Permutations from sage.combinat.subset import Subsets from sage.features.sagemath import sage__libs__braiding +from sage.functions.generalized import sign from sage.groups.artin import FiniteTypeArtinGroup, FiniteTypeArtinGroupElement -from sage.groups.finitely_presented import FinitelyPresentedGroup -from sage.groups.finitely_presented import GroupMorphismWithGensImages +from sage.groups.finitely_presented import ( + FinitelyPresentedGroup, + GroupMorphismWithGensImages, +) from sage.groups.free_group import FreeGroup, is_FreeGroup -from sage.functions.generalized import sign -from sage.groups.perm_gps.permgroup_named import SymmetricGroup -from sage.groups.perm_gps.permgroup_named import SymmetricGroupElement +from sage.groups.perm_gps.permgroup_named import SymmetricGroup, SymmetricGroupElement from sage.libs.gap.libgap import libgap from sage.matrix.constructor import identity_matrix, matrix +from sage.misc.cachefunc import cached_method 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.misc.misc_c import prod from sage.rings.integer import Integer -from sage.rings.integer_ring import IntegerRing +from sage.rings.integer_ring import ZZ from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing from sage.sets.set import Set from sage.structure.element import Expression -from sage.structure.richcmp import richcmp, rich_to_bool +from sage.structure.richcmp import rich_to_bool, richcmp lazy_import('sage.libs.braiding', ['leftnormalform', 'rightnormalform', 'centralizer', 'supersummitset', 'greatestcommondivisor', @@ -267,7 +269,7 @@ def burau_matrix(self, var='t', reduced=False): - :wikipedia:`Burau_representation` - [Squ1984]_ """ - R = LaurentPolynomialRing(IntegerRing(), var) + R = LaurentPolynomialRing(ZZ, var) t = R.gen() n = self.strands() if not reduced: @@ -418,7 +420,7 @@ def alexander_polynomial(self, var='t', normalized=True): """ n = self.strands() p = (self.burau_matrix(reduced=True) - identity_matrix(n - 1)).det() - K, t = LaurentPolynomialRing(IntegerRing(), var).objgen() + K, t = LaurentPolynomialRing(ZZ, var).objgen() if p == 0: return K.zero() qn = sum(t**i for i in range(n)) @@ -524,8 +526,8 @@ def plot(self, color='rainbow', orientation='bottom-top', gap=0.05, aspect_ratio Graphics object consisting of 12 graphics primitives """ from sage.plot.bezier_path import bezier_path - from sage.plot.plot import Graphics, line from sage.plot.colors import rainbow + from sage.plot.plot import Graphics, line if orientation == 'top-bottom': orx = 0 ory = -1 @@ -621,8 +623,8 @@ def plot3d(self, color='rainbow'): sage: b.plot3d(color=["red", "blue", "red", "blue"]) # needs sage.plot sage.symbolic Graphics3d Object """ - from sage.plot.plot3d.shapes2 import bezier3d from sage.plot.colors import rainbow + from sage.plot.plot3d.shapes2 import bezier3d b = [] n = self.strands() if isinstance(color, (list, tuple)): @@ -776,7 +778,7 @@ def TL_matrix(self, drain_size, variab=None, sparse=True): - [Jon2005]_ """ if variab is None: - R = LaurentPolynomialRing(IntegerRing(), 'A') + R = LaurentPolynomialRing(ZZ, 'A') else: R = variab.parent() rep = self.parent().TL_representation(drain_size, variab) @@ -857,7 +859,6 @@ def links_gould_polynomial(self, varnames=None, use_symbolics=False): - [MW2012]_ """ - from sage.rings.integer_ring import ZZ if varnames is not None: poly = self.links_gould_polynomial(use_symbolics=use_symbolics) R = LaurentPolynomialRing(ZZ, varnames) @@ -935,7 +936,7 @@ def tropical_coordinates(self): coord[k+2] = x2 + sign*(min(y2, 0) + min(min(y1, 0) + sign*z, 0)) from sage.rings.semirings.tropical_semiring import TropicalSemiring - T = TropicalSemiring(IntegerRing()) + T = TropicalSemiring(ZZ) return [T(_) for _ in coord] def markov_trace(self, variab=None, normalized=True): @@ -980,9 +981,9 @@ def markov_trace(self, variab=None, normalized=True): Univariate Laurent Polynomial Ring in A over Integer Ring """ if variab is None: - R = LaurentPolynomialRing(IntegerRing(), 'A') + R = LaurentPolynomialRing(ZZ, 'A') A = R.gens()[0] - one = IntegerRing().one() + one = ZZ.one() quantum_integer = lambda d: R({i: one for i in range(-2*d, 2*d+1, 4)}) else: A = variab @@ -1125,7 +1126,6 @@ def jones_polynomial(self, variab=None, skein_normalization=False): else: return self._jones_polynomial(variab) else: - from sage.rings.integer_ring import ZZ if variab is None: variab = 't' if not isinstance(variab, Expression): @@ -1189,8 +1189,8 @@ def _enhanced_states(self): ((6, 0), [(2, [((1, 1), [], [([(0, 0), (1, 2)], 0), ([(0, 2), (1, 0)], 0)])])])] """ - from sage.graphs.graph import Graph from sage.functions.generalized import sgn + from sage.graphs.graph import Graph crossinglist = self.Tietze() ncross = len(crossinglist) writhe = 0 @@ -1326,7 +1326,7 @@ def _annular_khovanov_complex_cached(self, qagrad, ring=None): """ from sage.homology.chain_complex import ChainComplex if ring is None: - ring = IntegerRing() + ring = ZZ states = self._enhanced_states() if qagrad in states: bases = states[qagrad] @@ -1402,13 +1402,13 @@ def annular_khovanov_complex(self, qagrad=None, ring=None): 0: []} """ if ring is None: - ring = IntegerRing() + ring = ZZ if qagrad is None: return {qa: self._annular_khovanov_complex_cached(qa, ring) for qa in self._enhanced_states()} return self._annular_khovanov_complex_cached(qagrad, ring) - def annular_khovanov_homology(self, qagrad=None, ring=IntegerRing()): + def annular_khovanov_homology(self, qagrad=None, ring=ZZ): r""" Return the annular Khovanov homology of a closure of a braid. @@ -1743,7 +1743,7 @@ def conjugating_braid(self, other): cb[0][0] %= 2 return B._element_from_libbraiding(cb) - def is_conjugated(self, other): + def is_conjugated(self, other) -> bool: """ Check if the two braids are conjugated. @@ -1908,7 +1908,7 @@ def thurston_type(self): """ return thurston_type(self) - def is_reducible(self): + def is_reducible(self) -> bool: """ Check whether the braid is reducible. @@ -1924,7 +1924,7 @@ def is_reducible(self): """ return self.thurston_type() == 'reducible' - def is_periodic(self): + def is_periodic(self) -> bool: """ Check whether the braid is periodic. @@ -1940,9 +1940,9 @@ def is_periodic(self): """ return self.thurston_type() == 'periodic' - def is_pseudoanosov(self): + def is_pseudoanosov(self) -> bool: """ - Check if the braid is pseudo-anosov. + Check if the braid is pseudo-Anosov. EXAMPLES:: @@ -2093,24 +2093,25 @@ def deformed_burau_matrix(self, variab='q'): sage: burau.subs({t:q}).change_ring(db_base) == db_simp True """ - R = LaurentPolynomialRing(IntegerRing(), variab) + R = LaurentPolynomialRing(ZZ, variab) + n = self.strands() tz = self.Tietze() - m = len(tz) - from sage.algebras.free_algebra import FreeAlgebra - alg = FreeAlgebra(R, m*3, - [f'{s}p_{i}' for i in range(m) if tz[i] > 0 - for s in 'bca'] - + [f'{s}m_{i}' for i in range(m) if tz[i] < 0 - for s in 'bca']) - gen_indices = ([i for i in range(m) if tz[i] > 0] - + [i for i in range(m) if tz[i] < 0]) - - M = identity_matrix(alg, n) + m3 = len(tz) * 3 + plus = [i for i, tzi in enumerate(tz) if tzi > 0] + minus = [i for i, tzi in enumerate(tz) if tzi < 0] + gens_str = [f'{s}p_{i}' for i in plus for s in 'bca'] + gens_str += [f'{s}m_{i}' for i in minus for s in 'bca'] + alg_ZZ = FreeAlgebra(ZZ, m3, gens_str) + gen_indices = {k: i for i, k in enumerate(plus + minus)} + gens = [[bca for bca in alg_ZZ.gens()[k:k+3]] + for k in range(0, m3, 3)] + + M = identity_matrix(alg_ZZ, n) for k, i in enumerate(tz): - A = identity_matrix(alg, n) - gen_index = gen_indices.index(k) - b, c, a = alg.gens()[3*gen_index:3*gen_index+3] + A = identity_matrix(alg_ZZ, n) + b, c, a = gens[gen_indices[k]] + # faster using row operations instead ? if i > 0: A[i-1, i-1] = a A[i, i] = 0 @@ -2122,7 +2123,9 @@ def deformed_burau_matrix(self, variab='q'): A[-1-i, -i] = c A[-i, -1-i] = b M = M * A - return M + + alg_R = FreeAlgebra(R, m3, gens_str) + return M.change_ring(alg_R) def _colored_jones_sum(self, N, qword): r""" @@ -2213,7 +2216,7 @@ def colored_jones_polynomial(self, N, variab=None, try_inverse=True): if variab is None: return cj if isinstance(variab, str): - variab = LaurentPolynomialRing(IntegerRing(), variab).gen() + variab = LaurentPolynomialRing(ZZ, variab).gen() return cj.subs(q=variab) db = self.deformed_burau_matrix('q')[1:, 1:] @@ -2286,12 +2289,15 @@ def __init__(self, words): """ self._algebra = words.parent() self.q = self._algebra.base_ring().gen() + self.iq = ~self.q self.R = self._algebra.base_ring() self._unreduced_words = words self._gens = self._algebra._indices.gens() - self._gens_index = {g: i for i, g in enumerate(self._gens)} self._minus_begin = min((i for i, gen in enumerate(self._gens) if 'm' in str(gen)), - default=len(self._gens)) + default=len(self._gens)) // 3 + split = ((g, str(g), i) for i, g in enumerate(self._gens)) + self._recognize = {g: (s[0], s[1] == 'm', 3 * (i // 3)) + for g, s, i in split} @lazy_attribute def tuples(self): @@ -2327,24 +2333,25 @@ def tuples(self): """ from collections import defaultdict ret = defaultdict(self.R) + convert = self._recognize + q = self.q + iq = self.iq for unreduced_monom, q_power in list(self._unreduced_words): - q = self.q ret_tuple = [0] * len(self._gens) for gen, exp in unreduced_monom: - gen_index = self._gens_index[gen] - is_minus = bool(gen_index >= self._minus_begin) - index = gen_index // 3 + letter, is_minus, index = convert[gen] # This uses the relations in equations (4.1) and (4.2) # of [HL2018]_. - i, j, k = ret_tuple[3*index: 3*index + 3] - if not (gen_index + 1) % 3: # is_a - ret_tuple[3*index: 3*index + 3] = [i, j, k + exp] - if not gen_index % 3: # is_b - ret_tuple[3*index: 3*index + 3] = [i + exp, j, k] - q_power *= q**(2*(k*exp + j*exp)) if is_minus else q**(-2*j*exp) - if not (gen_index + 2) % 3: # is_c - ret_tuple[3*index: 3*index + 3] = [i, j + exp, k] - q_power *= q**(-k*exp) if is_minus else q**(k*exp) + if letter == 'a': # is_a + ret_tuple[index + 2] += exp + elif letter == 'b': # is_b + j, k = ret_tuple[index + 1:index + 3] + ret_tuple[index] += exp + q_power *= q**(2*(k*exp + j*exp)) if is_minus else iq**(2*j*exp) + else: # is_c + k = ret_tuple[index + 2] + ret_tuple[index + 1] += exp + q_power *= iq**(k*exp) if is_minus else q**(k*exp) ret[tuple(ret_tuple)] += q_power return ret @@ -2443,16 +2450,16 @@ def eps_monom(q_tuple): """ q = self.q ret_q = q**sum((N - 1 - q_tuple[3*i + 2])*q_tuple[3*i + 1] - for i in range(self._minus_begin//3)) + for i in range(self._minus_begin)) ret_q *= q**sum((N - 1)*(-q_tuple[rj]) - for rj in range(self._minus_begin + 1, + for rj in range(self._minus_begin * 3 + 1, len(q_tuple), 3)) ret_q *= prod(prod(1 - q**(N - 1 - q_tuple[3*i + 1] - h) for h in range(q_tuple[3*i + 2])) - for i in range(self._minus_begin//3)) + for i in range(self._minus_begin)) ret_q *= prod(prod(1 - q**(q_tuple[3*j + 1] + k + 1 - N) for k in range(q_tuple[3*j + 2])) - for j in range(self._minus_begin//3, + for j in range(self._minus_begin, len(q_tuple)//3)) return ret_q @@ -2756,17 +2763,15 @@ def _links_gould_representation(self, symbolics=False): d = 4 # dimension of the natural module from sage.matrix.special import diagonal_matrix if symbolics: - from sage.symbolic.ring import SR as BR - from sage.calculus.var import var from sage.misc.functional import sqrt - t0, t1 = var('t0, t1') + from sage.symbolic.ring import SR as BR + t0, t1 = BR.var('t0, t1') s0 = sqrt(t0) s1 = sqrt(t1) Y = sqrt(-(t0 - 1)*(t1 - 1)) sparse = False else: from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - from sage.rings.integer_ring import ZZ LR = LaurentPolynomialRing(ZZ, 's0r, s1r') PR = PolynomialRing(LR, 'Yr') s0r, s1r, Yr = PR.gens_dict_recursive().values() @@ -2865,7 +2870,7 @@ def _LKB_matrix_(self, braid, variab): A = A*self._LKB_matrix_((i,), variab) return A n2 = [set(X) for X in combinations(range(n), 2)] - R = LaurentPolynomialRing(IntegerRing(), variab) + R = LaurentPolynomialRing(ZZ, variab) q = R.gens()[0] t = R.gens()[1] if not braid: @@ -3215,7 +3220,7 @@ def TL_representation(self, drain_size, variab=None): if variab is None: if drain_size in self._TL_representation_dict: return self._TL_representation_dict[drain_size] - R = LaurentPolynomialRing(IntegerRing(), 'A') + R = LaurentPolynomialRing(ZZ, 'A') A = R.gens()[0] else: R = variab.parent() From 5e3ddfd4ae0b05446a18be745fa275efaa30c798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 17 Nov 2024 19:46:09 +0100 Subject: [PATCH 101/210] details --- src/sage/groups/braid.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index 654ff1b068a..75ccf63a719 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -2104,8 +2104,7 @@ def deformed_burau_matrix(self, variab='q'): gens_str += [f'{s}m_{i}' for i in minus for s in 'bca'] alg_ZZ = FreeAlgebra(ZZ, m3, gens_str) gen_indices = {k: i for i, k in enumerate(plus + minus)} - gens = [[bca for bca in alg_ZZ.gens()[k:k+3]] - for k in range(0, m3, 3)] + gens = [alg_ZZ.gens()[k:k + 3] for k in range(0, m3, 3)] M = identity_matrix(alg_ZZ, n) for k, i in enumerate(tz): From 21ff2e82938bd1a05268c6262a793fa3be726ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 17 Nov 2024 20:10:28 +0100 Subject: [PATCH 102/210] further details --- src/sage/groups/braid.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index 75ccf63a719..1d561461f46 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -2149,23 +2149,19 @@ def _colored_jones_sum(self, N, qword): """ rqword = RightQuantumWord(qword).reduced_word() alg = qword.parent() - R = alg.base_ring() - result = R.one() + result = alg.base_ring().one() current_word = alg.one() - i = 1 - continue_summing = True # This seemingly infinite sum is always finite if the qword comes # from a sum of quantum determinants; because at some point # the break condition will become true. - while continue_summing: + while True: current_word *= rqword - new_rqw = RightQuantumWord(alg(current_word)) + new_rqw = RightQuantumWord(current_word) current_word = new_rqw.reduced_word() new_eps = new_rqw.eps(N) - result += new_eps if not new_eps: - continue_summing = False - i += 1 + break + result += new_eps return result def colored_jones_polynomial(self, N, variab=None, try_inverse=True): @@ -2420,7 +2416,7 @@ def eps(self, N): sage: from sage.groups.braid import RightQuantumWord sage: B = BraidGroup(3) sage: b = B([1,-2,1,2]) - sage: db = b.deformed_burau_matrix()[:, :] + sage: db = b.deformed_burau_matrix() sage: q = db.parent().base_ring().base_ring().gen() sage: (bp_0, cp_0, ap_0, ....: bp_2, cp_2, ap_2, From 990b436de55725c881586b27bc934e2ae4f3bf25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 17 Nov 2024 20:58:37 +0100 Subject: [PATCH 103/210] tentative of free-Algebra functor --- src/sage/algebras/free_algebra.py | 229 +++++++++++++++++++++++++++--- 1 file changed, 208 insertions(+), 21 deletions(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 8b73482e7bf..0a081f63e21 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -160,23 +160,25 @@ # *************************************************************************** -from sage.categories.rings import Rings - -from sage.monoids.free_monoid import FreeMonoid -from sage.monoids.free_monoid_element import FreeMonoidElement - from sage.algebras.free_algebra_element import FreeAlgebraElement - -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.integer_ring import ZZ from sage.categories.algebras_with_basis import AlgebrasWithBasis +from sage.categories.functor import Functor +from sage.categories.pushout import (ConstructionFunctor, + CompositeConstructionFunctor, + IdentityConstructionFunctor) +from sage.categories.rings import Rings from sage.combinat.free_module import CombinatorialFreeModule +from sage.combinat.words.alphabet import Alphabet from sage.combinat.words.word import Word +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import +from sage.monoids.free_monoid import FreeMonoid +from sage.monoids.free_monoid_element import FreeMonoidElement +from sage.rings.integer_ring import ZZ +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.structure.category_object import normalize_names - +from sage.structure.coerce_exceptions import CoercionException +from sage.structure.factory import UniqueFactory lazy_import('sage.algebras.letterplace.free_algebra_letterplace', 'FreeAlgebra_letterplace') @@ -199,12 +201,12 @@ class FreeAlgebraFactory(UniqueFactory): 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') - Free Algebra on 1 generators (z,) over Finite Field of size 5 + Free Algebra on 1 generator (z,) over Finite Field of size 5 sage: FreeAlgebra(GF(5),1, ['alpha']) - Free Algebra on 1 generators (alpha,) over Finite Field of size 5 + Free Algebra on 1 generator (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 1 generator (a,) over Integer Ring Free algebras are globally unique:: @@ -264,7 +266,7 @@ 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 1 generator (c,) over Free Algebra on 2 generators (a, b) over Rational Field sage: c^3 * a * b^2 a*b^2*c^3 @@ -507,6 +509,17 @@ def __init__(self, R, n, names, degrees=None): else: self._degrees = {g: ZZ(d) for g, d in zip(self.monoid().gens(), degrees)} + def construction(self): + """ + Return the construction of ``self``. + + EXAMPLES:: + + sage: algebras.Free(QQ,4,'x,y,z,t').construction() + (Associative[x,y,z,t], Rational Field) + """ + return AssociativeFunctor(self.variable_names(), self._degrees), self.base_ring() + def one_basis(self): """ Return the index of the basis element `1`. @@ -554,16 +567,17 @@ def _repr_(self) -> str: sage: F # indirect doctest QQ<> sage: FreeAlgebra(ZZ, 1, ['a']) - Free Algebra on 1 generators (a,) over Integer Ring + Free Algebra on 1 generator (a,) over Integer Ring sage: FreeAlgebra(QQ, 2, ['x', 'y'], degrees=(2,1)) Free Algebra on 2 generators (x, y) with degrees (2, 1) over Rational Field """ + txt = "generator" if self.__ngens == 1 else "generators" if self._degrees is None: - return "Free Algebra on {} generators {} over {}".format( - self.__ngens, self.gens(), self.base_ring()) - return "Free Algebra on {} generators {} with degrees {} over {}".format( - self.__ngens, self.gens(), tuple(self._degrees.values()), self.base_ring()) + return "Free Algebra on {} {} {} over {}".format( + self.__ngens, txt, self.gens(), self.base_ring()) + return "Free Algebra on {} {} {} with degrees {} over {}".format( + self.__ngens, txt, self.gens(), tuple(self._degrees.values()), self.base_ring()) def _latex_(self) -> str: r""" @@ -1449,3 +1463,176 @@ def expand(self): x + x^2*y - 2*x*y*x + y*x^2 + y^4*x """ return self.parent().expansion(self) + + +class AssociativeFunctor(ConstructionFunctor): + """ + A constructor for free associative algebras. + + EXAMPLES:: + + sage: P = algebras.Free(ZZ, 2, 'x,y') + sage: x,y = P.gens() + sage: F = P.construction()[0]; F + Associative[x,y] + + sage: A = GF(5)['a,b'] + sage: a, b = A.gens() + sage: F(A) + Free Algebra on 2 generators (x, 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) + Generic endomorphism of Free Algebra on 2 generators (x, y) + over Multivariate Polynomial Ring in a, b over Finite Field of size 5 + + sage: F(f)(a * F(A)(x)) + (a+b)*x + """ + rank = 9 + + def __init__(self, vars, degs=None): + """ + EXAMPLES:: + + sage: from sage.algebras.free_algebra import AssociativeFunctor + sage: F = AssociativeFunctor(['x','y']) + sage: F + Associative[x,y] + sage: F(ZZ) + Free Algebra on 2 generators (x, y) over Integer Ring + """ + Functor.__init__(self, Rings(), Rings()) + self.vars = vars + self.degs = degs + + def _apply_functor(self, R): + """ + Apply the functor to an object of ``self``'s domain. + + EXAMPLES:: + + sage: R = algebras.Free(ZZ, 3, 'x,y,z') + sage: F = R.construction()[0]; F + Associative[x,y,z] + sage: type(F) + + sage: F(ZZ) # indirect doctest + Free Algebra on 3 generators (x, y, z) over Integer Ring + """ + return FreeAlgebra(R, self.vars, self.degs) + + def _apply_functor_to_morphism(self, f): + """ + Apply the functor ``self`` to the ring morphism `f`. + + TESTS:: + + sage: R = algebras.Free(ZZ, 'x').construction()[0] + sage: R(ZZ.hom(GF(3))) # indirect doctest + Generic morphism: + From: Free Algebra on 1 generator (x,) over Integer Ring + To: Free Algebra on 1 generator (x,) over Finite Field of size 3 + """ + dom = self(f.domain()) + codom = self(f.codomain()) + + def action(x): + return codom._from_dict({a: f(b) + for a, b in x.monomial_coefficients().items()}) + return dom.module_morphism(function=action, codomain=codom) + + def __eq__(self, other): + """ + EXAMPLES:: + + sage: F = algebras.Free(ZZ, 3, 'x,y,z').construction()[0] + sage: G = algebras.Free(QQ, 3, 'x,y,z').construction()[0] + sage: F == G + True + sage: G == loads(dumps(G)) + True + sage: G = algebras.Free(QQ, 2, 'x,y').construction()[0] + sage: F == G + False + """ + if not isinstance(other, AssociativeFunctor): + return False + return self.vars == other.vars and self.degs == other.degs + + def __mul__(self, other): + """ + If two Associative functors are given in a row, form a single Associative functor + with all of the variables. + + EXAMPLES:: + + sage: from sage.algebras.free_algebra import AssociativeFunctor + sage: F = AssociativeFunctor(['x','y']) + sage: G = AssociativeFunctor(['t']) + sage: G * F + Associative[x,y,t] + """ + if isinstance(other, IdentityConstructionFunctor): + return self + if isinstance(other, AssociativeFunctor): + if set(self.vars).intersection(other.vars): + raise CoercionException("Overlapping variables (%s,%s)" % + (self.vars, other.vars)) + return AssociativeFunctor(other.vars + self.vars) + elif (isinstance(other, CompositeConstructionFunctor) and + isinstance(other.all[-1], AssociativeFunctor)): + return CompositeConstructionFunctor(other.all[:-1], + self * other.all[-1]) + else: + return CompositeConstructionFunctor(other, self) + + def merge(self, other): + """ + Merge ``self`` with another construction functor, or return ``None``. + + EXAMPLES:: + + sage: from sage.algebras.free_algebra import AssociativeFunctor + sage: F = AssociativeFunctor(['x','y']) + sage: G = AssociativeFunctor(['t']) + sage: F.merge(G) + Associative[x,y,t] + sage: F.merge(F) + Associative[x,y] + + Now some actual use cases:: + + sage: R = algebras.Free(ZZ, 3, 'x,y,z') + sage: x,y,z = R.gens() + sage: 1/2 * x + 1/2*x + sage: parent(1/2 * x) + Free Algebra on 3 generators (x, y, z) over Rational Field + + sage: S = algebras.Free(QQ, 2, 'z,t') + sage: z,t = S.gens() + sage: x + t + B[t[]] + B[x[]] + sage: parent(x + t) + Free Algebra on 4 generators ['z', 't', 'x', 'y'] over Rational Field + """ + if isinstance(other, AssociativeFunctor): + if self.vars == other.vars: + return self + ret = list(self.vars) + cur_vars = set(ret) + ret.extend(v for v in other.vars if v not in cur_vars) + # degrees are ignored for the moment ; TODO + return AssociativeFunctor(Alphabet(ret)) + + return None + + def _repr_(self) -> str: + """ + TESTS:: + + sage: algebras.Free(QQ,4,'x,y,z,t').construction()[0] + Associative[x,y,z,t] + """ + return "Associative[%s]" % ','.join(self.vars) From 840a11937bb12f289ddaaff775bfc96dd858eb08 Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Sun, 17 Nov 2024 19:43:56 -0500 Subject: [PATCH 104/210] fix typo in FinitePoset doc --- src/sage/combinat/posets/posets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index e565eb3d2ee..2a4b2d24f48 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -794,7 +794,7 @@ class FinitePoset(UniqueRepresentation, Parent): corresponding to vertex ``i``. If ``elements`` is ``None``, then it is set to be the vertex set of the digraph. Note that if this option is set, then ``elements`` is considered as a specified linear extension of the poset - and the `linear_extension` attribute is set. + and the ``linear_extension`` attribute is set. - ``category`` -- :class:`FinitePosets`, or a subcategory thereof From 7279faaee85269c1601b6c7842010fc552d29a5a Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Mon, 18 Nov 2024 14:33:01 +0900 Subject: [PATCH 105/210] Add a small improvement --- src/sage_docbuild/conf.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py index c4d1df3d23b..d90c2eb2dd1 100644 --- a/src/sage_docbuild/conf.py +++ b/src/sage_docbuild/conf.py @@ -961,7 +961,7 @@ def apply(self): parent = node.parent index = parent.index(node) prev_node = node.previous_sibling() - if isinstance(node.previous_sibling(), TabContainer): + if isinstance(prev_node, TabContainer): # Make sure not to merge inline tabs for adjacent literal blocks parent.insert(index, nodes.paragraph()) prev_node = parent[index] @@ -1103,4 +1103,3 @@ def feature_tags(): for feature in all_features(): if feature.is_present(): yield 'feature_' + feature.name.replace('.', '_') - From c431e2cd15f7aeecc3816ac28b6ec906cab08df2 Mon Sep 17 00:00:00 2001 From: Benjamin Hackl Date: Mon, 18 Nov 2024 08:51:52 +0100 Subject: [PATCH 106/210] reuse computed power, attempt early return --- src/sage/groups/misc_gps/argument_groups.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/groups/misc_gps/argument_groups.py b/src/sage/groups/misc_gps/argument_groups.py index 8d539c90438..88e48e4586b 100644 --- a/src/sage/groups/misc_gps/argument_groups.py +++ b/src/sage/groups/misc_gps/argument_groups.py @@ -1474,10 +1474,9 @@ def __pow__(self, exponent): result = self._element_ ** exponent P = self.parent() try: - result = P.element_class(P, self._element_ ** exponent) + return P.element_class(P, result) except (ValueError, TypeError): - pass - return result + return result def __invert__(self): r""" From 29e2888e55e75716b0183b5b73563ee10b5eed7c Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Mon, 18 Nov 2024 11:12:03 +0100 Subject: [PATCH 107/210] Upgrade to version with spkg-config --- build/pkgs/libbraiding/checksums.ini | 4 +- build/pkgs/libbraiding/package-version.txt | 2 +- build/pkgs/libbraiding/spkg-configure.m4 | 49 ++-------------------- 3 files changed, 7 insertions(+), 48 deletions(-) diff --git a/build/pkgs/libbraiding/checksums.ini b/build/pkgs/libbraiding/checksums.ini index d48af2f9e18..0795b89fdf6 100644 --- a/build/pkgs/libbraiding/checksums.ini +++ b/build/pkgs/libbraiding/checksums.ini @@ -1,4 +1,4 @@ tarball=libbraiding-VERSION-actually-VERSION.tar.gz -sha1=bb56d66b438e2deee7e5af4e08bba2b3b0411210 -sha256=428e8b22a42e5539e511619ac61242e088642054bacae1daef174667ecf19000 +sha1=8c22d5d396e2c4d2dd032172589042933b651108 +sha256=d1738c3ad64a90ca0ad968d2e3c9069b0de08abcf37fb44a151a229d88203950 upstream_url=https://github.com/miguelmarco/libbraiding/releases/download/VERSION/libbraiding-VERSION.tar.gz diff --git a/build/pkgs/libbraiding/package-version.txt b/build/pkgs/libbraiding/package-version.txt index 7e32cd56983..3a3cd8cc8b0 100644 --- a/build/pkgs/libbraiding/package-version.txt +++ b/build/pkgs/libbraiding/package-version.txt @@ -1 +1 @@ -1.3 +1.3.1 diff --git a/build/pkgs/libbraiding/spkg-configure.m4 b/build/pkgs/libbraiding/spkg-configure.m4 index 8fd86aa20ea..67d80d77a64 100644 --- a/build/pkgs/libbraiding/spkg-configure.m4 +++ b/build/pkgs/libbraiding/spkg-configure.m4 @@ -1,50 +1,9 @@ SAGE_SPKG_CONFIGURE([libbraiding], [ - # Since libbraiding is a C++ library with no pkg-config file, - # the best we can do here is compile and run a test program - # linked against it. - AC_LANG_PUSH(C++) - SAVED_LIBS=$LIBS - LIBS="$LIBS -lbraiding" - AC_MSG_CHECKING([if we can link against libbraiding]) - AC_RUN_IFELSE([ - AC_LANG_PROGRAM([ - #include - #include - using namespace Braiding; - ],[ - // Mimic BraidGroup(2)([1,1]).thurston_type() in SageMath. - // thurstontype == 1 corresponds to "periodic" - if (thurstontype(2, {1,1}) == 1) { return 0; } else { return 1; } - ]) - ], - [ - AC_MSG_RESULT([yes]) + PKG_CHECK_MODULES([libbraiding], [libbraiding >= 1.3.1], [ + AC_MSG_RESULT([found libbraiding >= 1.3.1, will use installed version]) sage_spkg_install_libbraiding=no - ], - [ - AC_MSG_RESULT([no]) - sage_spkg_install_libbraiding=yes ],[ - AC_LINK_IFELSE([ - AC_LANG_PROGRAM([ - #include - #include - using namespace Braiding; - ],[ - // Mimic BraidGroup(2)([1,1]).thurston_type() in SageMath. - // thurstontype == 1 corresponds to "periodic" - if (thurstontype(2, {1,1}) == 1) { return 0; } else { return 1; } - ]) - ], - [ - AC_MSG_RESULT([yes]) - sage_spkg_install_libbraiding=no - ], - [ - AC_MSG_RESULT([no]) - sage_spkg_install_libbraiding=yes - ]) + AC_MSG_RESULT([couldn't find libbraiding >= 1.3.1. It will be installed]) + sage_spkg_install_libbraiding=yes ]) - LIBS=$SAVED_LIBS - AC_LANG_POP ]) From afa6746708c9465c99243117757017d29fefe2b9 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Mon, 18 Nov 2024 11:25:14 +0100 Subject: [PATCH 108/210] Fix doctests --- src/sage/groups/braid.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index 5a4b45c6c45..84d96b8972b 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -2249,7 +2249,7 @@ def super_summit_set_element(self): sage: B = BraidGroup(4) sage: b = B([1, 2, 1, 2, 3, -1, 2, 1, 3]) - sage: b.send_to_sss() + sage: b.super_summit_set_element() (s0*s2*s0*s1*s2*s1*s0, s0^-1*s1^-1*s0^-1*s2^-1*s1^-1*s0^-1*s1*s0*s2*s1*s0) """ to_sss = send_to_sss(self) @@ -2265,7 +2265,7 @@ def ultra_summit_set_element(self): sage: B = BraidGroup(4) sage: b = B([1, 2, 1, 2, 3, -1, 2, -1, 3]) - sage: b.send_to_uss() + sage: b.ultra_summit_set_element() (s0*s1*s0*s2*s1, s0^-1*s1^-1*s0^-1*s2^-1*s1^-1*s0^-1*s1*s2*s1^2*s0) """ to_uss = send_to_uss(self) @@ -2281,7 +2281,7 @@ def sliding_circuits_element(self): sage: B = BraidGroup(4) sage: b = B([1, 2, 1, 2, 3, -1, 2, -1, 3]) - sage: b.send_to_sc() + sage: b.sliding_circuits_element() (s0*s1*s0*s2*s1, s0^2*s1*s2) """ to_sc = send_to_sc(self) From 7861e8d21d33cd66077050498913da0b4f2daeab Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 28 Oct 2024 22:04:32 +0800 Subject: [PATCH 109/210] Remove imports from `gsl.all` I had troubles with importing `gsl` (on Windows) and tried to fix it by changing imports from `gsl.all` to more specific imports. Turns out the real problem was actually wrong `pkg-config` entry; but I thought these more specific imports might be helpful anyway and should (slightly) reduce the size of the built library. --- src/sage/calculus/integration.pyx | 5 ++++- src/sage/calculus/ode.pyx | 3 ++- src/sage/probability/probability_distribution.pyx | 3 ++- src/sage/rings/complex_mpfr.pyx | 1 - .../rings/number_field/number_field_morphisms.pyx | 6 ++---- src/sage/rings/real_double_element_gsl.pyx | 11 ++++++++++- src/sage/symbolic/pynac_impl.pxi | 1 - 7 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/sage/calculus/integration.pyx b/src/sage/calculus/integration.pyx index 179e5751894..643442ac714 100644 --- a/src/sage/calculus/integration.pyx +++ b/src/sage/calculus/integration.pyx @@ -31,7 +31,10 @@ from cysignals.signals cimport sig_on, sig_off from memory_allocator cimport MemoryAllocator from sage.rings.real_double import RDF -from sage.libs.gsl.all cimport * +from sage.libs.gsl.errno cimport gsl_set_error_handler_off +from sage.libs.gsl.integration cimport * +from sage.libs.gsl.monte cimport * +from sage.libs.gsl.rng cimport * from sage.misc.sageinspect import sage_getargspec from sage.ext.interpreters.wrapper_rdf cimport Wrapper_rdf from sage.ext.fast_callable import fast_callable diff --git a/src/sage/calculus/ode.pyx b/src/sage/calculus/ode.pyx index 2addf3e7f81..80eaf228533 100644 --- a/src/sage/calculus/ode.pyx +++ b/src/sage/calculus/ode.pyx @@ -22,7 +22,8 @@ from cysignals.memory cimport sig_malloc, sig_free from cysignals.signals cimport sig_on, sig_off from sage.misc.sageinspect import sage_getargspec -from sage.libs.gsl.all cimport * +from sage.libs.gsl.types cimport * +from sage.libs.gsl.odeiv cimport * import sage.calculus.interpolation diff --git a/src/sage/probability/probability_distribution.pyx b/src/sage/probability/probability_distribution.pyx index fab94479291..44385e08d27 100644 --- a/src/sage/probability/probability_distribution.pyx +++ b/src/sage/probability/probability_distribution.pyx @@ -40,7 +40,8 @@ REFERENCES: # **************************************************************************** from cysignals.memory cimport sig_malloc, sig_free -from sage.libs.gsl.all cimport * +from sage.libs.gsl.rng cimport * +from sage.libs.gsl.random cimport * import sage.misc.prandom as random import sage.rings.real_double from sage.modules.free_module_element import vector diff --git a/src/sage/rings/complex_mpfr.pyx b/src/sage/rings/complex_mpfr.pyx index bec9978401e..d24e61d2823 100644 --- a/src/sage/rings/complex_mpfr.pyx +++ b/src/sage/rings/complex_mpfr.pyx @@ -48,7 +48,6 @@ from sage.rings.integer cimport Integer from sage.rings.complex_double cimport ComplexDoubleElement from sage.rings.real_mpfr cimport RealNumber -from sage.libs.gsl.complex cimport * from sage.libs.mpmath.utils cimport mpfr_to_mpfval from sage.rings.integer_ring import ZZ diff --git a/src/sage/rings/number_field/number_field_morphisms.pyx b/src/sage/rings/number_field/number_field_morphisms.pyx index e71bad5db7c..330e0a8ab69 100644 --- a/src/sage/rings/number_field/number_field_morphisms.pyx +++ b/src/sage/rings/number_field/number_field_morphisms.pyx @@ -20,16 +20,14 @@ fields (generally `\RR` or `\CC`). # https://www.gnu.org/licenses/ # **************************************************************************** -import sage.rings.complex_double - from sage.structure.element cimport Element from sage.categories.morphism cimport Morphism from sage.categories.map cimport Map from sage.categories.pushout import pushout +from sage.rings.complex_double import CDF from sage.rings.real_lazy import RLF, CLF, LazyField, LazyAlgebraic - cdef class NumberFieldEmbedding(Morphism): cdef _gen_image @@ -254,7 +252,7 @@ cdef class EmbeddedNumberFieldMorphism(NumberFieldEmbedding): candidate_ambient_fields.append(ambient_field.algebraic_closure()) except NotImplementedError: pass - candidate_ambient_fields.append(sage.rings.complex_double.CDF) + candidate_ambient_fields.append(CDF) else: candidate_ambient_fields = [ambient_field] diff --git a/src/sage/rings/real_double_element_gsl.pyx b/src/sage/rings/real_double_element_gsl.pyx index 001564dee37..7fea4dbc155 100644 --- a/src/sage/rings/real_double_element_gsl.pyx +++ b/src/sage/rings/real_double_element_gsl.pyx @@ -8,7 +8,16 @@ from cysignals.signals cimport sig_on, sig_off from sage.arith.constants cimport * -from sage.libs.gsl.all cimport * +from sage.libs.gsl.errno cimport gsl_set_error_handler_off +from sage.libs.gsl.math cimport * +from sage.libs.gsl.exp cimport * +from sage.libs.gsl.log cimport gsl_sf_log +from sage.libs.gsl.trig cimport * +from sage.libs.gsl.dilog cimport gsl_sf_dilog +from sage.libs.gsl.gamma cimport gsl_sf_fact, gsl_sf_gamma +from sage.libs.gsl.zeta cimport gsl_sf_zeta +from sage.libs.gsl.erf cimport gsl_sf_erf + gsl_set_error_handler_off() diff --git a/src/sage/symbolic/pynac_impl.pxi b/src/sage/symbolic/pynac_impl.pxi index 967ff18d020..fcd084cea81 100644 --- a/src/sage/symbolic/pynac_impl.pxi +++ b/src/sage/symbolic/pynac_impl.pxi @@ -40,7 +40,6 @@ from sage.arith.functions import lcm from sage.cpython.string cimport str_to_bytes, char_to_str from sage.ext.stdsage cimport PY_NEW from sage.libs.gmp.all cimport * -from sage.libs.gsl.types cimport * from sage.libs.gsl.complex cimport * from sage.libs.gsl.gamma cimport gsl_sf_lngamma_complex_e from sage.libs.mpmath import utils as mpmath_utils From ee8582e5f0dfbb3787f17c99ca57ff7b153c8750 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 30 Oct 2024 16:41:27 +0800 Subject: [PATCH 110/210] Remove whitespace --- src/sage/probability/probability_distribution.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/probability/probability_distribution.pyx b/src/sage/probability/probability_distribution.pyx index 44385e08d27..a1d11fb2bfb 100644 --- a/src/sage/probability/probability_distribution.pyx +++ b/src/sage/probability/probability_distribution.pyx @@ -40,7 +40,7 @@ REFERENCES: # **************************************************************************** from cysignals.memory cimport sig_malloc, sig_free -from sage.libs.gsl.rng cimport * +from sage.libs.gsl.rng cimport * from sage.libs.gsl.random cimport * import sage.misc.prandom as random import sage.rings.real_double From 19ec8c061edb77c4fa20668501d5fba2af63e25b Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Mon, 18 Nov 2024 11:47:20 +0100 Subject: [PATCH 111/210] Fix imports in doctests --- src/sage/libs/braiding.pyx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sage/libs/braiding.pyx b/src/sage/libs/braiding.pyx index cdefd5d2867..6bfdea11dc4 100644 --- a/src/sage/libs/braiding.pyx +++ b/src/sage/libs/braiding.pyx @@ -405,6 +405,7 @@ def send_to_sss(braid): EXAMPLES:: + sage: from sage.libs.braiding import send_to_sss sage: B = BraidGroup(4) sage: d = B([1, 2, 1, 2, 3, -1, 2,- 3]) sage: send_to_sss(d) @@ -434,6 +435,7 @@ def send_to_uss(braid): EXAMPLES:: + sage: from sage.libs.braiding import send_to_uss sage: B = BraidGroup(4) sage: d = B([1, 2, 1, 2, 3, -1, 2,- 1]) sage: send_to_uss(d) @@ -463,6 +465,7 @@ def send_to_sc(braid): EXAMPLES:: + sage: from sage.libs.braiding import send_to_sc sage: B = BraidGroup(4) sage: d = B([1, 2, 1, 2, 3, -1, 2, 2]) sage: send_to_sc(d) @@ -492,6 +495,7 @@ def trajectory(braid): EXAMPLES:: + sage: from sage.libs.braiding import trajectory sage: B = BraidGroup(4) sage: d = B([1, 2, 1, 2, 3, -1, 2, 2]) sage: trajectory(d) @@ -524,6 +528,7 @@ def cyclic_slidings(braid): EXAMPLES:: + sage: from sage.libs.braiding import cyclic_slidings sage: B = BraidGroup(4) sage: d = B([1, 2, 1, 2, 3, -1, 2, 2]) sage: cyclic_slidings(d) From 10c769ddb9554d5274f7baf9c91e7f88951c526a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 18 Nov 2024 14:12:23 +0100 Subject: [PATCH 112/210] more coercible algebras --- src/sage/algebras/free_algebra.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 0a081f63e21..2871442611b 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -757,7 +757,7 @@ def _coerce_map_from_(self, R): # free algebras in the same variable over any base that coerces in: if isinstance(R, (FreeAlgebra_generic, FreeAlgebra_letterplace)): - if R.variable_names() == self.variable_names(): + if all(x in self.variable_names() for x in R.variable_names()): return self.base_ring().has_coerce_map_from(R.base_ring()) if isinstance(R, PBWBasisOfFreeAlgebra): return self.has_coerce_map_from(R._alg) From 4fa4a34e0191db5c8c96a5b3df31b68a6228be1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 18 Nov 2024 14:15:09 +0100 Subject: [PATCH 113/210] fix doctests --- src/sage/algebras/free_algebra.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 2871442611b..997bd73bbc8 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -720,7 +720,7 @@ def _coerce_map_from_(self, R): sage: G._coerce_map_from_(F) True sage: F._coerce_map_from_(H) - False + True sage: F._coerce_map_from_(QQ) False sage: G._coerce_map_from_(QQ) @@ -1316,7 +1316,7 @@ def _coerce_map_from_(self, R): sage: G._coerce_map_from_(F) True sage: F._coerce_map_from_(H) - False + True sage: F._coerce_map_from_(QQ) False sage: G._coerce_map_from_(QQ) From 66600512aa032272a8d5fb3b6a6d6666f44f1823 Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Mon, 18 Nov 2024 15:54:17 -0500 Subject: [PATCH 114/210] fix many more single backquotes --- src/sage/categories/bialgebras_with_basis.py | 2 +- src/sage/categories/category_types.py | 2 +- src/sage/categories/rings.py | 4 ++-- src/sage/coding/abstract_code.py | 24 +++++++++---------- src/sage/coding/guruswami_sudan/gs_decoder.py | 2 +- src/sage/combinat/abstract_tree.py | 2 +- src/sage/combinat/crystals/pbw_datum.pyx | 2 +- src/sage/combinat/crystals/spins.pyx | 4 ++-- .../designs/evenly_distributed_sets.pyx | 2 +- src/sage/combinat/matrices/dancing_links.pyx | 2 +- .../multiset_partition_into_sets_ordered.py | 2 +- src/sage/combinat/permutation_cython.pyx | 2 +- .../combinat/root_system/type_reducible.py | 2 +- src/sage/combinat/tableau.py | 2 +- .../crypto/key_exchange/diffie_hellman.py | 2 +- src/sage/databases/cubic_hecke_db.py | 2 +- .../arithmetic_dynamics/projective_ds.py | 4 ++-- src/sage/features/databases.py | 2 +- src/sage/game_theory/normal_form_game.py | 2 +- .../geometry/polyhedron/base_number_field.py | 2 +- src/sage/graphs/base/c_graph.pyx | 2 +- src/sage/graphs/base/sparse_graph.pyx | 2 +- src/sage/graphs/centrality.pyx | 2 +- .../tree_decomposition.pyx | 4 ++-- src/sage/groups/cubic_braid.py | 2 +- src/sage/interfaces/interface.py | 2 +- src/sage/interfaces/mathematica.py | 2 +- src/sage/interfaces/mathics.py | 2 +- src/sage/interfaces/maxima_lib.py | 6 ++--- src/sage/matrix/matrix2.pyx | 2 +- src/sage/matrix/matrix_double_dense.pyx | 4 ++-- src/sage/misc/cachefunc.pyx | 2 +- src/sage/misc/persist.pyx | 2 +- src/sage/misc/superseded.py | 2 +- src/sage/modular/hypergeometric_motive.py | 4 ++-- .../hecke_triangle_groups.py | 2 +- src/sage/modules/free_module_element.pyx | 2 +- .../numerical/backends/generic_backend.pyx | 2 +- .../numerical/interactive_simplex_method.py | 6 ++--- src/sage/plot/misc.py | 2 +- src/sage/plot/primitive.py | 2 +- src/sage/quadratic_forms/binary_qf.py | 4 ++-- ...otics_multivariate_generating_functions.py | 2 +- .../finite_drinfeld_module.py | 6 ++--- .../rings/padics/padic_generic_element.pyx | 2 +- .../rings/polynomial/polynomial_element.pyx | 4 ++-- .../polynomial/polynomial_quotient_ring.py | 2 +- src/sage/rings/polynomial/polynomial_ring.py | 2 +- .../polynomial/weil/weil_polynomials.pyx | 8 +++---- src/sage/rings/ring.pyx | 2 +- src/sage/rings/species.py | 4 ++-- src/sage/sandpiles/sandpile.py | 2 +- src/sage/schemes/elliptic_curves/ell_field.py | 6 ++--- .../hyperelliptic_curves/jacobian_generic.py | 4 ++-- src/sage/sets/disjoint_set.pyx | 8 +++---- src/sage/structure/element.pyx | 4 ++-- src/sage/structure/global_options.py | 2 +- src/sage/topology/simplicial_set.py | 2 +- src/sage/topology/simplicial_set_examples.py | 2 +- .../command/sage_build_ext_minimal.py | 2 +- 60 files changed, 96 insertions(+), 96 deletions(-) diff --git a/src/sage/categories/bialgebras_with_basis.py b/src/sage/categories/bialgebras_with_basis.py index 10e829fd7fb..2589773dd31 100644 --- a/src/sage/categories/bialgebras_with_basis.py +++ b/src/sage/categories/bialgebras_with_basis.py @@ -402,7 +402,7 @@ def convolution_product(self, *maps): for mor in T[:-1]: # ALGORITHM: - # `split_convolve` moves terms of the form x # y to x*Ti(y1) # y2 in Sweedler notation. + # ``split_convolve`` moves terms of the form x # y to x*Ti(y1) # y2 in Sweedler notation. def split_convolve(x_y): x, y = x_y return (((xy1, y2), c * d) diff --git a/src/sage/categories/category_types.py b/src/sage/categories/category_types.py index de62a0109f0..01455011c40 100644 --- a/src/sage/categories/category_types.py +++ b/src/sage/categories/category_types.py @@ -458,7 +458,7 @@ def _subcategory_hook_(self, C): ....: VectorSpaces(GF(3)).parent_class) True - Check that :issue:`16618` is fixed: this `_subcategory_hook_` + Check that :issue:`16618` is fixed: this ``_subcategory_hook_`` method is only valid for :class:`Category_over_base_ring`, not :class:`Category_over_base`:: diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 8db71edfb9c..b2266980029 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -621,8 +621,8 @@ def _mul_(self, x, switch_sides=False): INPUT: - - `x`, an object to multiply with. - - `switch_sides` (optional bool): If ``False``, + - ``x``, an object to multiply with. + - ``switch_sides`` (optional bool): If ``False``, the product is ``self*x``; if ``True``, the product is ``x*self``. diff --git a/src/sage/coding/abstract_code.py b/src/sage/coding/abstract_code.py index d94eb1ca309..3d1fe305dbc 100644 --- a/src/sage/coding/abstract_code.py +++ b/src/sage/coding/abstract_code.py @@ -324,9 +324,9 @@ def __iter__(self): r""" Return an error message requiring to override ``__iter__`` in ``self``. - As one has to implement specific category related methods (`__iter__` and - `__contains__`) when writing a new code class which inherits from - :class:`AbstractCode`, the generic call to `__iter__` has to fail. + As one has to implement specific category related methods (``__iter__`` and + ``__contains__``) when writing a new code class which inherits from + :class:`AbstractCode`, the generic call to ``__iter__`` has to fail. EXAMPLES: @@ -352,9 +352,9 @@ def __contains__(self, c): r""" Return an error message requiring to override ``__contains__`` in ``self``. - As one has to implement specific category related methods (`__iter__` and - `__contains__`) when writing a new code class which inherits from - :class:`AbstractCode`, the generic call to `__contains__` has to fail. + As one has to implement specific category related methods (``__iter__`` and + ``__contains__``) when writing a new code class which inherits from + :class:`AbstractCode`, the generic call to ``__contains__`` has to fail. EXAMPLES: @@ -448,9 +448,9 @@ def _repr_(self): r""" Return an error message requiring to override ``_repr_`` in ``self``. - As one has to implement specific representation methods (`_repr_` and - `_latex_`) when writing a new code class which inherits from - :class:`AbstractCode`, the generic call to `_repr_` has to fail. + As one has to implement specific representation methods (``_repr_`` and + ``_latex_``) when writing a new code class which inherits from + :class:`AbstractCode`, the generic call to ``_repr_`` has to fail. EXAMPLES: @@ -476,9 +476,9 @@ def _latex_(self): r""" Return an error message requiring to override ``_latex_`` in ``self``. - As one has to implement specific representation methods (`_repr_` and - `_latex_`) when writing a new code class which inherits from - :class:`AbstractCode`, the generic call to `_latex_` has to fail. + As one has to implement specific representation methods (``_repr_`` and + ``_latex_``) when writing a new code class which inherits from + :class:`AbstractCode`, the generic call to ``_latex_`` has to fail. EXAMPLES: diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index a5bf1cf345f..e909c3a0bf3 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -389,7 +389,7 @@ def get_tau(s, l): # Either s or l is set, but not both. First a shared local function def find_integral_max(real_max, f): """Given a real (local) maximum of a function `f`, return that of - the integers around `real_max` which gives the (local) integral + the integers around ``real_max`` which gives the (local) integral maximum, and the value of at that point.""" if real_max in ZZ: int_max = ZZ(real_max) diff --git a/src/sage/combinat/abstract_tree.py b/src/sage/combinat/abstract_tree.py index 8ea604428f1..8359b3a8198 100644 --- a/src/sage/combinat/abstract_tree.py +++ b/src/sage/combinat/abstract_tree.py @@ -1857,7 +1857,7 @@ def __setitem__(self, idx, value): The tree ``self`` must be in a mutable state. See :mod:`sage.structure.list_clone` for more details about mutability. The default implementation here assume that the - container of the node implement a method `_setitem` with signature + container of the node implement a method ``_setitem`` with signature `self._setitem(idx, value)`. It is usually provided by inheriting from :class:`~sage.structure.list_clone.ClonableArray`. diff --git a/src/sage/combinat/crystals/pbw_datum.pyx b/src/sage/combinat/crystals/pbw_datum.pyx index 03a7aee51d9..fa3be1ca72e 100644 --- a/src/sage/combinat/crystals/pbw_datum.pyx +++ b/src/sage/combinat/crystals/pbw_datum.pyx @@ -167,7 +167,7 @@ class PBWDatum(): def star(self): """ Return the starred version of ``self``, i.e., - with reversed `long_word` and `lusztig_datum` + with reversed ``long_word`` and ``lusztig_datum`` EXAMPLES:: diff --git a/src/sage/combinat/crystals/spins.pyx b/src/sage/combinat/crystals/spins.pyx index 5ff109602d0..b45e0c24b17 100644 --- a/src/sage/combinat/crystals/spins.pyx +++ b/src/sage/combinat/crystals/spins.pyx @@ -65,7 +65,7 @@ def CrystalOfSpins(ct): Return the spin crystal of the given type `B`. This is a combinatorial model for the crystal with highest weight - `Lambda_n` (the `n`-th fundamental weight). It has + `\lambda_n` (the `n`-th fundamental weight). It has `2^n` elements, here called Spins. See also :func:`~sage.combinat.crystals.letters.CrystalOfLetters`, :func:`~sage.combinat.crystals.spins.CrystalOfSpinsPlus`, @@ -108,7 +108,7 @@ def CrystalOfSpinsPlus(ct): r""" Return the plus spin crystal of the given type D. - This is the crystal with highest weight `Lambda_n` (the + This is the crystal with highest weight `\lambda_n` (the `n`-th fundamental weight). INPUT: diff --git a/src/sage/combinat/designs/evenly_distributed_sets.pyx b/src/sage/combinat/designs/evenly_distributed_sets.pyx index 8fdf10c0bf1..e2a4d04b561 100644 --- a/src/sage/combinat/designs/evenly_distributed_sets.pyx +++ b/src/sage/combinat/designs/evenly_distributed_sets.pyx @@ -408,7 +408,7 @@ cdef class EvenlyDistributedSetsBacktracker: whether the set `f_{ij}(B)` is smaller than `B`. This is an internal function and should only be call by the backtracker - implemented in the method `__iter__`. + implemented in the method ``__iter__``. OUTPUT: ``False`` if ``self.B`` is not minimal diff --git a/src/sage/combinat/matrices/dancing_links.pyx b/src/sage/combinat/matrices/dancing_links.pyx index 475b5ef3e1b..d016f3495ea 100644 --- a/src/sage/combinat/matrices/dancing_links.pyx +++ b/src/sage/combinat/matrices/dancing_links.pyx @@ -154,7 +154,7 @@ cdef class dancing_linksWrapper: Initialization of the search algorithm. This adds the rows to the instance of dancing_links. This method is - used by `__init__` and `reinitialize` methods and should not be + used by ``__init__`` and ``reinitialize`` methods and should not be used directly. EXAMPLES:: diff --git a/src/sage/combinat/multiset_partition_into_sets_ordered.py b/src/sage/combinat/multiset_partition_into_sets_ordered.py index 67fbcb4e70a..49131e3a5c7 100755 --- a/src/sage/combinat/multiset_partition_into_sets_ordered.py +++ b/src/sage/combinat/multiset_partition_into_sets_ordered.py @@ -1885,7 +1885,7 @@ def __iter__(self): # iterate over blocks of letters over an alphabet if "alphabet" in self.constraints: A = self.constraints["alphabet"] - # establish a cutoff order `max_ell` + # establish a cutoff order ``max_ell`` max = self.constraints.get("max_length", infinity) max = self.constraints.get("length", max) max = max * len(A) diff --git a/src/sage/combinat/permutation_cython.pyx b/src/sage/combinat/permutation_cython.pyx index 978510c4ae9..db58f15f51e 100644 --- a/src/sage/combinat/permutation_cython.pyx +++ b/src/sage/combinat/permutation_cython.pyx @@ -74,7 +74,7 @@ cdef int next_swap(int n, int *c, int *o) noexcept: Note, Knuth's descriptions of algorithms tend to encourage one to think of finite state machines. For convenience, we have added comments to show what state the machine is - in at any given point in the algorithm. `plain_swap_reset` + in at any given point in the algorithm. ``plain_swap_reset`` sets the state to 1, and this function begins and ends in state 2. diff --git a/src/sage/combinat/root_system/type_reducible.py b/src/sage/combinat/root_system/type_reducible.py index 53dadb9864d..dfede775aa3 100644 --- a/src/sage/combinat/root_system/type_reducible.py +++ b/src/sage/combinat/root_system/type_reducible.py @@ -90,7 +90,7 @@ def __init__(self, types): ((1, 0), 5), ((1, 1), 6), ((1, 2), 7), ((1, 3), 8), ((1, 4), 9), ((1, 5), 10), ((2, 1), 11), ((2, 2), 12), ((2, 3), 13)] - Similarly, the attribute `_shifts` specifies by how much the + Similarly, the attribute ``_shifts`` specifies by how much the indices of the bases of the ambient spaces of the components are shifted in the ambient space of this Cartan type:: diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index aace1ba5a2c..cb912e67409 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -5841,7 +5841,7 @@ class SemistandardTableaux(Tableaux): OUTPUT: - The appropriate class, after checking basic consistency tests. (For - example, specifying ``eval`` implies a value for `max_entry`). + example, specifying ``eval`` implies a value for ``max_entry``). A semistandard tableau is a tableau whose entries are positive integers, which are weakly increasing in rows and strictly increasing down columns. diff --git a/src/sage/crypto/key_exchange/diffie_hellman.py b/src/sage/crypto/key_exchange/diffie_hellman.py index 47b6bd392a8..8dee1010a19 100644 --- a/src/sage/crypto/key_exchange/diffie_hellman.py +++ b/src/sage/crypto/key_exchange/diffie_hellman.py @@ -254,7 +254,7 @@ def subgroup_size(self) -> Integer: def __len__(self) -> int: """ Calculates the size of the subgroup of `\\GF{p}` generated by - ``self.generator()``. This is a wrapper around `subgroup_size`. + ``self.generator()``. This is a wrapper around ``subgroup_size``. TESTS:: diff --git a/src/sage/databases/cubic_hecke_db.py b/src/sage/databases/cubic_hecke_db.py index 668af9abacc..bc5b9ba9bdd 100644 --- a/src/sage/databases/cubic_hecke_db.py +++ b/src/sage/databases/cubic_hecke_db.py @@ -729,7 +729,7 @@ def __init__(self, num_strands): def _warn_incompatibility(self, fname): """ - Warn the user that he has an incomaptible file cache under `Sage_DOT` + Warn the user that he has an incomaptible file cache under ``Sage_DOT`` and move it away to another file (marked with timestamp). EXAMPLES:: diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 2fab95104f1..d9bff902d6d 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -6837,10 +6837,10 @@ def Lattes_to_curve(self, return_conjugation=False, check_lattes=False): INPUT: - `return_conjugation`` -- (default: ``False``) if ``True``, then + ``return_conjugation`` -- (default: ``False``) if ``True``, then return the conjugation that moves self to a map that comes from a Short Weierstrass Model Elliptic curve - `check_lattes``.-.(default:.``False``) if ``True``, then will ValueError if not Lattes + ``check_lattes``.-.(default:.``False``) if ``True``, then will ValueError if not Lattes OUTPUT: a Short Weierstrass Model Elliptic curve which is isogenous to the Elliptic curve of 'self', diff --git a/src/sage/features/databases.py b/src/sage/features/databases.py index 9d070d932ed..2394d4d6c05 100644 --- a/src/sage/features/databases.py +++ b/src/sage/features/databases.py @@ -25,7 +25,7 @@ def sage_data_path(data_name): r""" - Search path for database `data_name`. + Search path for database ``data_name``. EXAMPLES:: diff --git a/src/sage/game_theory/normal_form_game.py b/src/sage/game_theory/normal_form_game.py index e46e96c2b32..39622aaf3ef 100644 --- a/src/sage/game_theory/normal_form_game.py +++ b/src/sage/game_theory/normal_form_game.py @@ -1989,7 +1989,7 @@ def _solve_enumeration(self, maximization=True): sage: c._solve_enumeration() [[(0, 1), (1, 0)]] - Testing against an error in `_is_NE`. Note that 1 equilibrium is + Testing against an error in ``_is_NE``. Note that 1 equilibrium is missing: ``[(2/3, 1/3), (0, 1)]``, however this equilibrium has supports of different sizes. This only occurs in degenerate games and is not supported in the `enumeration` algorithm:: diff --git a/src/sage/geometry/polyhedron/base_number_field.py b/src/sage/geometry/polyhedron/base_number_field.py index ef912a5e501..c1d0ab39190 100644 --- a/src/sage/geometry/polyhedron/base_number_field.py +++ b/src/sage/geometry/polyhedron/base_number_field.py @@ -28,7 +28,7 @@ def _number_field_elements_from_algebraics_list_of_lists_of_lists(listss, **kwds): r""" - Like `number_field_elements_from_algebraics`, but for a list of lists of lists. + Like ``number_field_elements_from_algebraics``, but for a list of lists of lists. EXAMPLES:: diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 1aa7b32d691..00a535c3335 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -2824,7 +2824,7 @@ cdef class CGraphBackend(GenericGraphBackend): # WARNING # If you modify this, you must keep in mind the documentation in the - # corresponding method in `generic_graph.py` in the method `edge_iterator`. + # corresponding method in ``generic_graph.py`` in the method ``edge_iterator``. # E.g. code assumes that you can use an iterator to relabel or delete arcs. u_int = cg._next_neighbor_unsafe(v_int, -1, out, &l_int) diff --git a/src/sage/graphs/base/sparse_graph.pyx b/src/sage/graphs/base/sparse_graph.pyx index a02541436ac..d82ba543669 100644 --- a/src/sage/graphs/base/sparse_graph.pyx +++ b/src/sage/graphs/base/sparse_graph.pyx @@ -1569,7 +1569,7 @@ cdef class SparseGraphBackend(CGraphBackend): # WARNING # If you modify this, you must keep in mind the documentation in the - # corresponding method in `generic_graph.py` in the method `edge_iterator`. + # corresponding method in ``generic_graph.py`` in the method ``edge_iterator``. # E.g. code assumes that you can use an iterator to relabel or delete arcs. r = self._cg._neighbors_BTNode_unsafe(v_int, out, neighbors, maxdegree) diff --git a/src/sage/graphs/centrality.pyx b/src/sage/graphs/centrality.pyx index e249046ae70..6a68eab6684 100755 --- a/src/sage/graphs/centrality.pyx +++ b/src/sage/graphs/centrality.pyx @@ -131,7 +131,7 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True): - ``G`` -- a graph - ``_`` -- this variable is ignored, only its type matters. If it is of type - `mpq_t` then computations are made on `Q`, if it is ``double`` the + ``mpq_t`` then computations are made on `Q`, if it is ``double`` the computations are made on ``double``. - ``normalize`` -- boolean (default: ``True``); whether to renormalize the diff --git a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx index 8ed9ee9d224..da385943bd1 100644 --- a/src/sage/graphs/graph_decompositions/tree_decomposition.pyx +++ b/src/sage/graphs/graph_decompositions/tree_decomposition.pyx @@ -75,7 +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:`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`. @@ -830,7 +830,7 @@ def make_nice_tree_decomposition(graph, tree_decomp): .. WARNING:: - This method assumes that the vertices of the input tree `tree_decomp` + 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`. diff --git a/src/sage/groups/cubic_braid.py b/src/sage/groups/cubic_braid.py index e407b9d1326..d1edce0e5e1 100644 --- a/src/sage/groups/cubic_braid.py +++ b/src/sage/groups/cubic_braid.py @@ -371,7 +371,7 @@ def burau_matrix(self, root_bur=None, domain=None, characteristic=None, - ``root_bur`` -- six (resp. twelfth) root of unity in some field (default: root of unity over `\QQ`) - ``domain`` -- (default: cyclotomic field of order 3 and degree 2, resp. - the domain of `root_bur` if given) base ring for the Burau matrix + the domain of ``root_bur`` if given) base ring for the Burau matrix - ``characteristic`` -- integer giving the characteristic of the domain (default: 0 or the characteristic of ``domain`` if given) - ``var`` -- string used for the indeterminate name in case ``root_bur`` diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 6f2fb118968..bd1095e8c70 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -880,7 +880,7 @@ def _reduce(self): Special care has to be taken with strings. Since for example `r("abc")` will be interpreted as the R-command abc (not a string in R), we have to reduce to - `"'abc'"` instead. That is dependant on the Elements `is_string` function to + `"'abc'"` instead. That is dependant on the Elements ``is_string`` function to be implemented correctly. This has gone wrong in the past and remained uncaught by the doctests because the original identifier was reused. This test makes sure that does not happen again:: diff --git a/src/sage/interfaces/mathematica.py b/src/sage/interfaces/mathematica.py index 39c3aff9dc2..488a1fb1af5 100644 --- a/src/sage/interfaces/mathematica.py +++ b/src/sage/interfaces/mathematica.py @@ -454,7 +454,7 @@ def clean_output(s): def _un_camel(name): """ - Convert `CamelCase` to `camel_case`. + Convert ``CamelCase`` to ``camel_case``. EXAMPLES:: diff --git a/src/sage/interfaces/mathics.py b/src/sage/interfaces/mathics.py index a6d39ad3c14..58a376b9c72 100644 --- a/src/sage/interfaces/mathics.py +++ b/src/sage/interfaces/mathics.py @@ -402,7 +402,7 @@ def _mathics_sympysage_symbol(self): This function replaces ``_sympysage_symbol`` to take care of the special names used in Mathics. - It is set to the method `_sage_` of the Sympy class + It is set to the method ``_sage_`` of the Sympy class :class:`sympy.core.symbol.Sympol`. EXAMPLES:: diff --git a/src/sage/interfaces/maxima_lib.py b/src/sage/interfaces/maxima_lib.py index 1b1e97f3578..a8ba86ae3d0 100644 --- a/src/sage/interfaces/maxima_lib.py +++ b/src/sage/interfaces/maxima_lib.py @@ -35,7 +35,7 @@ classical Maxima Pexpect interface in case no new implementation has been made. This interface is the one used for calculus by Sage -and is accessible as `maxima_calculus`:: +and is accessible as ``maxima_calculus``:: sage: maxima_calculus Maxima_lib @@ -80,8 +80,8 @@ TESTS: Check our workaround for a race in ecl works, see :issue:`26968`. -We use a temporary `MAXIMA_USERDIR` so it's empty; we place it -in `DOT_SAGE` since we expect it to have more latency than `/tmp`. +We use a temporary ``MAXIMA_USERDIR`` so it's empty; we place it +in ``DOT_SAGE`` since we expect it to have more latency than ``/tmp``. sage: import tempfile, subprocess sage: tmpdir = tempfile.TemporaryDirectory(dir=DOT_SAGE) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index d2f0815e81e..dec25a76e54 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -3056,7 +3056,7 @@ cdef class Matrix(Matrix1): ALGORITHM: - If the base ring has a method `_matrix_charpoly`, we use it. + If the base ring has a method ``_matrix_charpoly``, we use it. In the generic case of matrices over a ring (commutative and with unity), there is a division-free algorithm, which can be accessed diff --git a/src/sage/matrix/matrix_double_dense.pyx b/src/sage/matrix/matrix_double_dense.pyx index 71254649be7..b3ee53e9c37 100644 --- a/src/sage/matrix/matrix_double_dense.pyx +++ b/src/sage/matrix/matrix_double_dense.pyx @@ -2396,8 +2396,8 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): r""" Return ``True`` if the matrix is (skew-)Hermitian. - For internal purposes. This function is used in `is_hermitian` - and `is_skew_hermitian` functions. + For internal purposes. This function is used in ``is_hermitian`` + and ``is_skew_hermitian`` functions. INPUT: diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index 52c10174dca..f800cfd27f1 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -1462,7 +1462,7 @@ class CachedMethodPickle(): we replace the actual cached method by a place holder, that kills itself as soon as any attribute is requested. Then, the original cached attribute is reinstated. But the - cached values are in fact saved (if `do_pickle` is set.) + cached values are in fact saved (if ``do_pickle`` is set.) EXAMPLES:: diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx index 7429388112e..15476a3ec37 100644 --- a/src/sage/misc/persist.pyx +++ b/src/sage/misc/persist.pyx @@ -57,7 +57,7 @@ from sage.misc.sage_unittest import TestSuite # Apart from this, you are free to use these variables as you like. # # However, the standard utilisation is the following. -# The pickling method (namely `__reduce__`) checks if the id of the +# The pickling method (namely ``__reduce__``) checks if the id of the # current element appears in the dictionary `already_pickled`. If it # does not, the methods records that this element is about to be # pickled by adding the entry { id: True } to `already_pickled`. diff --git a/src/sage/misc/superseded.py b/src/sage/misc/superseded.py index 6aaa8e6fb6f..fcc63bb1013 100644 --- a/src/sage/misc/superseded.py +++ b/src/sage/misc/superseded.py @@ -105,7 +105,7 @@ def deprecation_cython(issue_number, message, stacklevel=3): TESTS: - We check that `deprecation_cython` in a cython function generates a warning + We check that ``deprecation_cython`` in a cython function generates a warning with the same callsite reference as `deprecation` in a python function, whereas `deprecation` in a cython function does not:: diff --git a/src/sage/modular/hypergeometric_motive.py b/src/sage/modular/hypergeometric_motive.py index 5418a1fff58..dc3cd115306 100644 --- a/src/sage/modular/hypergeometric_motive.py +++ b/src/sage/modular/hypergeometric_motive.py @@ -685,7 +685,7 @@ def zigzag(self, x, flip_beta=False): Count ``alpha``'s at most ``x`` minus ``beta``'s at most ``x``. This function is used to compute the weight and the Hodge numbers. - With `flip_beta` set to ``True``, replace each `b` in `\beta` + With ``flip_beta`` set to ``True``, replace each `b` in `\beta` with `1-b`. .. SEEALSO:: @@ -1317,7 +1317,7 @@ def padic_H_value(self, p, f, t, prec=None, cache_p=False): If left unspecified, `prec` is set to the minimum `p`-adic precision needed to recover the Euler factor. - If `cache_p` is ``True``, then the function caches an intermediate + If ``cache_p`` is ``True``, then the function caches an intermediate result which depends only on `p` and `f`. This leads to a significant speedup when iterating over `t`. diff --git a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py index 6aedcba881c..f4a4c3a892b 100644 --- a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py +++ b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py @@ -1383,7 +1383,7 @@ def rational_period_functions(self, k, D): The method assumes that ``D > 0``. - Also see the element method `rational_period_function` for more information. + Also see the element method ``rational_period_function`` for more information. - ``k`` -- even integer, the desired weight of the rational period functions diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index f840143a073..a0be451f3f4 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -3451,7 +3451,7 @@ cdef class FreeModuleElement(Vector): # abstract base class The more general :meth:`sage.matrix.matrix2.tensor_product` is an operation on a pair of matrices. If we construct a pair of vectors as a column vector and a row vector, then an outer product and a - tensor product are identical. Thus `tensor_product` is a synonym + tensor product are identical. Thus ``tensor_product`` is a synonym for this method. :: sage: u = vector(QQ, [1/2, 1/3, 1/4, 1/5]) diff --git a/src/sage/numerical/backends/generic_backend.pyx b/src/sage/numerical/backends/generic_backend.pyx index b7962c3c877..edda183ade9 100644 --- a/src/sage/numerical/backends/generic_backend.pyx +++ b/src/sage/numerical/backends/generic_backend.pyx @@ -265,7 +265,7 @@ cdef class GenericBackend: @classmethod def _test_sense(cls, tester=None, **options): """ - Run tests on `set_sense` and `is_maximization`. + Run tests on ``set_sense`` and ``is_maximization``. TESTS:: diff --git a/src/sage/numerical/interactive_simplex_method.py b/src/sage/numerical/interactive_simplex_method.py index a89da826c77..bc2c5e468e4 100644 --- a/src/sage/numerical/interactive_simplex_method.py +++ b/src/sage/numerical/interactive_simplex_method.py @@ -4783,9 +4783,9 @@ def add_row(self, nonbasic_coefficients, constant, basic_variable=None): The implementation of this method for revised dictionaries adds a new inequality constraint to the problem, in which the given - `basic_variable` becomes the slack variable. The resulting dictionary - (with `basic_variable` added to the basis) will have the given - `nonbasic_coefficients` and `constant` as a new row. + ``basic_variable`` becomes the slack variable. The resulting dictionary + (with ``basic_variable`` added to the basis) will have the given + ``nonbasic_coefficients`` and ``constant`` as a new row. INPUT: diff --git a/src/sage/plot/misc.py b/src/sage/plot/misc.py index b86b52b05f6..ca19ef887cb 100644 --- a/src/sage/plot/misc.py +++ b/src/sage/plot/misc.py @@ -285,7 +285,7 @@ def _multiple_of_constant(n, pos, const): Function for internal use in formatting ticks on axes with nice-looking multiples of various symbolic constants, such as `\pi` or `e`. Should only be used via keyword argument - `tick_formatter` in :meth:`plot.show`. See documentation + ``tick_formatter`` in :meth:`plot.show`. See documentation for the matplotlib.ticker module for more details. EXAMPLES: diff --git a/src/sage/plot/primitive.py b/src/sage/plot/primitive.py index ef69f7f4344..3c4032085cc 100644 --- a/src/sage/plot/primitive.py +++ b/src/sage/plot/primitive.py @@ -146,7 +146,7 @@ def set_zorder(self, zorder): def set_options(self, new_options): """ - Change the options to `new_options`. + Change the options to ``new_options``. EXAMPLES:: diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index 1a75f415b64..202da0652ff 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -1630,7 +1630,7 @@ def solve_integer(self, n, *, algorithm='general', _flag=2): ALGORITHM: :pari:`qfbsolve` or :pari:`qfbcornacchia` - TODO:: Replace `_flag` with human-readable parameters c.f. :issue:`37119` + TODO:: Replace ``_flag`` with human-readable parameters c.f. :issue:`37119` EXAMPLES:: @@ -1736,7 +1736,7 @@ def solve_integer(self, n, *, algorithm='general', _flag=2): sage: Q(*xy) 0 - Test for different `_flag` values:: + Test for different ``_flag`` values:: sage: # needs sage.libs.pari sage: Q = BinaryQF([1, 0, 5]) diff --git a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py index 9eaf85376ca..44d18f376d2 100644 --- a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +++ b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py @@ -4032,7 +4032,7 @@ def diff_op_simple(A, B, AB_derivs, x, v, a, N): various natural numbers `e, k, l` that depend on `v` and `N`. Here `DD` is a specific linear differential operator that depends - on `a` and `v` , `A` and `B` are symbolic functions, and `AB_derivs` + on `a` and `v` , `A` and `B` are symbolic functions, and ``AB_derivs`` contains all the derivatives of `A` and `B` evaluated at `p` that are necessary for the computation. diff --git a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py index 2269085539d..9662572d5c0 100644 --- a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py @@ -127,8 +127,8 @@ def __init__(self, gen, category): """ Initialize ``self``. - Validity of the input is checked in `__classcall_private__`. The - `__init__` just saves attributes. + Validity of the input is checked in ``__classcall_private__``. The + ``__init__`` just saves attributes. INPUT: @@ -469,7 +469,7 @@ def _frobenius_charpoly_CSA(self): Compute the characteristic polynomial of the Frobenius from the reduced characteristic polynomial of the Ore polynomial - `phi_T`. This algorithm is particularly interesting when the + `\phi_T`. This algorithm is particularly interesting when the rank of the Drinfeld module is large compared to the degree of the extension `K/\mathbb F_q`. See [CL2023]_. """ diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index 073a3d98f5f..81b164a03f9 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -1349,7 +1349,7 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: Zp(5)(0).gamma() 1 + O(5^20) - Check the cached version of `dwork_expansion` from :issue:`24433`:: + Check the cached version of ``dwork_expansion`` from :issue:`24433`:: sage: p = next_prime(200) sage: F = Qp(p) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index feb0ef1b03b..43671f8f42e 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -10038,7 +10038,7 @@ cdef class Polynomial(CommutativePolynomial): sage: f.is_irreducible() True - If the base ring implements `_is_irreducible_univariate_polynomial`, + If the base ring implements ``_is_irreducible_univariate_polynomial``, then this method gets used instead of the generic algorithm which just factors the input:: @@ -10285,7 +10285,7 @@ cdef class Polynomial(CommutativePolynomial): sage: f.is_squarefree.cache False - If the base ring implements `_is_squarefree_univariate_polynomial`, + If the base ring implements ``_is_squarefree_univariate_polynomial``, then this method gets used instead of the generic algorithm in :meth:`_is_squarefree_generic`:: diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index 9851c477abf..7275a122c06 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -383,7 +383,7 @@ class of the category, and store the current class of the quotient 1 The test suite passes. However, we have to skip the test for its elements, - since `an_element` has been cached in the call above and its class does not + since ``an_element`` has been cached in the call above and its class does not match the new category's element class anymore:: sage: TestSuite(Q).run(skip=['_test_elements']) # needs sage.rings.number_field diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 0ab8074ec1e..67dbecbe99c 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -289,7 +289,7 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, sage: PolynomialRing(Zmod(1), 'x').category() Category of finite commutative rings - Check `is_finite` inherited from category (:issue:`24432`):: + Check ``is_finite`` inherited from category (:issue:`24432`):: sage: Zmod(1)['x'].is_finite() True diff --git a/src/sage/rings/polynomial/weil/weil_polynomials.pyx b/src/sage/rings/polynomial/weil/weil_polynomials.pyx index e2dd7bd04e7..4c5517ad6d1 100755 --- a/src/sage/rings/polynomial/weil/weil_polynomials.pyx +++ b/src/sage/rings/polynomial/weil/weil_polynomials.pyx @@ -83,7 +83,7 @@ cdef class dfs_manager: """ Data structure to manage depth-first search. - Such a structure is created and managed by an instance of `WeilPolynomials_iter`. + Such a structure is created and managed by an instance of ``WeilPolynomials_iter``. There is generally no need for a user to manipulate it directly. """ cdef int d @@ -156,8 +156,8 @@ cdef class dfs_manager: """ Count nodes. - This method should not be called directly. Instead, use the `node_count` method - of an instance of `WeilPolynomials` or `WeilPolynomials_iter`. + This method should not be called directly. Instead, use the ``node_count`` method + of an instance of ``WeilPolynomials`` or ``WeilPolynomials_iter``. TESTS:: @@ -179,7 +179,7 @@ cdef class dfs_manager: Advance the tree exhaustion. This method should not be called directly. Instead, use the iterator - `WeilPolynomials_iter` or the iterable `WeilPolynomials`. + ``WeilPolynomials_iter`` or the iterable ``WeilPolynomials``. TESTS:: diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index 28f272a18f0..f902434accc 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -218,7 +218,7 @@ cdef class Ring(ParentWithGens): sage: CDF._repr_option('element_is_atomic') # needs sage.rings.complex_double False - Check that categories correctly implement `is_finite` and `cardinality`:: + Check that categories correctly implement ``is_finite`` and ``cardinality``:: sage: QQ.is_finite() False diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index bcda9a9f510..248c118ac70 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -381,7 +381,7 @@ def __init__(self, names): TESTS: - We have to exclude `_test_graded_components`, because + We have to exclude ``_test_graded_components``, because :meth:`~sage.combinat.integer_vector.IntegerVectors.some_elements` yields degrees that are too large:: @@ -834,7 +834,7 @@ def __init__(self, names): TESTS: - We have to exclude `_test_graded_components`, because + We have to exclude ``_test_graded_components``, because :meth:`~sage.combinat.integer_vector.IntegerVectors.some_elements` yields degrees that are too large:: diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index 6fb9720b945..66033cbb02b 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -2000,7 +2000,7 @@ def jacobian_representatives(self, verbose=True): [{0: -5, 1: 3, 2: 2}, {0: -4, 1: 3, 2: 1}] Let `\tau` be the nonnegative generator of the kernel of the transpose of - the Laplacian, and let `tau_s` be it sink component, then the sandpile + the Laplacian, and let `\tau_s` be its sink component, then the sandpile group is isomorphic to the direct sum of the cyclic group of order `\tau_s` and the Jacobian group. In the example above, we have:: diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 4f694e0f252..9bed4936f7b 100755 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1364,7 +1364,7 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al From: Elliptic Curve defined by y^2 + x*y = x^3 + x + 2 over Finite Field of size 31 To: Elliptic Curve defined by y^2 + x*y = x^3 + 2*x + 26 over Finite Field of size 31 - Multiple ways to set the `velu_sqrt_bound`:: + Multiple ways to set the ``velu_sqrt_bound``:: sage: E = EllipticCurve_from_j(GF(97)(42)) sage: P = E.gens()[0]*4 @@ -1427,7 +1427,7 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al sage: phi.codomain()._order 170141183460469231746191640949390434666 - Check that ``'factored'`` recursively apply `velu_sqrt_bound`:: + Check that ``factored`` recursively apply ``velu_sqrt_bound``:: sage: from sage.schemes.elliptic_curves.hom_velusqrt import _velu_sqrt_bound sage: _velu_sqrt_bound.get() @@ -2141,7 +2141,7 @@ def isogenies_degree(self, n, *, _intermediate=False): """ def compute_key(phi): """ - Data used in ``hash(phi)`` excluding the expensive `.kernel_polynomial`. + Data used in ``hash(phi)`` excluding the expensive ``.kernel_polynomial``. """ return (phi.domain(), phi.codomain(), phi.degree(), phi.scaling_factor()) diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py index efc2a805bc0..c83c1a0997c 100755 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py @@ -185,7 +185,7 @@ def _have_established_geometrically_trivial(self): trivial. This is related to the warning at the top of the - `jacobian_endomorphism_utils.py` module. + ``jacobian_endomorphism_utils.py`` module. INPUT: @@ -214,7 +214,7 @@ def _have_established_geometrically_field(self): trivial. This is related to the warning at the top of the - `jacobian_endomorphism_utils.py` module. + ``jacobian_endomorphism_utils.py`` module. INPUT: diff --git a/src/sage/sets/disjoint_set.pyx b/src/sage/sets/disjoint_set.pyx index c2cce67037f..b991094924b 100644 --- a/src/sage/sets/disjoint_set.pyx +++ b/src/sage/sets/disjoint_set.pyx @@ -556,8 +556,8 @@ cdef class DisjointSet_of_integers(DisjointSet_class): Add a new element into a new set containing only the new element. According to :wikipedia:`Disjoint-set_data_structure#Making_new_sets` the - `make_set` operation adds a new element into a new set containing only - the new element. The new set is added at the end of `self`. + ``make_set`` operation adds a new element into a new set containing only + the new element. The new set is added at the end of ``self``. EXAMPLES:: sage: d = DisjointSet(5) @@ -874,8 +874,8 @@ cdef class DisjointSet_of_hashables(DisjointSet_class): Add a new element into a new set containing only the new element. According to :wikipedia:`Disjoint-set_data_structure#Making_new_sets` - the `make_set` operation adds a new element into a new set containing - only the new element. The new set is added at the end of `self`. + the ``make_set`` operation adds a new element into a new set containing + only the new element. The new set is added at the end of ``self``. INPUT: diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 14cae09d6f0..4860b4efabd 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -4661,7 +4661,7 @@ def coerce_binop(method): EXAMPLES: - Sparse polynomial rings uses `@coerce_binop` on `gcd`:: + Sparse polynomial rings uses ``@coerce_binop`` on ``gcd``:: sage: S. = PolynomialRing(ZZ, sparse=True) sage: f = x^2 @@ -4695,7 +4695,7 @@ def coerce_binop(method): sage: h.gcd(f, 'modular') 1 - We demonstrate a small class using `@coerce_binop` on a method:: + We demonstrate a small class using ``@coerce_binop`` on a method:: sage: from sage.structure.element import coerce_binop sage: class MyRational(Rational): diff --git a/src/sage/structure/global_options.py b/src/sage/structure/global_options.py index 0f3308cc80f..cbf08174532 100644 --- a/src/sage/structure/global_options.py +++ b/src/sage/structure/global_options.py @@ -1296,7 +1296,7 @@ def __setstate__(self, state): the :class:`GlobalOptions` class. The :meth:`__getstate__` method returns a dictionary with an - `options_class` key which identifies the "parent" class for the options. + ``options_class`` key which identifies the "parent" class for the options. This is then used to unpickle the options class. EXAMPLES:: diff --git a/src/sage/topology/simplicial_set.py b/src/sage/topology/simplicial_set.py index 974feac8510..7387dde2f94 100644 --- a/src/sage/topology/simplicial_set.py +++ b/src/sage/topology/simplicial_set.py @@ -455,7 +455,7 @@ def __eq__(self, other): def __ne__(self, other): """ - This returns the negation of `__eq__`. + This returns the negation of ``__eq__``. EXAMPLES:: diff --git a/src/sage/topology/simplicial_set_examples.py b/src/sage/topology/simplicial_set_examples.py index 367a00413b7..5f0a4f2d228 100644 --- a/src/sage/topology/simplicial_set_examples.py +++ b/src/sage/topology/simplicial_set_examples.py @@ -123,7 +123,7 @@ def __eq__(self, other) -> bool: def __ne__(self, other) -> bool: """ - Return the negation of `__eq__`. + Return the negation of ``__eq__``. EXAMPLES:: diff --git a/src/sage_setup/command/sage_build_ext_minimal.py b/src/sage_setup/command/sage_build_ext_minimal.py index 34ac31f8a87..25cab109ff8 100644 --- a/src/sage_setup/command/sage_build_ext_minimal.py +++ b/src/sage_setup/command/sage_build_ext_minimal.py @@ -20,7 +20,7 @@ def get_default_number_build_jobs() -> int: Get number of parallel build jobs used by default, i.e. unless explicitly set by the --parallel command line argument of setup.py. - First, the environment variable `SAGE_NUM_THREADS` is checked. + First, the environment variable ``SAGE_NUM_THREADS`` is checked. If that is unset, return the number of processors on the system, with a maximum of 10 (to prevent overloading the system if there a lot of CPUs). From ff9d834088f1ad43827054d1e685b72ac9b03dea Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Tue, 19 Nov 2024 08:27:10 +0700 Subject: [PATCH 115/210] Fix crash when specify invalid base for RR and RIF construction --- src/sage/rings/convert/mpfi.pyx | 29 +++++++++++++++++++++++++++++ src/sage/rings/real_mpfr.pyx | 29 +++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/sage/rings/convert/mpfi.pyx b/src/sage/rings/convert/mpfi.pyx index 803eed59146..106a94c5aca 100644 --- a/src/sage/rings/convert/mpfi.pyx +++ b/src/sage/rings/convert/mpfi.pyx @@ -72,6 +72,33 @@ cdef int mpfi_set_sage(mpfi_ptr re, mpfi_ptr im, x, field, int base) except -1: imaginary component is 0. - in all other cases: raise an exception. + + TESTS:: + + sage: RIF('0xabc') + Traceback (most recent call last): + ... + TypeError: unable to convert '0xabc' to real interval + sage: RIF("0x123.e1", base=0) # rel tol 1e-12 + 291.87890625000000? + sage: RIF("0x123.@1", base=0) # rel tol 1e-12 + 4656 + sage: RIF("1Xx", base=36) # rel tol 1e-12 + 2517 + sage: RIF("-1Xx@-10", base=62) # rel tol 1e-12 + -7.088054920481391?e-15 + sage: RIF("1", base=1) + Traceback (most recent call last): + ... + ValueError: base (=1) must be 0 or between 2 and 62 + sage: RIF("1", base=-1) + Traceback (most recent call last): + ... + ValueError: base (=-1) must be 0 or between 2 and 62 + sage: RIF("1", base=63) + Traceback (most recent call last): + ... + ValueError: base (=63) must be 0 or between 2 and 62 """ cdef RealIntervalFieldElement ri cdef ComplexIntervalFieldElement zi @@ -79,6 +106,8 @@ cdef int mpfi_set_sage(mpfi_ptr re, mpfi_ptr im, x, field, int base) except -1: cdef ComplexDoubleElement zd cdef bytes s + if base != 0 and (base < 2 or base > 62): + raise ValueError(f"base (={base}) must be 0 or between 2 and 62") if im is not NULL and isinstance(x, tuple): # For complex numbers, interpret tuples as real/imag parts if len(x) != 2: diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 7e1ab748b55..a870c6bf0c7 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -1437,6 +1437,33 @@ cdef class RealNumber(sage.structure.element.RingElement): sage: RealNumber('1_3.1e-32_45') 1.31000000000000e-3244 + + Test conversion from base different from `10`:: + + sage: RR('0xabc') + Traceback (most recent call last): + ... + TypeError: unable to convert '0xabc' to a real number + sage: RR("0x123.e1", base=0) # rel tol 1e-12 + 291.878906250000 + sage: RR("0x123.@1", base=0) # rel tol 1e-12 + 4656.00000000000 + sage: RR("1Xx", base=36) # rel tol 1e-12 + 2517.00000000000 + sage: RR("-1Xx@-10", base=62) # rel tol 1e-12 + -7.08805492048139e-15 + sage: RR("1", base=1) + Traceback (most recent call last): + ... + ValueError: base (=1) must be 0 or between 2 and 62 + sage: RR("1", base=-1) + Traceback (most recent call last): + ... + ValueError: base (=-1) must be 0 or between 2 and 62 + sage: RR("1", base=63) + Traceback (most recent call last): + ... + ValueError: base (=63) must be 0 or between 2 and 62 """ if x is not None: self._set(x, base) @@ -1485,6 +1512,8 @@ cdef class RealNumber(sage.structure.element.RingElement): # Real Numbers are supposed to be immutable. cdef RealField_class parent parent = self._parent + if base != 0 and (base < 2 or base > 62): + raise ValueError(f"base (={base}) must be 0 or between 2 and 62") if isinstance(x, RealNumber): if isinstance(x, RealLiteral): s = (x).literal From aa29916d7c61912cdc5597c202d638e7d0201e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 19 Nov 2024 10:28:03 +0100 Subject: [PATCH 116/210] adapted auxiliary functions --- .../q_integer_valued_polynomials.py | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index 954f74139ed..4709d0df744 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -39,7 +39,7 @@ from sage.structure.unique_representation import UniqueRepresentation -def q_int_x(n): +def q_int_x(n, q=None): """ Return the interpolating polynomial of `q`-integers. @@ -47,19 +47,30 @@ def q_int_x(n): - ``n`` -- a positive integer + - ``q`` -- optional variable + EXAMPLES:: sage: from sage.rings.polynomial.q_integer_valued_polynomials import q_int_x sage: q_int_x(3) q^2*x + q + 1 + + TESTS:: + + sage: from sage.rings.polynomial.q_integer_valued_polynomials import q_int_x + sage: q_int_x(3, 1) + x + 2 """ - ring_q = PolynomialRing(ZZ, 'q') - q = ring_q.gen() + if q is None: + ring_q = PolynomialRing(ZZ, 'q') + q = ring_q.gen() + else: + ring_q = q.parent() x = polygen(ring_q, 'x') - return q_int(n - 1) + q**(n - 1) * x + return q_int(n - 1, q) + q**(n - 1) * x -def q_binomial_x(m, n): +def q_binomial_x(m, n, q=None): r""" Return a `q`-analogue of ``binomial(m + x, n)``. @@ -70,6 +81,8 @@ def q_binomial_x(m, n): - ``m`` and ``n`` -- positive integers + - ``q`` -- optional variable + EXAMPLES:: sage: from sage.combinat.q_analogues import q_int @@ -83,11 +96,22 @@ def q_binomial_x(m, n): sage: q_binomial_x(2,0).parent() Univariate Polynomial Ring in x over Fraction Field of Univariate Polynomial Ring in q over Integer Ring + + TESTS:: + + sage: from sage.rings.polynomial.q_integer_valued_polynomials import q_binomial_x + sage: q_binomial_x(4,2,1) + 1/2*x^2 + 7/2*x + 6 """ - ring = PolynomialRing(PolynomialRing(ZZ, 'q').fraction_field(), 'x') + if q is None: + ring_q = PolynomialRing(ZZ, 'q') + else: + ring_q = q.parent() + ring = PolynomialRing(ring_q.fraction_field(), 'x') if n == 0: return ring.one() - return ring.prod(q_int_x(m + 2 - i) / q_int(i) for i in range(1, n + 1)) + return ring.prod(q_int_x(m + 2 - i, q) / q_int(i, q) + for i in range(1, n + 1)) class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): From de7f7c997526da4138137960f9e74b0027aced01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 19 Nov 2024 10:34:57 +0100 Subject: [PATCH 117/210] allow an optional q parameter --- .../q_integer_valued_polynomials.py | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index 4709d0df744..ba82f83b0f6 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -128,8 +128,16 @@ class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): - ``R`` -- commutative ring - The ring ``R`` is not containing the variable `q`. Instead the - Laurent polynomial ring over ``R`` is built and used. + - ``q`` -- optional variable + + There are two possible input formats: + + - If the argument ``q`` is not given, then the ring ``R`` is + taken as a base ring and the ring of Laurent polynomials in `q` + over ``R`` is built and used. + + - If the argument ``q`` is given, then it should belong to the ring ``R`` + and be invertible in this ring. EXAMPLES:: @@ -168,7 +176,7 @@ class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): S[0] - (1/2*q^-3)*S[2] + (1/2*q^-4+q^-3+q^-2+1/2*q^-1)*S[3] - (1/2*q^-4+1/2*q^-3+q^-2+1/2*q^-1+1/2)*S[4] """ - def __init__(self, R) -> None: + def __init__(self, R, q=None) -> None: r""" Initialize ``self``. @@ -178,6 +186,10 @@ def __init__(self, R) -> None: Quantum-Valued Polynomial Ring over Rational Field sage: TestSuite(F).run() + sage: F = QuantumValuedPolynomialRing(QQ, 1); F + Quantum-Valued Polynomial Ring over Integer Ring + sage: TestSuite(F).run() + TESTS:: sage: QuantumValuedPolynomialRing(24) @@ -188,9 +200,16 @@ def __init__(self, R) -> None: if R not in Rings().Commutative(): msg = "argument R must be a commutative ring" raise TypeError(msg) - laurent = LaurentPolynomialRing(R, 'q') - self._ground_ring = R - self._q = laurent.gen() + + if q is None: + laurent = LaurentPolynomialRing(R, 'q') + self._ground_ring = R + self._q = laurent.gen() + else: + laurent = q.parent() + self._ground_ring = laurent.base_ring() + self._q = q + cat = Algebras(laurent).Commutative().WithBasis() Parent.__init__(self, base=laurent, category=cat.WithRealizations()) From 3a217c40350dc4944a62fe12ac31099b96f26155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 19 Nov 2024 10:37:50 +0100 Subject: [PATCH 118/210] tweak the doc --- src/sage/rings/polynomial/q_integer_valued_polynomials.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index ba82f83b0f6..537114b6639 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -119,7 +119,11 @@ class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): The quantum-valued polynomial ring over a base ring. Quantum-valued polynomial rings are commutative and associative - algebras, with a basis indexed by integers. + algebras, with a basis indexed by nonnegative integers. + + The elements are polynomials in one variable `x` with coefficients in + the field of rational functions in `q`, such that the value at + every nonegative `q`-integer is a polynomial in `q`. This algebra is endowed with two bases, named ``B`` or ``Binomial`` and ``S`` or ``Shifted``. From 6640b49214d086a1fd6f1f9005374ee381a05dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 19 Nov 2024 11:45:11 +0100 Subject: [PATCH 119/210] enhanced coercion, also for free monoids --- src/sage/algebras/free_algebra.py | 15 +++++++++++++-- src/sage/monoids/free_monoid.py | 22 ++++++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 997bd73bbc8..d7fd38239fb 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -648,13 +648,24 @@ def _element_constructor_(self, x): 1.00000000000000*x^2 * 1.00000000000000*y^3 sage: F(f) 1.00000000000000*x^2*y^3 + + Check for extended coercion:: + + sage: A = algebras.Free(QQ,['x','y']) + sage: B = algebras.Free(QQ,['y']) + sage: y, = B.gens() + sage: A(4+y) + 4 + y """ if isinstance(x, FreeAlgebraElement): P = x.parent() if P is self: return x - if P is not self.base_ring(): - return self.element_class(self, x) + # from another FreeAlgebra: + if x not in self.base_ring(): + D = {self.monoid()(T): cf + for T, cf in x.monomial_coefficients().items()} + return self.element_class(self, D) elif hasattr(x, 'letterplace_polynomial'): P = x.parent() if self.has_coerce_map_from(P): # letterplace versus generic diff --git a/src/sage/monoids/free_monoid.py b/src/sage/monoids/free_monoid.py index e7a2a9f6532..32196e004dc 100644 --- a/src/sage/monoids/free_monoid.py +++ b/src/sage/monoids/free_monoid.py @@ -241,12 +241,26 @@ def _element_constructor_(self, x, check=True): sage: F(F(w), check=False) a^2*b^2*c*a*b*a*c + + sage: F = FreeMonoid(3, 'a,b,c') + sage: G = FreeMonoid(2, 'a,c') + sage: F(G(Word("ac"))) + a*c """ # There should really be some careful type checking here... - if isinstance(x, FreeMonoidElement) and x.parent() is self: - return x - if isinstance(x, FreeMonoidElement) and x.parent() == self: - return self.element_class(self, x._element_list, check) + if isinstance(x, FreeMonoidElement): + P = x.parent() + if P is self: + return x + elif P == self: + return self.element_class(self, x._element_list, check) + elif all(v in self.variable_names() + for v in P.variable_names()): + reindex = [next(j for j, w in enumerate(self.variable_names()) + if v == w) + for v in P.variable_names()] + elt = [(reindex[i], exp) for i, exp in x._element_list] + return self.element_class(self, elt, check) if isinstance(x, (int, Integer)) and x == 1: return self.element_class(self, x, check) if isinstance(x, FiniteWord_class): From 15511a79bf4859d63e9922893eb48b06e57fd373 Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Tue, 19 Nov 2024 12:01:53 -0500 Subject: [PATCH 120/210] Lambda is capitalized --- src/sage/combinat/crystals/spins.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/crystals/spins.pyx b/src/sage/combinat/crystals/spins.pyx index b45e0c24b17..28729fc93c0 100644 --- a/src/sage/combinat/crystals/spins.pyx +++ b/src/sage/combinat/crystals/spins.pyx @@ -65,7 +65,7 @@ def CrystalOfSpins(ct): Return the spin crystal of the given type `B`. This is a combinatorial model for the crystal with highest weight - `\lambda_n` (the `n`-th fundamental weight). It has + `\Lambda_n` (the `n`-th fundamental weight). It has `2^n` elements, here called Spins. See also :func:`~sage.combinat.crystals.letters.CrystalOfLetters`, :func:`~sage.combinat.crystals.spins.CrystalOfSpinsPlus`, @@ -108,7 +108,7 @@ def CrystalOfSpinsPlus(ct): r""" Return the plus spin crystal of the given type D. - This is the crystal with highest weight `\lambda_n` (the + This is the crystal with highest weight `\Lambda_n` (the `n`-th fundamental weight). INPUT: @@ -141,7 +141,7 @@ def CrystalOfSpinsMinus(ct): r""" Return the minus spin crystal of the given type D. - This is the crystal with highest weight `Lambda_{n-1}` + This is the crystal with highest weight `\Lambda_{n-1}` (the `(n-1)`-st fundamental weight). INPUT: From 837740309ffbc47f340534ed9fd163d2ee4c1495 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Mon, 18 Nov 2024 23:02:58 +0900 Subject: [PATCH 121/210] Do not upload logs artifact for the default job --- .github/workflows/ci-linux.yml | 1 + .github/workflows/docker.yml | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index ca4607e3cc3..1bf8862b4f4 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -50,6 +50,7 @@ jobs: tox_packages_factors: >- ["standard"] docker_push_repository: ghcr.io/${{ github.repository }}/ + logs_artifact: false # All platforms. This duplicates the default platform, but why not, # it makes it more robust regarding random timeouts. diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a7d5ecc8835..96427164eae 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -85,6 +85,9 @@ on: description: 'Elapsed time (seconds) at which to kill the build' default: 20000 type: number + logs_artifact: + default: true + type: boolean # # Publishing to GitHub Packages # @@ -260,11 +263,12 @@ jobs: cp -r .tox/$TOX_ENV/* "artifacts/$LOGS_ARTIFACT_NAME" rm -rf "artifacts/$LOGS_ARTIFACT_NAME"/{bin,lib,pyvenv.cfg} if: always() - - uses: actions/upload-artifact@v4 + - name: Upload logs artifact + uses: actions/upload-artifact@v4 with: path: artifacts name: ${{ env.LOGS_ARTIFACT_NAME }} - if: always() + if: always() && inputs.logs_artifact - name: Print out logs for immediate inspection # and markup the output with GitHub Actions logging commands run: | From 8f4a3789fcbf0f0ad221781789e43069fb76abc8 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Nov 2024 17:57:58 +0800 Subject: [PATCH 122/210] Fix a few minor typos --- .vscode/settings.json | 84 ++++++++++++++++++++++++++++- src/sage/manifolds/manifold.py | 2 +- src/sage/manifolds/vector_bundle.py | 2 +- 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index bf6ab3e7c3a..c38aafb376d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,10 +24,90 @@ ], "python.testing.unittestEnabled": false, "cSpell.words": [ - "furo", + "adic", + "arccos", + "arccosh", + "arcsin", + "arcsinh", + "arctan", + "arctanh", + "Bejger", + "bigcup", + "cachefunc", + "charpoly", + "classmethod", + "clopen", + "codim", + "codomain", + "coframe", + "coframes", "Conda", + "cputime", + "cysignals", + "Cython", + "d'Alembertian", + "dalembertian", + "disp", + "doctest", + "doctests", + "emptyset", + "figsize", + "Florentin", + "fontsize", + "forall", + "furo", + "Gourgoulhon", + "grayskull", + "groebner", + "homeomorphic", + "homset", + "homsets", + "hypersurfaces", + "infty", + "Jaffredo", + "Katsura", + "Koeppe", + "longmapsto", + "longrightarrow", + "mapsto", + "mathbb", + "mathrm", + "Michal", + "micjung", + "Minkowski", + "Möbius", + "mpfr", + "nabla", + "Nullspace", + "padics", + "pari", + "prandom", + "Pynac", + "rightarrow", "sagemath", - "Cython" + "scalarfield", + "SEEALSO", + "setminus", + "smithform", + "subchart", + "subcharts", + "subframe", + "subframes", + "subobjects", + "subring", + "superchart", + "supercharts", + "supersets", + "sympy", + "tensorfield", + "trigsimp", + "varphi", + "vbundle", + "vecmat", + "vectorfield", + "walltime", + "zmax", + "zmin" ], "editor.formatOnType": true, "esbonio.sphinx.confDir": "" diff --git a/src/sage/manifolds/manifold.py b/src/sage/manifolds/manifold.py index c27cd0b6434..fbb454235bc 100644 --- a/src/sage/manifolds/manifold.py +++ b/src/sage/manifolds/manifold.py @@ -1692,7 +1692,7 @@ def orientation(self): r""" Get the preferred orientation of ``self`` if available. - An *orientation* of an `n`-dimensional topologial manifold is an + An *orientation* of an `n`-dimensional topological manifold is an atlas of charts whose transition maps are orientation preserving. A homeomorphism `f \colon U \to V` for open subsets `U, V \subset \RR^n` is called *orientation preserving* if for each `x \in U` the diff --git a/src/sage/manifolds/vector_bundle.py b/src/sage/manifolds/vector_bundle.py index ad830d68469..0acfa14e70a 100644 --- a/src/sage/manifolds/vector_bundle.py +++ b/src/sage/manifolds/vector_bundle.py @@ -796,7 +796,7 @@ def local_frame(self, *args, **kwargs): resu._init_from_family(sections) except ArithmeticError as err: linked = str(err) in ["non-invertible matrix", - "input matrix must be nonsingular"] + "input matrix must be non-singular"] if linked: raise ValueError("the provided sections are not linearly " "independent") From c227b70e28f042d94b91de666e681aeea9cda9a6 Mon Sep 17 00:00:00 2001 From: maple3142 Date: Wed, 20 Nov 2024 22:29:25 +0800 Subject: [PATCH 123/210] Matrix_mod2_dense solve_right test signal --- src/sage/matrix/matrix_mod2_dense.pyx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/sage/matrix/matrix_mod2_dense.pyx b/src/sage/matrix/matrix_mod2_dense.pyx index 055359e6fd0..55f39acf67f 100644 --- a/src/sage/matrix/matrix_mod2_dense.pyx +++ b/src/sage/matrix/matrix_mod2_dense.pyx @@ -1967,6 +1967,18 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse True sage: matrix(GF(2), 2, 2).solve_right(matrix(GF(2), 2, 0)) == matrix(GF(2), 2, 0) True + + Check that it can be interrupted:: + + sage: set_random_seed(12345) + sage: n, m = 20000, 19968 + sage: A = random_matrix(GF(2), n, m) + sage: x = random_vector(GF(2), m) + sage: B = A*x + sage: alarm(0.5); sol = A.solve_right(B) + Traceback (most recent call last): + ... + AlarmInterrupt """ cdef mzd_t *B_entries = (B)._entries From 4f3c259d07cace3ada11ba827e3212fe15979aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 20 Nov 2024 17:39:11 +0100 Subject: [PATCH 124/210] minor details --- src/sage/algebras/free_algebra.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index d7fd38239fb..0c1699ca5dd 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -515,8 +515,8 @@ def construction(self): EXAMPLES:: - sage: algebras.Free(QQ,4,'x,y,z,t').construction() - (Associative[x,y,z,t], Rational Field) + sage: F, R = algebras.Free(QQ,4,'x,y,z,t').construction(); F + Associative[x,y,z,t] """ return AssociativeFunctor(self.variable_names(), self._degrees), self.base_ring() @@ -703,21 +703,23 @@ def exp_to_monomial(T): return self.element_class(self, {}) return self.element_class(self, {self.one_basis(): x}) - def _coerce_map_from_(self, R): + def _coerce_map_from_(self, R) -> bool: """ Return ``True`` if there is a coercion from ``R`` into ``self`` and - ``False`` otherwise. The things that coerce into ``self`` are: + ``False`` otherwise. + + The things that coerce into ``self`` are: - This free algebra. - - Anything with a coercion into ``self.monoid()``. + - The PBW basis of ``self``. - - Free algebras in the same variables over a base with a coercion - map into ``self.base_ring()``. + - Free algebras in some subset of variables + over a base with a coercion map into ``self.base_ring()``. - The underlying monoid. - - The PBW basis of ``self``. + - Anything with a coercion into ``self.monoid()``. - Anything with a coercion into ``self.base_ring()``. @@ -833,7 +835,7 @@ def algebra_generators(self): return Family(self.variable_names(), lambda i: ret[i]) @cached_method - def gens(self): + def gens(self) -> tuple: """ Return the generators of ``self``. @@ -1624,12 +1626,12 @@ def merge(self, other): sage: S = algebras.Free(QQ, 2, 'z,t') sage: z,t = S.gens() sage: x + t - B[t[]] + B[x[]] + t + x sage: parent(x + t) - Free Algebra on 4 generators ['z', 't', 'x', 'y'] over Rational Field + Free Algebra on 4 generators (z, t, x, y) over Rational Field """ if isinstance(other, AssociativeFunctor): - if self.vars == other.vars: + if self.vars == other.vars and self.degs == other.degs: return self ret = list(self.vars) cur_vars = set(ret) @@ -1646,4 +1648,5 @@ def _repr_(self) -> str: sage: algebras.Free(QQ,4,'x,y,z,t').construction()[0] Associative[x,y,z,t] """ + # should we add the degree there ? return "Associative[%s]" % ','.join(self.vars) From c3c3d9520cdaa603b91e15f8a20fcf4e7856f484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 21 Nov 2024 11:00:21 +0100 Subject: [PATCH 125/210] using classcall_private --- .../q_integer_valued_polynomials.py | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index 537114b6639..10ad71e27f8 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -1,7 +1,7 @@ r""" Quantum-valued polynomial rings -This provide a `q`-analogue of the :class:`~sage.rings.polynomials.integer_valued_polynomials.IntegerValuedPolynomialRing`. +This provides a `q`-analogue of the :class:`~sage.rings.polynomials.integer_valued_polynomials.IntegerValuedPolynomialRing`. AUTHORS: @@ -180,7 +180,23 @@ class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): S[0] - (1/2*q^-3)*S[2] + (1/2*q^-4+q^-3+q^-2+1/2*q^-1)*S[3] - (1/2*q^-4+1/2*q^-3+q^-2+1/2*q^-1+1/2)*S[4] """ - def __init__(self, R, q=None) -> None: + @staticmethod + def __classcall_private__(cls, R, q=None) -> None: + """ + Normalize the input. + """ + if R not in Rings().Commutative(): + msg = "argument R must be a commutative ring" + raise TypeError(msg) + + if q is None: + laurent = LaurentPolynomialRing(R, 'q') + q = laurent.gen() + else: + laurent = q.parent() + return super().__classcall__(cls, laurent, q) + + def __init__(self, R, q) -> None: r""" Initialize ``self``. @@ -201,21 +217,10 @@ def __init__(self, R, q=None) -> None: ... TypeError: argument R must be a commutative ring """ - if R not in Rings().Commutative(): - msg = "argument R must be a commutative ring" - raise TypeError(msg) - - if q is None: - laurent = LaurentPolynomialRing(R, 'q') - self._ground_ring = R - self._q = laurent.gen() - else: - laurent = q.parent() - self._ground_ring = laurent.base_ring() - self._q = q - - cat = Algebras(laurent).Commutative().WithBasis() - Parent.__init__(self, base=laurent, category=cat.WithRealizations()) + self._ground_ring = R.base_ring() + self._q = q + cat = Algebras(R).Commutative().WithBasis() + Parent.__init__(self, base=R, category=cat.WithRealizations()) _shorthands = ["B", "S"] From a42e8a5e5c337667095e4ff0a7b1ded011b9716b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 22 Nov 2024 08:26:17 +0100 Subject: [PATCH 126/210] add doctest for uniqueness Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/q_integer_valued_polynomials.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sage/rings/polynomial/q_integer_valued_polynomials.py b/src/sage/rings/polynomial/q_integer_valued_polynomials.py index 10ad71e27f8..fdcca6d5fff 100644 --- a/src/sage/rings/polynomial/q_integer_valued_polynomials.py +++ b/src/sage/rings/polynomial/q_integer_valued_polynomials.py @@ -184,6 +184,14 @@ class QuantumValuedPolynomialRing(UniqueRepresentation, Parent): def __classcall_private__(cls, R, q=None) -> None: """ Normalize the input. + + EXAMPLES:: + + sage: q = LaurentPolynomialRing(QQ, 'q').gen() + sage: F1 = QuantumValuedPolynomialRing(QQ) + sage: F2 = QuantumValuedPolynomialRing(q.parent(), q) + sage: F1 is F2 + True """ if R not in Rings().Commutative(): msg = "argument R must be a commutative ring" From 250a0b309baffaad73f3200e37a59bc4bb4674ba Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 22 Nov 2024 14:14:47 +0100 Subject: [PATCH 127/210] simplify isogeny-enumeration code following #35949 --- .../schemes/elliptic_curves/ell_finite_field.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_finite_field.py b/src/sage/schemes/elliptic_curves/ell_finite_field.py index 905cc63e149..a97c5c26138 100755 --- a/src/sage/schemes/elliptic_curves/ell_finite_field.py +++ b/src/sage/schemes/elliptic_curves/ell_finite_field.py @@ -2810,18 +2810,8 @@ def special_supersingular_curve(F, q=None, *, endomorphism=False): try: endo = iso * E.isogeny(None, iso.domain(), degree=q) except (NotImplementedError, ValueError): #FIXME catching ValueError here is a workaround for #38481 - #FIXME this code could be simplified/optimized after #37388 and/or #35949 - def _isogs(E, d): - if d.is_one(): - yield E.identity_morphism() - return - l = d.prime_factors()[-1] - for phi in E.isogenies_prime_degree(l): - for psi in _isogs(phi.codomain(), d//l): - yield psi * phi - endos = (iso*phi for phi in _isogs(E, q) for iso in phi.codomain().isomorphisms(E)) -# endos = (iso*phi for phi in E.isogenies_degree(q) -# for iso in phi.codomain().isomorphisms(E)) + endos = (iso*phi for phi in E.isogenies_degree(q) + for iso in phi.codomain().isomorphisms(E)) endo = next(endo for endo in endos if endo.trace().is_zero()) endo._degree = ZZ(q) From ff0be520b699b4edc4810da96e39ea4cd599fbdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 22 Nov 2024 14:25:16 +0100 Subject: [PATCH 128/210] one more method in FHM-triangles --- src/sage/combinat/triangles_FHM.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/sage/combinat/triangles_FHM.py b/src/sage/combinat/triangles_FHM.py index c8248bdc5f2..cfd1d5f0f3c 100644 --- a/src/sage/combinat/triangles_FHM.py +++ b/src/sage/combinat/triangles_FHM.py @@ -667,6 +667,25 @@ def m(self): polym = step.numerator() return M_triangle(polym, variables=(x, y)) + def parabolic(self): + """ + Return a parabolic version of the F-triangle. + + This is obtained by replacing the variable `y` by `y-1`. + + EXAMPLES:: + + sage: from sage.combinat.triangles_FHM import H_triangle + sage: x, y = polygens(ZZ,'x,y') + sage: H_triangle(1+x*y).f() + F: x + y + 1 + sage: _.parabolic() + F: x + y + """ + x, y = self._vars + polyf = self._poly(y=y - 1) + return F_triangle(polyf, variables=(x, y)) + def vector(self): """ Return the f-vector as a polynomial in one variable. From 03b278e37c1a4837d583e0bedc7d36fcb3eda151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 22 Nov 2024 14:51:25 +0100 Subject: [PATCH 129/210] hot-fix for ruff linter --- src/tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tox.ini b/src/tox.ini index b6548bc55a4..ba85a363c66 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -314,7 +314,7 @@ passenv = RUFF_OUTPUT_FORMAT # 1 F402 [ ] Import `factor` from line 259 shadowed by loop variable # 1 PLC0208 [*] Use a sequence type instead of a `set` when iterating over values # -commands = ruff check --ignore PLR2004,I001,F401,E741,F821,PLR0912,PLR0913,E402,PLR0915,PLW2901,PLR5501,PLR0911,E731,F405,PLR1714,PLR1736,F403,PLR0402,PLW0603,F841,PLW0602,PLW0642,PLR1711,E714,SIM101,PLR1704,PLW3301,PLW1510,E721,PLW0211,PLW0120,F811,PLC2401,PLC0414,E743,PLE0101,PLR0124,PLW0127,F541,PLW1508,PLC3002,E742,PLE0302,PLW0129,F402,PLC0208 {posargs:{toxinidir}/sage/} +commands = ruff check --ignore PLR2004,I001,F401,E741,F821,PLR0912,PLR0913,E402,PLR0915,PLW2901,PLR5501,PLR0911,E731,F405,PLR1714,PLR1736,F403,PLR0402,PLW0603,F841,PLW0602,PLW0642,PLR1711,SIM101,PLR1704,PLW3301,PLW1510,E721,PLW0211,PLW0120,F811,PLC2401,PLC0414,E743,PLE0101,PLR0124,PLW0127,F541,PLW1508,PLC3002,E742,PLE0302,PLW0129,F402,PLC0208,PLC0206 {posargs:{toxinidir}/sage/} [flake8] rst-roles = From 88dd72cf6417e5541bcc4529c76156716836a93a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 22 Nov 2024 21:34:33 +0100 Subject: [PATCH 130/210] fix all ruff warnings SIM101 --- src/sage/combinat/fully_packed_loop.py | 4 +-- src/sage/combinat/sf/sfa.py | 2 +- src/sage/combinat/words/words.py | 8 +++--- .../arithmetic_dynamics/generic_ds.py | 3 ++- .../arithmetic_dynamics/projective_ds.py | 26 ++++++++++++------- src/sage/geometry/voronoi_diagram.py | 2 +- .../characteristic_cohomology_class.py | 2 +- ...otics_multivariate_generating_functions.py | 6 ++--- src/sage/rings/number_field/number_field.py | 4 +-- src/sage/rings/padics/factory.py | 5 ++-- src/sage/rings/polynomial/flatten.py | 6 +++-- .../polynomial/multi_polynomial_sequence.py | 2 +- src/sage/rings/polynomial/polynomial_ring.py | 2 +- .../polynomial_singular_interface.py | 4 +-- src/sage/structure/sequence.py | 2 +- 15 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/sage/combinat/fully_packed_loop.py b/src/sage/combinat/fully_packed_loop.py index 74a14fa1ecd..81e3a30508f 100644 --- a/src/sage/combinat/fully_packed_loop.py +++ b/src/sage/combinat/fully_packed_loop.py @@ -1361,8 +1361,8 @@ def _element_constructor_(self, generator): """ if isinstance(generator, AlternatingSignMatrix): SVM = generator.to_six_vertex_model() - elif isinstance(generator, SquareIceModel.Element) or \ - isinstance(generator, SixVertexConfiguration): + elif isinstance(generator, (SquareIceModel.Element, + SixVertexConfiguration)): SVM = generator else: # Not ASM nor SVM try: diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 8d911087b24..92a068e4c8c 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -6747,7 +6747,7 @@ def _nonnegative_coefficients(x): sage: _nonnegative_coefficients(x^2-4) False """ - if isinstance(x, Polynomial) or isinstance(x, MPolynomial): + if isinstance(x, (Polynomial, MPolynomial)): return all(c >= 0 for c in x.coefficients(sparse=False)) else: return x >= 0 diff --git a/src/sage/combinat/words/words.py b/src/sage/combinat/words/words.py index e940582f83c..403b28f2049 100644 --- a/src/sage/combinat/words/words.py +++ b/src/sage/combinat/words/words.py @@ -90,10 +90,10 @@ def Words(alphabet=None, length=None, finite=True, infinite=True): sage: Words('natural numbers') Finite and infinite words over Non negative integers """ - if isinstance(alphabet, FiniteWords) or \ - isinstance(alphabet, InfiniteWords) or \ - isinstance(alphabet, FiniteOrInfiniteWords) or \ - isinstance(alphabet, Words_n): + if isinstance(alphabet, (FiniteWords, + InfiniteWords, + FiniteOrInfiniteWords, + Words_n)): return alphabet if length is None: diff --git a/src/sage/dynamics/arithmetic_dynamics/generic_ds.py b/src/sage/dynamics/arithmetic_dynamics/generic_ds.py index f16d99cbb11..67ca0c97e8d 100644 --- a/src/sage/dynamics/arithmetic_dynamics/generic_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/generic_ds.py @@ -165,7 +165,8 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): if isinstance(morphism_or_polys, SchemeMorphism_polynomial): domain = morphism_or_polys.domain() if domain is not None: - if isinstance(domain, AffineSpace_generic) or isinstance(domain, AlgebraicScheme_subscheme_affine): + if isinstance(domain, (AffineSpace_generic, + AlgebraicScheme_subscheme_affine)): from sage.dynamics.arithmetic_dynamics.affine_ds import DynamicalSystem_affine return DynamicalSystem_affine(morphism_or_polys, domain) if isinstance(domain, Berkovich_Cp): diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 2fab95104f1..76e40d85cbd 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -385,7 +385,7 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): polys = list(morphism_or_polys) if len(polys) == 1: raise ValueError("list/tuple must have at least 2 polynomials") - test = lambda x: isinstance(x, PolynomialRing_general) or isinstance(x, MPolynomialRing_base) + test = lambda x: isinstance(x, (PolynomialRing_general, MPolynomialRing_base)) if not all(test(poly.parent()) for poly in polys): try: polys = [poly.lift() for poly in polys] @@ -450,7 +450,8 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): msg = 'polys (={}) must be of the same degree' raise ValueError(msg.format(polys)) - if not isinstance(domain, ProjectiveSpace_ring) and not isinstance(domain, AlgebraicScheme_subscheme_projective): + if not isinstance(domain, (ProjectiveSpace_ring, + AlgebraicScheme_subscheme_projective)): raise ValueError('"domain" must be a projective scheme') if R not in Fields(): return typecall(cls, polys, domain) @@ -3530,7 +3531,9 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): if hyperplane_found: break else: - if isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base) or isinstance(R, FractionField_generic): + if isinstance(R, (PolynomialRing_general, + MPolynomialRing_base, + FractionField_generic)): # for polynomial rings, we can get an infinite family of hyperplanes # by increasing the degree var = R.gen() @@ -4592,7 +4595,8 @@ def preperiodic_points(self, m, n, **kwds): for k in ZZ(n).divisors(): if ZZ(n/k).is_prime(): Sn.append(k) - if (isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base)): + if isinstance(R, (PolynomialRing_general, + MPolynomialRing_base)): phi = FlatteningMorphism(CR) flatCR = phi.codomain() Ik = flatCR.ideal(1) @@ -4946,9 +4950,10 @@ def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='vari elif minimal: Sn = [] for k in ZZ(n).divisors(): - if ZZ(n/k).is_prime(): + if ZZ(n//k).is_prime(): Sn.append(k) - if (isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base)): + if isinstance(R, (PolynomialRing_general, + MPolynomialRing_base)): phi = FlatteningMorphism(CR) flatCR = phi.codomain() Ik = flatCR.ideal(1) @@ -5239,7 +5244,8 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur # if we are already using an algebraic closure, we move the # map into a finite extension and set use_algebraic_closure to True # in order to get a scheme defined over a finite extension - if isinstance(K, sage.rings.abc.AlgebraicField) or isinstance(K, AlgebraicClosureFiniteField_generic): + if isinstance(K, (sage.rings.abc.AlgebraicField, + AlgebraicClosureFiniteField_generic)): f = self.reduce_base_field() K = f.base_ring() use_algebraic_closure = True @@ -5780,7 +5786,8 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', else: F = base_ring if isinstance(base_ring, FractionField_generic): - if isinstance(base_ring.ring(), MPolynomialRing_base) or isinstance(base_ring.ring(), PolynomialRing_general): + if isinstance(base_ring.ring(), (MPolynomialRing_base, + PolynomialRing_general)): f.normalize_coordinates() f_ring = f.change_ring(base_ring.ring()) X = f_ring.periodic_points(n, minimal=False, formal=formal, return_scheme=True) @@ -5883,7 +5890,8 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', base_ring = dom.base_ring() if isinstance(base_ring, FractionField_generic): base_ring = base_ring.ring() - if (isinstance(base_ring, PolynomialRing_general) or isinstance(base_ring, MPolynomialRing_base)): + if isinstance(base_ring, (PolynomialRing_general, + MPolynomialRing_base)): base_ring = base_ring.base_ring() elif base_ring in FunctionFields(): base_ring = base_ring.constant_base_field() diff --git a/src/sage/geometry/voronoi_diagram.py b/src/sage/geometry/voronoi_diagram.py index 1402e0b1e77..9929ae7ca60 100644 --- a/src/sage/geometry/voronoi_diagram.py +++ b/src/sage/geometry/voronoi_diagram.py @@ -290,7 +290,7 @@ def plot(self, cell_colors=None, **kwds): cell_colors = rainbow(self._n) shuffle(cell_colors) else: - if not (isinstance(cell_colors, list) or (isinstance(cell_colors, dict))): + if not isinstance(cell_colors, (list, dict)): raise AssertionError("'cell_colors' must be a list or a dictionary") for i, p in enumerate(self._P): col = cell_colors[i] diff --git a/src/sage/manifolds/differentiable/characteristic_cohomology_class.py b/src/sage/manifolds/differentiable/characteristic_cohomology_class.py index 51f32ffb4b8..ebb8b2f75a4 100644 --- a/src/sage/manifolds/differentiable/characteristic_cohomology_class.py +++ b/src/sage/manifolds/differentiable/characteristic_cohomology_class.py @@ -795,7 +795,7 @@ def _element_constructor_(self, x, **kwargs): Characteristic cohomology class pontr(TM) of the Tangent bundle TM over the 8-dimensional differentiable manifold M """ - if isinstance(x, (str, Expression)) or isinstance(x, Polynomial): + if isinstance(x, (str, Expression, Polynomial)): return self._build_element(x, **kwargs) R = self.base_ring() diff --git a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py index 9eaf85376ca..45548f32fa3 100644 --- a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +++ b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py @@ -505,7 +505,7 @@ def dimension(self): from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base R = self.denominator_ring - if isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base): + if isinstance(R, (PolynomialRing_general, MPolynomialRing_base)): return R.ngens() raise NotImplementedError('only polynomial rings are supported as base') @@ -3167,7 +3167,7 @@ def _element_constructor_(self, *args, **kwargs): from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base - if isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base): + if isinstance(R, (PolynomialRing_general, MPolynomialRing_base)): if not R(q).is_unit(): # Factor denominator try: @@ -3235,7 +3235,7 @@ def _coerce_map_from_(self, P): B = P.base() from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base - if isinstance(B, PolynomialRing_general) or isinstance(B, MPolynomialRing_base): + if isinstance(B, (PolynomialRing_general, MPolynomialRing_base)): if self.base().has_coerce_map_from(B): return True diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 7128d40032e..2559771ae62 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -1762,8 +1762,8 @@ def _element_constructor_(self, x, check=True): return self._convert_from_str(s.replace('!', '')) elif isinstance(x, str): return self._convert_from_str(x) - elif (isinstance(x, (tuple, list)) or - isinstance(x, sage.modules.free_module_element.FreeModuleElement)): + elif isinstance(x, (tuple, list, + sage.modules.free_module_element.FreeModuleElement)): if len(x) != self.relative_degree(): raise ValueError("Length must be equal to the degree of this number field") base = self.base_ring() diff --git a/src/sage/rings/padics/factory.py b/src/sage/rings/padics/factory.py index cee585d48a1..44093d2cf67 100644 --- a/src/sage/rings/padics/factory.py +++ b/src/sage/rings/padics/factory.py @@ -2570,7 +2570,7 @@ def Zq(q, prec=None, type='capped-rel', modulus=None, names=None, True """ if check: - if isinstance(q, Factorization) or isinstance(q, (list, tuple)): + if isinstance(q, (Factorization, list, tuple)): if not isinstance(q, Factorization) and len(q) == 2: F = [(Integer(q[0]), Integer(q[1]))] else: @@ -2592,7 +2592,8 @@ def Zq(q, prec=None, type='capped-rel', modulus=None, names=None, if isinstance(names, (list, tuple)): names = names[0] from sage.structure.element import Expression - if not (modulus is None or isinstance(modulus, Polynomial) or isinstance(modulus, Expression)): + if not (modulus is None or isinstance(modulus, (Polynomial, + Expression))): raise TypeError("modulus must be a polynomial") if names is not None and not isinstance(names, str): names = str(names) diff --git a/src/sage/rings/polynomial/flatten.py b/src/sage/rings/polynomial/flatten.py index 6354bbcd382..32d07423e91 100644 --- a/src/sage/rings/polynomial/flatten.py +++ b/src/sage/rings/polynomial/flatten.py @@ -167,7 +167,7 @@ def __init__(self, domain): variables = [] intermediate_rings = [] - while isinstance(ring, PolynomialRing_general) or isinstance(ring, MPolynomialRing_base): + while isinstance(ring, (PolynomialRing_general, MPolynomialRing_base)): intermediate_rings.append(ring) v = ring.variable_names() variables.extend(reversed(v)) @@ -538,7 +538,9 @@ def __init__(self, domain, D): # Construct unflattened codomain R new_vars = [] R = domain - while isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base) or isinstance(R, FractionField_generic): + while isinstance(R, (PolynomialRing_general, + MPolynomialRing_base, + FractionField_generic)): if isinstance(R, FractionField_generic): # We've hit base_ring, so set _sub_specialization and exit the loop field_over = R.base() diff --git a/src/sage/rings/polynomial/multi_polynomial_sequence.py b/src/sage/rings/polynomial/multi_polynomial_sequence.py index db276a75c25..4a596cea922 100644 --- a/src/sage/rings/polynomial/multi_polynomial_sequence.py +++ b/src/sage/rings/polynomial/multi_polynomial_sequence.py @@ -301,7 +301,7 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): except ImportError: BooleanMonomialMonoid = () - is_ring = lambda r: isinstance(r, MPolynomialRing_base) or isinstance(r, BooleanMonomialMonoid) or (isinstance(r, QuotientRing_nc) and isinstance(r.cover_ring(), MPolynomialRing_base)) + is_ring = lambda r: isinstance(r, (MPolynomialRing_base, BooleanMonomialMonoid)) or (isinstance(r, QuotientRing_nc) and isinstance(r.cover_ring(), MPolynomialRing_base)) if is_ring(arg1): ring, gens = arg1, arg2 diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 0ab8074ec1e..8b078fed68c 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -642,7 +642,7 @@ def flattening_morphism(self): """ from .multi_polynomial_ring import MPolynomialRing_base base = self.base_ring() - if isinstance(base, PolynomialRing_general) or isinstance(base, MPolynomialRing_base): + if isinstance(base, (PolynomialRing_general, MPolynomialRing_base)): from .flatten import FlatteningMorphism return FlatteningMorphism(self) else: diff --git a/src/sage/rings/polynomial/polynomial_singular_interface.py b/src/sage/rings/polynomial/polynomial_singular_interface.py index 1bdca3af614..60d2dd74b52 100644 --- a/src/sage/rings/polynomial/polynomial_singular_interface.py +++ b/src/sage/rings/polynomial/polynomial_singular_interface.py @@ -430,8 +430,8 @@ def can_convert_to_singular(R): base_ring = R.base_ring() if (base_ring is ZZ - or isinstance(base_ring, RationalField) - or isinstance(base_ring, (sage.rings.abc.IntegerModRing, + or isinstance(base_ring, (RationalField, + sage.rings.abc.IntegerModRing, sage.rings.abc.RealField, sage.rings.abc.ComplexField, sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField))): return True diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index cc9fcedadfe..6a18b3bf610 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -257,7 +257,7 @@ def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=Non except ImportError: pass else: - if isinstance(universe, MPolynomialRing_base) or isinstance(universe, BooleanMonomialMonoid) or (isinstance(universe, QuotientRing_nc) and isinstance(universe.cover_ring(), MPolynomialRing_base)): + if isinstance(universe, MPolynomialRing_base, BooleanMonomialMonoid) or (isinstance(universe, QuotientRing_nc) and isinstance(universe.cover_ring(), MPolynomialRing_base)): return PolynomialSequence(x, universe, immutable=immutable, cr=cr, cr_str=cr_str) return Sequence_generic(x, universe, check, immutable, cr, cr_str, use_sage_types) From cde4fa1f89b052c7ce76830e6a4c92a74ac0e648 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 22 Nov 2024 18:02:52 -0500 Subject: [PATCH 131/210] src/sage/misc/table.py: fix the right border on table cells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It looks like during the conversion to unicode, the right borders of table cells were overlooked. Instead of a nice unicode character, they still have an ASCII pipe. For example, sage: table([1],frame=True) ┌───┐ │ 1 | └───┘ This commit changes it to a unicode thingy, just like the left borders, sage: table([1],frame=True) ┌───┐ │ 1 │ └───┘ and updates all of the tests in sage.misc.table. --- src/sage/misc/table.py | 74 +++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/sage/misc/table.py b/src/sage/misc/table.py index 086e8fd49ed..61ead0537b1 100644 --- a/src/sage/misc/table.py +++ b/src/sage/misc/table.py @@ -69,11 +69,11 @@ class table(SageObject): \end{tabular} sage: table(rows=rows, frame=True) ┌─────┬───┬────┐ - │ a | b | c | + │ a │ b │ c │ ├─────┼───┼────┤ - │ 100 | 2 | 3 | + │ 100 │ 2 │ 3 │ ├─────┼───┼────┤ - │ 4 | 5 | 60 | + │ 4 │ 5 │ 60 │ └─────┴───┴────┘ sage: latex(table(rows=rows, frame=True)) \begin{tabular}{|l|l|l|} \hline @@ -83,11 +83,11 @@ class table(SageObject): \end{tabular} sage: table(rows, header_column=True, frame=True) ┌─────╥───┬────┐ - │ a ║ b | c | + │ a ║ b │ c │ ├─────╫───┼────┤ - │ 100 ║ 2 | 3 | + │ 100 ║ 2 │ 3 │ ├─────╫───┼────┤ - │ 4 ║ 5 | 60 | + │ 4 ║ 5 │ 60 │ └─────╨───┴────┘ sage: latex(table(rows, header_row=True, frame=True)) \begin{tabular}{|l|l|l|} \hline @@ -109,15 +109,15 @@ class table(SageObject): sage: table([(x,n(sin(x), digits=2)) for x in [0..3]], # needs sage.symbolic ....: header_row=["$x$", r"$\sin(x)$"], frame=True) ┌─────┬───────────┐ - │ $x$ | $\sin(x)$ | + │ $x$ │ $\sin(x)$ │ ╞═════╪═══════════╡ - │ 0 | 0.00 | + │ 0 │ 0.00 │ ├─────┼───────────┤ - │ 1 | 0.84 | + │ 1 │ 0.84 │ ├─────┼───────────┤ - │ 2 | 0.91 | + │ 2 │ 0.91 │ ├─────┼───────────┤ - │ 3 | 0.14 | + │ 3 │ 0.14 │ └─────┴───────────┘ You can create the transpose of this table in several ways, for @@ -127,9 +127,9 @@ class table(SageObject): ....: [n(sin(x), digits=2) for x in [0..3]]], ....: header_column=['$x$', r'$\sin(x)$'], frame=True) ┌───────────╥──────┬──────┬──────┬──────┐ - │ $x$ ║ 0 | 1 | 2 | 3 | + │ $x$ ║ 0 │ 1 │ 2 │ 3 │ ├───────────╫──────┼──────┼──────┼──────┤ - │ $\sin(x)$ ║ 0.00 | 0.84 | 0.91 | 0.14 | + │ $\sin(x)$ ║ 0.00 │ 0.84 │ 0.91 │ 0.14 │ └───────────╨──────┴──────┴──────┴──────┘ or by passing the original data as the ``columns`` of the table @@ -138,9 +138,9 @@ class table(SageObject): sage: table(columns=[(x, n(sin(x), digits=2)) for x in [0..3]], # needs sage.symbolic ....: header_column=['$x$', r'$\sin(x)$'], frame=True) ┌───────────╥──────┬──────┬──────┬──────┐ - │ $x$ ║ 0 | 1 | 2 | 3 | + │ $x$ ║ 0 │ 1 │ 2 │ 3 │ ├───────────╫──────┼──────┼──────┼──────┤ - │ $\sin(x)$ ║ 0.00 | 0.84 | 0.91 | 0.14 | + │ $\sin(x)$ ║ 0.00 │ 0.84 │ 0.91 │ 0.14 │ └───────────╨──────┴──────┴──────┴──────┘ or by taking the :meth:`transpose` of the original table:: @@ -148,9 +148,9 @@ class table(SageObject): sage: table(rows=[(x, n(sin(x), digits=2)) for x in [0..3]], # needs sage.symbolic ....: header_row=['$x$', r'$\sin(x)$'], frame=True).transpose() ┌───────────╥──────┬──────┬──────┬──────┐ - │ $x$ ║ 0 | 1 | 2 | 3 | + │ $x$ ║ 0 │ 1 │ 2 │ 3 │ ├───────────╫──────┼──────┼──────┼──────┤ - │ $\sin(x)$ ║ 0.00 | 0.84 | 0.91 | 0.14 | + │ $\sin(x)$ ║ 0.00 │ 0.84 │ 0.91 │ 0.14 │ └───────────╨──────┴──────┴──────┴──────┘ In either plain text or LaTeX, entries in tables can be aligned to the @@ -166,11 +166,11 @@ class table(SageObject): 4 5 60 sage: table(rows, align='right', frame=True) ┌─────┬───┬────┐ - │ a | b | c | + │ a │ b │ c │ ├─────┼───┼────┤ - │ 100 | 2 | 3 | + │ 100 │ 2 │ 3 │ ├─────┼───┼────┤ - │ 4 | 5 | 60 | + │ 4 │ 5 │ 60 │ └─────┴───┴────┘ To generate HTML you should use ``html(table(...))``:: @@ -253,7 +253,7 @@ def __init__(self, rows=None, columns=None, header_row=False, sage: table([1,2,3], frame=True) ┌───┬───┬───┐ - │ 1 | 2 | 3 | + │ 1 │ 2 │ 3 │ └───┴───┴───┘ """ # If both rows and columns are set, raise an error. @@ -342,20 +342,20 @@ def options(self, **kwds): sage: T = table([[1,2,3], [4,5,6]], header_row=['a', 'b', 'c'], frame=True) sage: T ┌───┬───┬───┐ - │ a | b | c | + │ a │ b │ c │ ╞═══╪═══╪═══╡ - │ 1 | 2 | 3 | + │ 1 │ 2 │ 3 │ ├───┼───┼───┤ - │ 4 | 5 | 6 | + │ 4 │ 5 │ 6 │ └───┴───┴───┘ sage: T.options(header_row=False) sage: T ┌───┬───┬───┐ - │ a | b | c | + │ a │ b │ c │ ├───┼───┼───┤ - │ 1 | 2 | 3 | + │ 1 │ 2 │ 3 │ ├───┼───┼───┤ - │ 4 | 5 | 6 | + │ 4 │ 5 │ 6 │ └───┴───┴───┘ If you do specify a list for ``header_row``, an error is raised:: @@ -398,11 +398,11 @@ def transpose(self): sage: T = table([[1,2,3], [4,5,6]], header_row=['x', 'y', 'z'], frame=True) sage: T.transpose() ┌───╥───┬───┐ - │ x ║ 1 | 4 | + │ x ║ 1 │ 4 │ ├───╫───┼───┤ - │ y ║ 2 | 5 | + │ y ║ 2 │ 5 │ ├───╫───┼───┤ - │ z ║ 3 | 6 | + │ z ║ 3 │ 6 │ └───╨───┴───┘ """ return table(list(zip(*self._rows)), @@ -508,7 +508,7 @@ def _str_table_row(self, row, header_row=False, last_row=False): ' 1 │ 2 3\n├────┼─────┼───────┤\n' sage: T.options(frame=True) sage: T._str_table_row([1,2,3], False) - '│ 1 ║ 2 | 3 |\n├────╫─────┼───────┤\n' + '│ 1 ║ 2 │ 3 │\n├────╫─────┼───────┤\n' Check that :issue:`14601` has been fixed:: @@ -552,7 +552,7 @@ def _str_table_row(self, row, header_row=False, last_row=False): for entry, width in zip(row, widths): s += ("{!s:" + align_char + str(width) + "}").format(entry) if frame: - s += " | " + s += " │ " else: s += " " s = s.rstrip(' ') @@ -696,15 +696,15 @@ def _html_(self): ....: header_row=True, frame=True) sage: T # needs sage.symbolic ┌─────┬───────────┐ - │ $x$ | $\sin(x)$ | + │ $x$ │ $\sin(x)$ │ ╞═════╪═══════════╡ - │ 0 | 0.00 | + │ 0 │ 0.00 │ ├─────┼───────────┤ - │ 1 | 0.84 | + │ 1 │ 0.84 │ ├─────┼───────────┤ - │ 2 | 0.91 | + │ 2 │ 0.91 │ ├─────┼───────────┤ - │ 3 | 0.14 | + │ 3 │ 0.14 │ └─────┴───────────┘ sage: print(html(T)) # needs sage.symbolic
From c5d9fc27a3a62af19d449c5d9c92920a3b486e45 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 22 Nov 2024 19:53:28 -0500 Subject: [PATCH 132/210] src/sage/combinat/bijectionist.py: update right borders in tables The right borders of table cells have been updated to use unicode instead of an ASCII pipe, so any tests that print tables need to be changed. --- src/sage/combinat/bijectionist.py | 108 +++++++++++++++--------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/src/sage/combinat/bijectionist.py b/src/sage/combinat/bijectionist.py index ce1bf8aca13..2020b729917 100644 --- a/src/sage/combinat/bijectionist.py +++ b/src/sage/combinat/bijectionist.py @@ -69,52 +69,52 @@ sage: a, b = bij.statistics_table() sage: table(a, header_row=True, frame=True) ┌───────────┬────────┬────────┬────────┐ - │ a | α_1(a) | α_2(a) | α_3(a) | + │ a │ α_1(a) │ α_2(a) │ α_3(a) │ ╞═══════════╪════════╪════════╪════════╡ - │ [] | 0 | 0 | 0 | + │ [] │ 0 │ 0 │ 0 │ ├───────────┼────────┼────────┼────────┤ - │ [1] | 1 | 1 | 1 | + │ [1] │ 1 │ 1 │ 1 │ ├───────────┼────────┼────────┼────────┤ - │ [1, 2] | 2 | 2 | 2 | + │ [1, 2] │ 2 │ 2 │ 2 │ ├───────────┼────────┼────────┼────────┤ - │ [2, 1] | 2 | 1 | 0 | + │ [2, 1] │ 2 │ 1 │ 0 │ ├───────────┼────────┼────────┼────────┤ - │ [1, 2, 3] | 3 | 3 | 3 | + │ [1, 2, 3] │ 3 │ 3 │ 3 │ ├───────────┼────────┼────────┼────────┤ - │ [1, 3, 2] | 3 | 2 | 1 | + │ [1, 3, 2] │ 3 │ 2 │ 1 │ ├───────────┼────────┼────────┼────────┤ - │ [2, 1, 3] | 3 | 2 | 1 | + │ [2, 1, 3] │ 3 │ 2 │ 1 │ ├───────────┼────────┼────────┼────────┤ - │ [2, 3, 1] | 3 | 2 | 0 | + │ [2, 3, 1] │ 3 │ 2 │ 0 │ ├───────────┼────────┼────────┼────────┤ - │ [3, 1, 2] | 3 | 1 | 0 | + │ [3, 1, 2] │ 3 │ 1 │ 0 │ ├───────────┼────────┼────────┼────────┤ - │ [3, 2, 1] | 3 | 2 | 1 | + │ [3, 2, 1] │ 3 │ 2 │ 1 │ └───────────┴────────┴────────┴────────┘ sage: table(b, header_row=True, frame=True) ┌───────────┬───┬────────┬────────┬────────┐ - │ b | τ | β_1(b) | β_2(b) | β_3(b) | + │ b │ τ │ β_1(b) │ β_2(b) │ β_3(b) │ ╞═══════════╪═══╪════════╪════════╪════════╡ - │ [] | 0 | 0 | 0 | 0 | + │ [] │ 0 │ 0 │ 0 │ 0 │ ├───────────┼───┼────────┼────────┼────────┤ - │ [1] | 1 | 1 | 1 | 1 | + │ [1] │ 1 │ 1 │ 1 │ 1 │ ├───────────┼───┼────────┼────────┼────────┤ - │ [1, 2] | 2 | 2 | 1 | 0 | + │ [1, 2] │ 2 │ 2 │ 1 │ 0 │ ├───────────┼───┼────────┼────────┼────────┤ - │ [2, 1] | 1 | 2 | 2 | 2 | + │ [2, 1] │ 1 │ 2 │ 2 │ 2 │ ├───────────┼───┼────────┼────────┼────────┤ - │ [1, 2, 3] | 3 | 3 | 1 | 0 | + │ [1, 2, 3] │ 3 │ 3 │ 1 │ 0 │ ├───────────┼───┼────────┼────────┼────────┤ - │ [1, 3, 2] | 2 | 3 | 2 | 1 | + │ [1, 3, 2] │ 2 │ 3 │ 2 │ 1 │ ├───────────┼───┼────────┼────────┼────────┤ - │ [2, 1, 3] | 2 | 3 | 2 | 1 | + │ [2, 1, 3] │ 2 │ 3 │ 2 │ 1 │ ├───────────┼───┼────────┼────────┼────────┤ - │ [2, 3, 1] | 2 | 3 | 2 | 1 | + │ [2, 3, 1] │ 2 │ 3 │ 2 │ 1 │ ├───────────┼───┼────────┼────────┼────────┤ - │ [3, 1, 2] | 2 | 3 | 2 | 0 | + │ [3, 1, 2] │ 2 │ 3 │ 2 │ 0 │ ├───────────┼───┼────────┼────────┼────────┤ - │ [3, 2, 1] | 1 | 3 | 3 | 3 | + │ [3, 2, 1] │ 1 │ 3 │ 3 │ 3 │ └───────────┴───┴────────┴────────┴────────┘ sage: from sage.combinat.cyclic_sieving_phenomenon import orbit_decomposition @@ -849,51 +849,51 @@ def statistics_table(self, header=True): sage: a, b = bij.statistics_table() sage: table(a, header_row=True, frame=True) ┌───────────┬────────┬────────┐ - │ a | α_1(a) | α_2(a) | + │ a │ α_1(a) │ α_2(a) │ ╞═══════════╪════════╪════════╡ - │ [] | 0 | 0 | + │ [] │ 0 │ 0 │ ├───────────┼────────┼────────┤ - │ [1] | 1 | 1 | + │ [1] │ 1 │ 1 │ ├───────────┼────────┼────────┤ - │ [1, 2] | 2 | 2 | + │ [1, 2] │ 2 │ 2 │ ├───────────┼────────┼────────┤ - │ [2, 1] | 1 | 0 | + │ [2, 1] │ 1 │ 0 │ ├───────────┼────────┼────────┤ - │ [1, 2, 3] | 3 | 3 | + │ [1, 2, 3] │ 3 │ 3 │ ├───────────┼────────┼────────┤ - │ [1, 3, 2] | 2 | 1 | + │ [1, 3, 2] │ 2 │ 1 │ ├───────────┼────────┼────────┤ - │ [2, 1, 3] | 2 | 1 | + │ [2, 1, 3] │ 2 │ 1 │ ├───────────┼────────┼────────┤ - │ [2, 3, 1] | 2 | 0 | + │ [2, 3, 1] │ 2 │ 0 │ ├───────────┼────────┼────────┤ - │ [3, 1, 2] | 1 | 0 | + │ [3, 1, 2] │ 1 │ 0 │ ├───────────┼────────┼────────┤ - │ [3, 2, 1] | 2 | 1 | + │ [3, 2, 1] │ 2 │ 1 │ └───────────┴────────┴────────┘ sage: table(b, header_row=True, frame=True) ┌───────────┬───┬────────┬────────┐ - │ b | τ | β_1(b) | β_2(b) | + │ b │ τ │ β_1(b) │ β_2(b) │ ╞═══════════╪═══╪════════╪════════╡ - │ [] | 0 | 0 | 0 | + │ [] │ 0 │ 0 │ 0 │ ├───────────┼───┼────────┼────────┤ - │ [1] | 1 | 1 | 1 | + │ [1] │ 1 │ 1 │ 1 │ ├───────────┼───┼────────┼────────┤ - │ [1, 2] | 2 | 1 | 0 | + │ [1, 2] │ 2 │ 1 │ 0 │ ├───────────┼───┼────────┼────────┤ - │ [2, 1] | 1 | 2 | 2 | + │ [2, 1] │ 1 │ 2 │ 2 │ ├───────────┼───┼────────┼────────┤ - │ [1, 2, 3] | 3 | 1 | 0 | + │ [1, 2, 3] │ 3 │ 1 │ 0 │ ├───────────┼───┼────────┼────────┤ - │ [1, 3, 2] | 2 | 2 | 1 | + │ [1, 3, 2] │ 2 │ 2 │ 1 │ ├───────────┼───┼────────┼────────┤ - │ [2, 1, 3] | 2 | 2 | 1 | + │ [2, 1, 3] │ 2 │ 2 │ 1 │ ├───────────┼───┼────────┼────────┤ - │ [2, 3, 1] | 2 | 2 | 1 | + │ [2, 3, 1] │ 2 │ 2 │ 1 │ ├───────────┼───┼────────┼────────┤ - │ [3, 1, 2] | 2 | 2 | 0 | + │ [3, 1, 2] │ 2 │ 2 │ 0 │ ├───────────┼───┼────────┼────────┤ - │ [3, 2, 1] | 1 | 3 | 3 | + │ [3, 2, 1] │ 1 │ 3 │ 3 │ └───────────┴───┴────────┴────────┘ TESTS: @@ -906,27 +906,27 @@ def statistics_table(self, header=True): sage: a, b = bij.statistics_table() sage: table(a, header_row=True, frame=True) ┌────────┐ - │ a | + │ a │ ╞════════╡ - │ [] | + │ [] │ ├────────┤ - │ [1] | + │ [1] │ ├────────┤ - │ [1, 2] | + │ [1, 2] │ ├────────┤ - │ [2, 1] | + │ [2, 1] │ └────────┘ sage: table(b, header_row=True, frame=True) ┌────────┬───┐ - │ b | τ | + │ b │ τ │ ╞════════╪═══╡ - │ [] | 0 | + │ [] │ 0 │ ├────────┼───┤ - │ [1] | 1 | + │ [1] │ 1 │ ├────────┼───┤ - │ [1, 2] | 2 | + │ [1, 2] │ 2 │ ├────────┼───┤ - │ [2, 1] | 1 | + │ [2, 1] │ 1 │ └────────┴───┘ We can omit the header:: From 5c9e59745f5ac1aaa73973496220951853b3946a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 23 Nov 2024 08:16:59 +0100 Subject: [PATCH 133/210] fix mistake --- src/sage/structure/sequence.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index 6a18b3bf610..1a056f33c6d 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -257,7 +257,7 @@ def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=Non except ImportError: pass else: - if isinstance(universe, MPolynomialRing_base, BooleanMonomialMonoid) or (isinstance(universe, QuotientRing_nc) and isinstance(universe.cover_ring(), MPolynomialRing_base)): + if isinstance(universe, (MPolynomialRing_base, BooleanMonomialMonoid)) or (isinstance(universe, QuotientRing_nc) and isinstance(universe.cover_ring(), MPolynomialRing_base)): return PolynomialSequence(x, universe, immutable=immutable, cr=cr, cr_str=cr_str) return Sequence_generic(x, universe, check, immutable, cr, cr_str, use_sage_types) From b9e396a7444167fb334b12a5b41db9af0cfa8ef0 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sat, 23 Nov 2024 11:49:49 +0100 Subject: [PATCH 134/210] Updated SageMath version to 10.5.rc1 --- CITATION.cff | 4 ++-- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 4 ++-- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/version_requirements.txt | 2 +- build/pkgs/sage_docbuild/version_requirements.txt | 2 +- build/pkgs/sage_setup/version_requirements.txt | 2 +- build/pkgs/sage_sws2rst/version_requirements.txt | 2 +- build/pkgs/sagelib/version_requirements.txt | 2 +- build/pkgs/sagemath_bliss/version_requirements.txt | 2 +- build/pkgs/sagemath_categories/version_requirements.txt | 2 +- build/pkgs/sagemath_coxeter3/version_requirements.txt | 2 +- build/pkgs/sagemath_environment/version_requirements.txt | 2 +- build/pkgs/sagemath_mcqd/version_requirements.txt | 2 +- build/pkgs/sagemath_meataxe/version_requirements.txt | 2 +- build/pkgs/sagemath_objects/version_requirements.txt | 2 +- build/pkgs/sagemath_repl/version_requirements.txt | 2 +- build/pkgs/sagemath_sirocco/version_requirements.txt | 2 +- build/pkgs/sagemath_tdlib/version_requirements.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 38 files changed, 44 insertions(+), 44 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index c2d778402ac..846dc8d56de 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.5.rc0 +version: 10.5.rc1 doi: 10.5281/zenodo.8042260 -date-released: 2024-11-16 +date-released: 2024-11-23 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 539643e825a..eb2ad2d41d0 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.5.rc0, Release Date: 2024-11-16 +SageMath version 10.5.rc1, Release Date: 2024-11-23 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 3a59fabe4df..c572b3c4604 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,3 +1,3 @@ tarball=configure-VERSION.tar.gz -sha1=75d6eb488fd370ea17699188dabf78afa295d6d9 -sha256=679c7a5c352eeac458ee6574326208df1bc0b30be5c803b952e19a9d2a8b7d32 +sha1=4b08e1c0e6b812bfbade59ef7c751619d8e44f81 +sha256=9ae6ed35a2391f1af02ed2c7b855670d3db0bb421a69064a2c907b4f3a584eb4 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 1a46ad3eaf8..fe064f68b5e 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -659705e89638fae6821783730c357bf292ebed6e +95eb9b8c8642831f849b5fec82a0b545a95e9ca6 diff --git a/build/pkgs/sage_conf/version_requirements.txt b/build/pkgs/sage_conf/version_requirements.txt index 75a00f0f83b..9d4b482d5a4 100644 --- a/build/pkgs/sage_conf/version_requirements.txt +++ b/build/pkgs/sage_conf/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.5rc0 +sage-conf ~= 10.5rc1 diff --git a/build/pkgs/sage_docbuild/version_requirements.txt b/build/pkgs/sage_docbuild/version_requirements.txt index 6e02f12a485..cc82b61571d 100644 --- a/build/pkgs/sage_docbuild/version_requirements.txt +++ b/build/pkgs/sage_docbuild/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.5rc0 +sage-docbuild ~= 10.5rc1 diff --git a/build/pkgs/sage_setup/version_requirements.txt b/build/pkgs/sage_setup/version_requirements.txt index af4273ca5a6..1ff54dc7d60 100644 --- a/build/pkgs/sage_setup/version_requirements.txt +++ b/build/pkgs/sage_setup/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.5rc0 +sage-setup ~= 10.5rc1 diff --git a/build/pkgs/sage_sws2rst/version_requirements.txt b/build/pkgs/sage_sws2rst/version_requirements.txt index f6461b249ee..1c2539d939c 100644 --- a/build/pkgs/sage_sws2rst/version_requirements.txt +++ b/build/pkgs/sage_sws2rst/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.5rc0 +sage-sws2rst ~= 10.5rc1 diff --git a/build/pkgs/sagelib/version_requirements.txt b/build/pkgs/sagelib/version_requirements.txt index a5764ac2ff3..43b9a42f129 100644 --- a/build/pkgs/sagelib/version_requirements.txt +++ b/build/pkgs/sagelib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-standard ~= 10.5rc0 +sagemath-standard ~= 10.5rc1 diff --git a/build/pkgs/sagemath_bliss/version_requirements.txt b/build/pkgs/sagemath_bliss/version_requirements.txt index 54e31199a21..2368924f603 100644 --- a/build/pkgs/sagemath_bliss/version_requirements.txt +++ b/build/pkgs/sagemath_bliss/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.5rc0 +sagemath-bliss ~= 10.5rc1 diff --git a/build/pkgs/sagemath_categories/version_requirements.txt b/build/pkgs/sagemath_categories/version_requirements.txt index 24190dcde29..12dbd988f69 100644 --- a/build/pkgs/sagemath_categories/version_requirements.txt +++ b/build/pkgs/sagemath_categories/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.5rc0 +sagemath-categories ~= 10.5rc1 diff --git a/build/pkgs/sagemath_coxeter3/version_requirements.txt b/build/pkgs/sagemath_coxeter3/version_requirements.txt index d583b886874..68b68b8849a 100644 --- a/build/pkgs/sagemath_coxeter3/version_requirements.txt +++ b/build/pkgs/sagemath_coxeter3/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.5rc0 +sagemath-coxeter3 ~= 10.5rc1 diff --git a/build/pkgs/sagemath_environment/version_requirements.txt b/build/pkgs/sagemath_environment/version_requirements.txt index 4c460e8258e..90066e303ad 100644 --- a/build/pkgs/sagemath_environment/version_requirements.txt +++ b/build/pkgs/sagemath_environment/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.5rc0 +sagemath-environment ~= 10.5rc1 diff --git a/build/pkgs/sagemath_mcqd/version_requirements.txt b/build/pkgs/sagemath_mcqd/version_requirements.txt index 394ab1ab42c..f41ce17c20b 100644 --- a/build/pkgs/sagemath_mcqd/version_requirements.txt +++ b/build/pkgs/sagemath_mcqd/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.5rc0 +sagemath-mcqd ~= 10.5rc1 diff --git a/build/pkgs/sagemath_meataxe/version_requirements.txt b/build/pkgs/sagemath_meataxe/version_requirements.txt index e3b1b8d80dd..f8304228dbc 100644 --- a/build/pkgs/sagemath_meataxe/version_requirements.txt +++ b/build/pkgs/sagemath_meataxe/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.5rc0 +sagemath-meataxe ~= 10.5rc1 diff --git a/build/pkgs/sagemath_objects/version_requirements.txt b/build/pkgs/sagemath_objects/version_requirements.txt index 84f9308c624..990a0601e08 100644 --- a/build/pkgs/sagemath_objects/version_requirements.txt +++ b/build/pkgs/sagemath_objects/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.5rc0 +sagemath-objects ~= 10.5rc1 diff --git a/build/pkgs/sagemath_repl/version_requirements.txt b/build/pkgs/sagemath_repl/version_requirements.txt index 124091c62c1..7ab5cec5f5b 100644 --- a/build/pkgs/sagemath_repl/version_requirements.txt +++ b/build/pkgs/sagemath_repl/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.5rc0 +sagemath-repl ~= 10.5rc1 diff --git a/build/pkgs/sagemath_sirocco/version_requirements.txt b/build/pkgs/sagemath_sirocco/version_requirements.txt index 57ed9f87891..0863567dacc 100644 --- a/build/pkgs/sagemath_sirocco/version_requirements.txt +++ b/build/pkgs/sagemath_sirocco/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.5rc0 +sagemath-sirocco ~= 10.5rc1 diff --git a/build/pkgs/sagemath_tdlib/version_requirements.txt b/build/pkgs/sagemath_tdlib/version_requirements.txt index ea110e02460..847534f161e 100644 --- a/build/pkgs/sagemath_tdlib/version_requirements.txt +++ b/build/pkgs/sagemath_tdlib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.5rc0 +sagemath-tdlib ~= 10.5rc1 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/src/VERSION.txt b/src/VERSION.txt index 9228dedd0ce..d2205320557 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.5.rc0 +10.5.rc1 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 9c1fb9c0309..bafb8fc6368 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.5.rc0' -SAGE_RELEASE_DATE='2024-11-16' -SAGE_VERSION_BANNER='SageMath version 10.5.rc0, Release Date: 2024-11-16' +SAGE_VERSION='10.5.rc1' +SAGE_RELEASE_DATE='2024-11-23' +SAGE_VERSION_BANNER='SageMath version 10.5.rc1, Release Date: 2024-11-23' diff --git a/src/sage/version.py b/src/sage/version.py index d05ce0beb53..eeb9eae6692 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '10.5.rc0' -date = '2024-11-16' -banner = 'SageMath version 10.5.rc0, Release Date: 2024-11-16' +version = '10.5.rc1' +date = '2024-11-23' +banner = 'SageMath version 10.5.rc1, Release Date: 2024-11-23' From 0fe4a58321fae3d114e234b81e771af0a5d1fe79 Mon Sep 17 00:00:00 2001 From: Soham Rane Date: Sat, 23 Nov 2024 19:08:28 +0530 Subject: [PATCH 135/210] Create changelog_trigger.yml This workflow in turn triggeres changelog generator workflow on website repo --- .github/workflows/changelog_trigger.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/changelog_trigger.yml diff --git a/.github/workflows/changelog_trigger.yml b/.github/workflows/changelog_trigger.yml new file mode 100644 index 00000000000..374a002c4f9 --- /dev/null +++ b/.github/workflows/changelog_trigger.yml @@ -0,0 +1,23 @@ +name: Trigger Changelog Generation + +on: + release: + types: [published] + +jobs: + trigger-website-repo-workflow: + runs-on: ubuntu-latest + steps: + - name: Trigger Workflow in website repo + env: + GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + TRIGGER_SECRET: ${{ secrets.CHANGELOG_TRIGGER_SECRET }} + RELEASE_TAG: ${{ github.event.release.tag_name }} + run: | + curl -L \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $GH_TOKEN" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/sagemath/website/actions/workflows/generate_changelog.yml/dispatches \ + -d '{"ref":"master","inputs":{"release_tag":"'"$RELEASE_TAG"'","trigger_secret":"'"$TRIGGER_SECRET"'"}}' From 520af53f688be9a1a8b7def6f3ed6e744411a662 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 24 Nov 2024 20:38:24 +0700 Subject: [PATCH 136/210] Numerical evaluation of modular form --- src/sage/modular/modform/ambient_eps.py | 15 ++ .../modular/modform/cuspidal_submodule.py | 15 ++ .../modular/modform/eisenstein_submodule.py | 16 +++ src/sage/modular/modform/element.py | 136 +++++++++++++++++- 4 files changed, 181 insertions(+), 1 deletion(-) diff --git a/src/sage/modular/modform/ambient_eps.py b/src/sage/modular/modform/ambient_eps.py index ddd4ed467bc..6d6d8a1c575 100644 --- a/src/sage/modular/modform/ambient_eps.py +++ b/src/sage/modular/modform/ambient_eps.py @@ -288,3 +288,18 @@ def hecke_module_of_level(self, N): return constructor.ModularForms(self.character().restrict(N), self.weight(), self.base_ring(), prec=self.prec()) else: raise ValueError("N (=%s) must be a divisor or a multiple of the level of self (=%s)" % (N, self.level())) + + def _pari_init_(self): + """ + Conversion to Pari. + + EXAMPLES:: + + sage: m = ModularForms(DirichletGroup(17).0^2, 2) + sage: pari.mfdim(m) + 3 + sage: pari.mfparams(m) + [17, 2, Mod(9, 17), 4, t^4 + 1] + """ + from sage.libs.pari import pari + return pari.mfinit([self.level(), self.weight(), self.character()], 4) diff --git a/src/sage/modular/modform/cuspidal_submodule.py b/src/sage/modular/modform/cuspidal_submodule.py index 5de0805b386..90cf7758cdc 100644 --- a/src/sage/modular/modform/cuspidal_submodule.py +++ b/src/sage/modular/modform/cuspidal_submodule.py @@ -377,6 +377,21 @@ def _compute_q_expansion_basis(self, prec=None): return [weight1.modular_ratio_to_prec(chi, f, prec) for f in weight1.hecke_stable_subspace(chi)] + def _pari_init_(self): + """ + Conversion to Pari. + + EXAMPLES:: + + sage: A = CuspForms(DirichletGroup(23, QQ).0, 1) + sage: pari.mfparams(A) + [23, 1, -23, 1, t + 1] + sage: pari.mfdim(A) + 1 + """ + from sage.libs.pari import pari + return pari.mfinit([self.level(), self.weight(), self.character()], 1) + class CuspidalSubmodule_wt1_gH(CuspidalSubmodule): r""" diff --git a/src/sage/modular/modform/eisenstein_submodule.py b/src/sage/modular/modform/eisenstein_submodule.py index fbbe2e06da3..72665f3d686 100644 --- a/src/sage/modular/modform/eisenstein_submodule.py +++ b/src/sage/modular/modform/eisenstein_submodule.py @@ -586,6 +586,22 @@ class EisensteinSubmodule_eps(EisensteinSubmodule_params): q^5 + (zeta3 + 1)*q^8 + O(q^10) ] """ + def _pari_init_(self): + """ + Conversion to Pari. + + EXAMPLES:: + + sage: e = DirichletGroup(27,CyclotomicField(3)).0**2 + sage: M = ModularForms(e,2,prec=10).eisenstein_subspace() + sage: pari.mfdim(M) + 6 + sage: pari.mfparams(M) + [27, 2, Mod(10, 27), 3, t^2 + t + 1] + """ + from sage.libs.pari import pari + return pari.mfinit([self.level(), self.weight(), self.character()], 3) + # TODO # def _compute_q_expansion_basis(self, prec): # B = EisensteinSubmodule_params._compute_q_expansion_basis(self, prec) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index 6ce83f0372e..6768fbc1c03 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -219,6 +219,38 @@ def _repr_(self): """ return str(self.q_expansion()) + def _pari_init_(self): + """ + Conversion to Pari. + + TESTS:: + + sage: M = EisensteinForms(96, 2) + sage: M.6 + O(q^6) + sage: M.7 + O(q^6) + sage: pari(M.6) == pari(M.7) + False + sage: pari(M.6).mfcoefs(10) + [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0] + + sage: M = ModularForms(DirichletGroup(17).0^2, 2) + sage: pari(M.0).mfcoefs(5) + [0, 1, Mod(-t^3 + t^2 - 1, t^4 + 1), Mod(t^3 - t^2 - t - 1, t^4 + 1), Mod(2*t^3 - t^2 + 2*t, t^4 + 1), Mod(-t^3 - t^2, t^4 + 1)] + sage: M.0.qexp(5) + q + (-zeta8^3 + zeta8^2 - 1)*q^2 + (zeta8^3 - zeta8^2 - zeta8 - 1)*q^3 + (2*zeta8^3 - zeta8^2 + 2*zeta8)*q^4 + O(q^5) + """ + from sage.libs.pari import pari + from sage.rings.number_field.number_field_element import NumberFieldElement + M = pari(self.parent()) + f = self.qexp(self.parent().sturm_bound()) + coefficients = [ + x.__pari__('t') if isinstance(x, NumberFieldElement) else x + for x in f] + # we cannot compute pari(f) directly because we need to set the variable name as t + return M.mflinear(M.mftobasis(coefficients + [0] * (f.prec() - len(coefficients)))) + def __call__(self, x, prec=None): """ Evaluate the `q`-expansion of this modular form at x. @@ -233,9 +265,111 @@ def __call__(self, x, prec=None): sage: f(0) 0 - """ + + Evaluate numerically:: + + sage: f = ModularForms(1, 12).0 + sage: f(0.3) # rel tol 1e-12 + 2.3452457654859093943911095448677943331e-6 + sage: f = EisensteinForms(1, 4).0 + sage: f(0.9) # rel tol 1e-12 + 1.2647594220924141255379137476604196202e7 + + TESTS:: + + sage: f = ModularForms(96, 2).0 + sage: f(0.3) # rel tol 1e-12 + 0.299999997396191 + sage: f(0.0+0.0*I) + 0 + + Higher precision:: + + sage: f(ComplexField(1024)(0.3)) # rel tol 1e-300 + 0.299999997396191310292851660587501640585287966606926712372685051052183848485101271417891225951099656119402111562859500035032541015715233392211176407057239620967660312966086779337994327624536037187214146041831261633868799976346085552246983798477217725916938994733822571999849908529513379575860920140944745353698614348900664409173 + sage: f(ComplexField(1024)(1+2*I)/3) # rel tol 1e-300 + 0.321653845723568825567905326693899006909160675826045434571915911867833071589696569615194893689901721899490426373845744862497953969333193682758406183041097473225418603897622369265087989491842075279034290073993079800285909375526425931622610153626461152157393613063055863371355916362145445869467929251660349223775541765403069287756 + 0.670612446383675863028207907112577773897857202143717552376205630684889727243085419317012486309756101468259545944957593645365938699136657674117927754488042563377649540662343013944001734211314704342435690945950614217421684269575557390763317106676805075226392963322227027538349081598725382171963223815408532667527371217267163311545*I + + Confirm numerical evaluation matches the q-expansion:: + + sage: f = EisensteinForms(1, 4).0 + sage: f(0.3) # rel tol 1e-12 + 741.741819297986 + sage: f.qexp(50).polynomial()(0.3) # rel tol 1e-12 + 741.741819297986 + + With a nontrivial character:: + + sage: M = ModularForms(DirichletGroup(17).0^2, 2) + sage: M.0(0.5) # rel tol 1e-12 + 0.166916655031616406 + 0.0111529051752428267*I + sage: M.0.qexp(50).polynomial()(0.5) # rel tol 1e-12 + 0.166916655031612 + 0.0111529051752446*I + + Higher precision:: + + sage: f(ComplexField(1024)(1+2*I)/3) # rel tol 1e-300 + 429.199948322062942786880853990563596327120079065066254109432103144473221199829480785902664748868493907769441449473555229387561526629665655661427945472113572803307694967838236473063580602746440482717293005228669958745844625512025507948139637569777953993158796185335086681612581007434046175713336414282554064647719988594288913120 - 786.157362841882433511538308248529749947718853411006076221833170249528876337224355907958857459245137532046109965098912535988424738933052981899295555982842062176345159766720738928291892050139943952864992573038108609831401219671626805315734950245686731132797235451098295774853868203027469066869512246697946206845252244686704009880*I + sage: f.qexp(3000).polynomial()(ComplexField(1024)(1+2*I)/3) # rel tol 1e-300 + 429.1999483220629427868808539905635963271200790650662541094321031444732211998294807859026647488684939077694414494735552293875615266296656556614279454721135728033076949678382364730635806027464404827172930052286699587458446255120255079481396375697779539931587961853350866816125810074340461757133364142825540647 - 786.1573628418824335115383082485297499477188534110060762218331702495288763372243559079588574592451375320461099650989125359884247389330529818992955559828420621763451597667207389282918920501399439528649925730381086098314012196716268053157349502456867311327972354510982957748538682030274690668695122466979462069*I + + Check ``SR`` does not make the result lose precision:: + + sage: f(ComplexField(1024)(1+2*I)/3 + x - x) # rel tol 1e-300 + 429.199948322062942786880853990563596327120079065066254109432103144473221199829480785902664748868493907769441449473555229387561526629665655661427945472113572803307694967838236473063580602746440482717293005228669958745844625512025507948139637569777953993158796185335086681612581007434046175713336414282554064647719988594288913120 - 786.157362841882433511538308248529749947718853411006076221833170249528876337224355907958857459245137532046109965098912535988424738933052981899295555982842062176345159766720738928291892050139943952864992573038108609831401219671626805315734950245686731132797235451098295774853868203027469066869512246697946206845252244686704009880*I + """ + from sage.rings.integer import Integer + from sage.misc.functional import log + from sage.structure.element import parent + from sage.rings.complex_mpfr import ComplexNumber + from sage.rings.cc import CC + from sage.rings.real_mpfr import RealNumber + from sage.symbolic.constants import pi + from sage.rings.imaginary_unit import I # import from here instead of sage.symbolic.constants to avoid cast to SR + from sage.symbolic.expression import Expression + if isinstance(x, Expression): + try: + x = x.pyobject() + except TypeError: + pass + if x in CC: + if x == 0: + return self.qexp(1)[0] + if not isinstance(x, (RealNumber, ComplexNumber)): + x = CC(x) # might lose precision if this is done unconditionally (TODO what about interval and ball types?) + if isinstance(x, (RealNumber, ComplexNumber)): + return self.eval_at_tau(log(x)/(2*parent(x)(pi)*I)) # cast to parent(x) to force numerical evaluation of pi return self.q_expansion(prec)(x) + def eval_at_tau(self, tau): + r""" + Evaluate this modular form at the half-period ratio `\tau`. + This is related to `q` by `q = e^{2\pi i \tau}`. + + TESTS: + + Check ``SR`` does not make the result lose precision:: + + sage: f = EisensteinForms(1, 4).0 + sage: f.eval_at_tau(ComplexField(1024)(1+2*I)/3 + x - x) # rel tol 1e-300 + -1.04515705822020600561978783142860369660026850501222224469267227428610961984014327083815700740447933744582038996915609186529679911598578009500436771124828467825291523495268250908979376807788900006209591385867335039616941215684551066086395842278498086825793727621839992525301493298760414972421090964300343066954661155411439536627 + 2.72251120985198030982039335832865902741427458369769410157055618486577347595364447691251370354689965324163927321325893070988471497088161774220563106128912211718551704485285953814944589707973769813648021661388772620343922776832791016518443400344473023932887976990908175600815202111437107948718799541078554987252368104803278882956*I + """ + from sage.libs.pari.convert_sage import gen_to_sage + from sage.libs.pari import pari + from sage.rings.complex_mpfr import ComplexNumber + from sage.rings.real_mpfr import RealNumber + from sage.symbolic.expression import Expression + if isinstance(tau, Expression): + try: + tau = tau.pyobject() + except TypeError: + pass + if isinstance(tau, (RealNumber, ComplexNumber)): + precision = tau.prec() + else: + precision = 53 + return gen_to_sage(pari(self.parent()).mfeval(self, tau, precision=precision)) + @cached_method def valuation(self): """ From 5773e0beb5294b5e8b1d1018b3021e2160e7e8ce Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 25 Nov 2024 12:53:02 +0800 Subject: [PATCH 137/210] Remove pipfile --- .ci/write-dockerfile.sh | 4 ++-- .gitignore | 4 ---- Makefile | 1 - Pipfile.m4 | 40 ---------------------------------------- bootstrap | 1 - src/Pipfile.m4 | 22 ---------------------- 6 files changed, 2 insertions(+), 70 deletions(-) delete mode 100644 Pipfile.m4 delete mode 100644 src/Pipfile.m4 diff --git a/.ci/write-dockerfile.sh b/.ci/write-dockerfile.sh index cfd4fb20810..973444bec72 100755 --- a/.ci/write-dockerfile.sh +++ b/.ci/write-dockerfile.sh @@ -275,11 +275,11 @@ cat < Date: Tue, 26 Nov 2024 14:10:58 +0800 Subject: [PATCH 138/210] Add dependency groups to `pyproject.toml` --- pyproject.toml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 47c125c4e26..9840e43b7a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -90,8 +90,8 @@ platforms = [ 'osx-64', 'linux-64', 'linux-aarch64', 'osx-arm64' ] -[external] # External dependencies in the format proposed by https://peps.python.org/pep-0725 +[external] build-requires = [ "virtual:compiler/c", "virtual:compiler/cpp", @@ -152,4 +152,23 @@ dependencies = [ "pkg:generic/tachyon", "pkg:generic/sagemath-polytopes-db", "pkg:generic/sagemath-elliptic-curves", + "pkg:generic/sagemath-graphs", +] + +[dependency-groups] +test = [ + "pytest", + "pytest-xdist", + "coverage", +] +docs = [ + "sphinx", + "sphinx-inline-tabs", + "furo", +] +lint = [ + "relint", + "ruff", + "pycodestyle", + "flake8-rst-docstrings", ] From f211bdcac6b9088671339aebfe77f78d0d9fab3f Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 17 Nov 2024 20:12:24 +0800 Subject: [PATCH 139/210] Fix meson build by adding missing python files --- src/meson.build | 6 +----- src/sage/matroids/meson.build | 2 ++ src/sage/rings/meson.build | 1 + 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/meson.build b/src/meson.build index 10ce96a8da2..31544d29dbd 100644 --- a/src/meson.build +++ b/src/meson.build @@ -78,11 +78,7 @@ endif # that too to make the fallback detection with CMake work blas_order += ['cblas', 'openblas', 'OpenBLAS', 'flexiblas', 'blis', 'blas'] blas = dependency(blas_order) -gsl = dependency( - 'gsl', - version: '>=2.5', - required: true, -) +gsl = dependency('gsl', version: '>=2.5', required: true) gd = cc.find_library('gd') # Only some platforms have a standalone math library (https://mesonbuild.com/howtox.html#add-math-library-lm-portably) m = cc.find_library('m', required: false) diff --git a/src/sage/matroids/meson.build b/src/sage/matroids/meson.build index 43c80789811..f60970da5b9 100644 --- a/src/sage/matroids/meson.build +++ b/src/sage/matroids/meson.build @@ -4,6 +4,8 @@ py.install_sources( 'basis_exchange_matroid.pxd', 'basis_matroid.pxd', 'catalog.py', + 'chow_ring.py', + 'chow_ring_ideal.py', 'circuit_closures_matroid.pxd', 'circuits_matroid.pxd', 'constructor.py', diff --git a/src/sage/rings/meson.build b/src/sage/rings/meson.build index 14ed48a7c7a..171592eccbd 100644 --- a/src/sage/rings/meson.build +++ b/src/sage/rings/meson.build @@ -72,6 +72,7 @@ py.install_sources( 'ring_extension_element.pxd', 'ring_extension_homset.py', 'ring_extension_morphism.pxd', + 'species.py', 'sum_of_squares.pxd', 'tate_algebra.py', 'tate_algebra_element.pxd', From d41a5fb157d9ec7d3f4f24745d7145d715302dff Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 29 Oct 2024 13:28:21 +0800 Subject: [PATCH 140/210] Use meson as backend for numpy.f2py --- src/sage/misc/inline_fortran.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/sage/misc/inline_fortran.py b/src/sage/misc/inline_fortran.py index ccd4b1da87c..e245249af20 100644 --- a/src/sage/misc/inline_fortran.py +++ b/src/sage/misc/inline_fortran.py @@ -162,9 +162,7 @@ def eval(self, x, globals=None, locals=None): # What follows are the arguments to f2py itself (appended later # just for logical separation) - cmd += ['-c', '-m', name, fortran_file, '--quiet', - '--f77exec=sage-inline-fortran', - '--f90exec=sage-inline-fortran'] + s_lib_path + s_lib + cmd += ['-c', '-m', name, fortran_file, '--quiet', '--backend', 'meson'] + s_lib_path + s_lib try: out = subprocess.check_output(cmd, stderr=subprocess.STDOUT) From 791c4934d275dfd806cc3f40ea71238577086eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 26 Nov 2024 11:28:56 +0100 Subject: [PATCH 141/210] adding degrees in repr of functor --- src/sage/algebras/free_algebra.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 0c1699ca5dd..30941a0ef26 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -1647,6 +1647,10 @@ def _repr_(self) -> str: sage: algebras.Free(QQ,4,'x,y,z,t').construction()[0] Associative[x,y,z,t] + sage: algebras.Free(QQ,4,'x,y,z,t',degrees=(1,2,3,4)).construction()[0] + Associative[x,y,z,t] with degrees {x: 1, y: 2, z: 3, t: 4} """ - # should we add the degree there ? - return "Associative[%s]" % ','.join(self.vars) + vars = ','.join(self.vars) + if self.degs is None: + return f"Associative[{vars}]" + return f"Associative[{vars}] with degrees {self.degs}" From 7ce18777a7e6784a9d123ceb5f279d99d51958ba Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Tue, 26 Nov 2024 10:00:00 -0600 Subject: [PATCH 142/210] the patch breaks some macOS installations --- build/pkgs/ecm/patches/assembler.patch | 67 -------------------------- 1 file changed, 67 deletions(-) delete mode 100644 build/pkgs/ecm/patches/assembler.patch diff --git a/build/pkgs/ecm/patches/assembler.patch b/build/pkgs/ecm/patches/assembler.patch deleted file mode 100644 index 2e3d6c94b6d..00000000000 --- a/build/pkgs/ecm/patches/assembler.patch +++ /dev/null @@ -1,67 +0,0 @@ -*** a/x86_64/Makefile.in Mon Nov 4 14:08:05 2024 ---- b/x86_64/Makefile.in Mon Nov 4 14:15:46 2024 -*************** -*** 355,361 **** - all: all-am - - .SUFFIXES: -! .SUFFIXES: .asm .lo .o .obj .s - $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ ---- 355,361 ---- - all: all-am - - .SUFFIXES: -! .SUFFIXES: .asm .lo .o .obj .sx - $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ -*************** -*** 406,418 **** - distclean-compile: - -rm -f *.tab.c - -! .s.o: - $(AM_V_CCAS)$(CCASCOMPILE) -c -o $@ $< - -! .s.obj: - $(AM_V_CCAS)$(CCASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -! .s.lo: - $(AM_V_CCAS)$(LTCCASCOMPILE) -c -o $@ $< - - mostlyclean-libtool: ---- 406,418 ---- - distclean-compile: - -rm -f *.tab.c - -! .sx.o: - $(AM_V_CCAS)$(CCASCOMPILE) -c -o $@ $< - -! .sx.obj: - $(AM_V_CCAS)$(CCASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -! .sx.lo: - $(AM_V_CCAS)$(LTCCASCOMPILE) -c -o $@ $< - - mostlyclean-libtool: -*************** -*** 706,713 **** - mulredc1_20.asm: mulredc1.m4 - $(M4) -DLENGTH=20 $< > $@ - -! .asm.s: -! $(M4) -I../ -DOPERATION_$* `test -f $< || echo '$(srcdir)/'`$< >$*.s - # Nothing here needs the C preprocessor, and including this rule causes - # "make" to build .S, then .s files which fails on case-insensitive - # filesystems ---- 706,713 ---- - mulredc1_20.asm: mulredc1.m4 - $(M4) -DLENGTH=20 $< > $@ - -! .asm.sx: -! $(M4) -I../ -DOPERATION_$* `test -f $< || echo '$(srcdir)/'`$< >$*.sx - # Nothing here needs the C preprocessor, and including this rule causes - # "make" to build .S, then .s files which fails on case-insensitive - # filesystems From b8b7cbda24331d2b0df2f8faa295c84c922b20a0 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 27 Nov 2024 13:22:10 +0700 Subject: [PATCH 143/210] Some documentation clean-up --- src/sage/libs/eclib/interface.py | 37 +++++++++++-------- src/sage/libs/eclib/mwrank.pyx | 28 +++----------- src/sage/modules/free_module_element.pyx | 2 +- .../elliptic_curves/ell_rational_field.py | 19 +++------- 4 files changed, 34 insertions(+), 52 deletions(-) diff --git a/src/sage/libs/eclib/interface.py b/src/sage/libs/eclib/interface.py index a5e65a37d4d..ded015e5c7c 100644 --- a/src/sage/libs/eclib/interface.py +++ b/src/sage/libs/eclib/interface.py @@ -267,21 +267,28 @@ def two_descent(self, verbose=True, selmer_only=False, first_limit=20, - ``selmer_only`` -- boolean (default: ``False``); ``selmer_only`` switch - - ``first_limit`` -- integer (default: 20); bound on `|x|+|z|` in - quartic point search - - - ``second_limit`` -- integer (default: 8); bound on - `\log \max(|x|,|z|)`, i.e. logarithmic - - - ``n_aux`` -- integer (default: -1); (only relevant for general - 2-descent when 2-torsion trivial) number of primes used for - quartic search. ``n_aux=-1`` causes default (8) to be used. - Increase for curves of higher rank. - - - ``second_descent`` -- boolean (default: ``True``); (only relevant - for curves with 2-torsion, where mwrank uses descent via - 2-isogeny) flag determining whether or not to do second - descent. *Default strongly recommended.* + - ``first_limit`` -- integer (default: 20); naive height bound on + first point search on quartic homogeneous spaces (before + testing local solubility; very simple search with no + overheads). + + - ``second_limit`` -- integer (default: 8); naive height bound on + second point search on quartic homogeneous spaces (after + testing local solubility; sieve-assisted search) + + - ``n_aux`` -- integer (default: -1); if positive, the number of + auxiliary primes used in sieve-assisted search for quartics. + If -1 (the default) use a default value (set in the eclib + code in ``src/qrank/mrank1.cc`` in DEFAULT_NAUX: currently 8). + Only relevant for curves with no 2-torsion, where full + 2-descent is carried out. Worth increasing for curves + expected to be of rank > 6 to one or two more than the + expected rank. + + - ``second_descent`` -- boolean (default: ``True``); flag specifying + whether or not a second descent will be carried out. Only relevant + for curves with 2-torsion. Recommended left as the default except for + experts interested in details of Selmer groups. OUTPUT: nothing diff --git a/src/sage/libs/eclib/mwrank.pyx b/src/sage/libs/eclib/mwrank.pyx index 5bc54a04cdc..4a2ca04e55f 100644 --- a/src/sage/libs/eclib/mwrank.pyx +++ b/src/sage/libs/eclib/mwrank.pyx @@ -992,29 +992,11 @@ cdef class _two_descent: points. Useful as a faster way of getting an upper bound on the rank. - - ``firstlim`` -- integer (default: 20); naive height bound on - first point search on quartic homogeneous spaces (before - testing local solubility; very simple search with no - overheads). - - - ``secondlim`` -- integer (default: 8); naive height bound on - second point search on quartic homogeneous spaces (after - testing local solubility; sieve-assisted search) - - - ``n_aux`` -- integer (default: -1); if positive, the number of - auxiliary primes used in sieve-assisted search for quartics. - If -1 (the default) use a default value (set in the eclib - code in ``src/qrank/mrank1.cc`` in DEFAULT_NAUX: currently 8). - Only relevant for curves with no 2-torsion, where full - 2-descent is carried out. Worth increasing for curves - expected to be of rank > 6 to one or two more than the - expected rank. - - - ``second_descent`` -- integer (default: 1); flag specifying - whether or not a second descent will be carried out (yes if - 1, the default; no if 0). Only relevant for curves with - 2-torsion. Recommended left as the default except for - experts interested in details of Selmer groups. + - ``firstlim``, ``secondlim``, ``n_aux``, ``second_descent`` -- + see ``first_limit``, ``second_limit``, ``n_aux``, ``second_descent`` + respectively in :meth:`~sage.libs.eclib.interface.mwrank_EllipticCurve.two_descent` + (although ``second_descent`` here is ``1`` or ``0`` instead of ``True`` or ``False`` + respectively) OUTPUT: none diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index f840143a073..7578dc4c645 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -4047,7 +4047,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Differentiate with respect to var by differentiating each element with respect to var. - .. seealso: + .. SEEALSO:: :meth:`derivative` diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 2f2868d37ca..639519a2ed5 100755 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -808,16 +808,8 @@ def two_descent(self, verbose=True, - ``selmer_only`` -- boolean (default: ``False``); selmer_only switch - - ``first_limit`` -- (default: 20) firstlim is bound - on x+z second_limit- (default: 8) secondlim is bound on log max - x,z , i.e. logarithmic - - - ``n_aux`` -- (default: -1) n_aux only relevant for - general 2-descent when 2-torsion trivial; n_aux=-1 causes default - to be used (depends on method) - - - ``second_descent`` -- (default: ``True``) - second_descent only relevant for descent via 2-isogeny + - ``first_limit``, ``second_limit``, ``n_aux``, ``second_descent`` -- + see :meth:`~sage.libs.eclib.interface.mwrank_EllipticCurve.two_descent` OUTPUT: @@ -2256,9 +2248,9 @@ def gens(self, proof=None, **kwds): - ``algorithm`` -- one of the following: - - ``'mwrank_shell'`` -- default; call mwrank shell command + - ``'mwrank_lib'`` -- default; call mwrank C library - - ``'mwrank_lib'`` -- call mwrank C library + - ``'mwrank_shell'`` -- call mwrank shell command - ``'pari'`` -- use ellrank in pari @@ -2268,7 +2260,8 @@ def gens(self, proof=None, **kwds): - ``use_database`` -- boolean (default: ``True``); if ``True``, attempts to find curve and gens in the (optional) database - - ``descent_second_limit`` -- (default: 12) used in 2-descent + - ``descent_second_limit`` -- (default: 12) used in 2-descent. See ``second_limit`` + in :meth:`~sage.libs.eclib.interface.mwrank_EllipticCurve.two_descent` - ``sat_bound`` -- (default: 1000) bound on primes used in saturation. If the computed bound on the index of the From 4b5992ebc623e87dc651ae36bf7497062e0b5684 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 27 Nov 2024 14:49:07 +0100 Subject: [PATCH 144/210] provide default argument for monomial_coefficients --- src/sage/algebras/commutative_dga.py | 4 ++-- src/sage/algebras/splitting_algebra.py | 4 ++-- src/sage/categories/modules_with_basis.py | 4 ++++ src/sage/rings/derivation.py | 2 +- src/sage/rings/multi_power_series_ring_element.py | 2 +- src/sage/rings/polynomial/multi_polynomial_element.py | 2 +- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 2 +- src/sage/rings/polynomial/polynomial_element.pyx | 2 +- src/sage/rings/power_series_pari.pyx | 2 +- src/sage/rings/power_series_poly.pyx | 4 ++-- 10 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index fdcaeedaad8..7dadae0de4d 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -1559,7 +1559,7 @@ def homogeneous_parts(self): res[deg] = term return {i: res[i] for i in sorted(res.keys())} - def monomial_coefficients(self): + def monomial_coefficients(self, copy=True): r""" A dictionary that determines the element. @@ -1578,7 +1578,7 @@ def monomial_coefficients(self): sage: sorted(elt.dict().items()) [((0, 1, 1, 0), -5), ((1, 1, 0, 0), 1), ((1, 2, 3, 1), 7)] """ - return self.lift().monomial_coefficients() + return self.lift().monomial_coefficients(copy=copy) dict = monomial_coefficients diff --git a/src/sage/algebras/splitting_algebra.py b/src/sage/algebras/splitting_algebra.py index 43d72ed7470..14ceda36556 100644 --- a/src/sage/algebras/splitting_algebra.py +++ b/src/sage/algebras/splitting_algebra.py @@ -102,7 +102,7 @@ def is_unit(self): return super().is_unit() - def monomial_coefficients(self): + def monomial_coefficients(self, copy=True): r""" Return the dictionary of ``self`` according to its lift to the cover. @@ -119,7 +119,7 @@ def monomial_coefficients(self): sage: f.dict() {0: 42, 1: 1} """ - return self.lift().monomial_coefficients() + return self.lift().monomial_coefficients(copy=copy) dict = monomial_coefficients diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py index 489f2f97dbb..0fab5826239 100644 --- a/src/sage/categories/modules_with_basis.py +++ b/src/sage/categories/modules_with_basis.py @@ -1919,6 +1919,10 @@ def leading_coefficient(self, *args, **kwds): sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules sage: f.leading_coefficient() # needs sage.combinat sage.modules -5 + + sage: P. = QQ[] + sage: (3*x^2*y + y^2*x).leading_coefficient() + 3 """ return self.leading_item(*args, **kwds)[1] diff --git a/src/sage/rings/derivation.py b/src/sage/rings/derivation.py index b824e16e0d1..a1f80611473 100644 --- a/src/sage/rings/derivation.py +++ b/src/sage/rings/derivation.py @@ -996,7 +996,7 @@ def list(self): parent = self.parent() return [self(x) for x in parent.dual_basis()] - def monomial_coefficients(self): + def monomial_coefficients(self, copy=None): r""" Return dictionary of nonzero coordinates (on the canonical basis) of this derivation. diff --git a/src/sage/rings/multi_power_series_ring_element.py b/src/sage/rings/multi_power_series_ring_element.py index 9c27ba678bb..046f8338e05 100644 --- a/src/sage/rings/multi_power_series_ring_element.py +++ b/src/sage/rings/multi_power_series_ring_element.py @@ -1099,7 +1099,7 @@ def __mod__(self, other): return self.change_ring(Zmod(other)) raise NotImplementedError("Mod on multivariate power series ring elements not defined except modulo an integer.") - def monomial_coefficients(self): + def monomial_coefficients(self, copy=None): """ Return underlying dictionary with keys the exponents and values the coefficients of this power series. diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 3e00ef62991..a22330ef4b8 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -802,7 +802,7 @@ def monomial_coefficient(self, mon): zero = self.parent().base_ring().zero() return self.element().get(exp, zero) - def monomial_coefficients(self): + def monomial_coefficients(self, copy=None): """ Return underlying dictionary with keys the exponents and values the coefficients of this polynomial. diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 72b4aea43ce..9c940755987 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -2997,7 +2997,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): return self._parent._base._zero_element - def monomial_coefficients(self): + def monomial_coefficients(self, copy=None): """ Return a dictionary representing ``self``. This dictionary is in the same format as the generic MPolynomial: The dictionary diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index feb0ef1b03b..5196651d041 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -4461,7 +4461,7 @@ cdef class Polynomial(CommutativePolynomial): if self.get_unsafe(n) else zero for n in range(self.degree() + 1)] return S(p) - def monomial_coefficients(self): + def monomial_coefficients(self, copy=None): """ Return a sparse dictionary representation of this univariate polynomial. diff --git a/src/sage/rings/power_series_pari.pyx b/src/sage/rings/power_series_pari.pyx index 8f7ff769dd1..baeef616e02 100644 --- a/src/sage/rings/power_series_pari.pyx +++ b/src/sage/rings/power_series_pari.pyx @@ -734,7 +734,7 @@ cdef class PowerSeries_pari(PowerSeries): else: return [R(g)] + [R.zero()] * (n - 1) - def monomial_coefficients(self): + def monomial_coefficients(self, copy=None): """ Return a dictionary of coefficients for ``self``. diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index 39b05cce069..8b7bcf04dad 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -794,7 +794,7 @@ cdef class PowerSeries_poly(PowerSeries): """ return self.__f.list() - def monomial_coefficients(self): + def monomial_coefficients(self, copy=True): """ Return a dictionary of coefficients for ``self``. @@ -814,7 +814,7 @@ cdef class PowerSeries_poly(PowerSeries): sage: f.dict() {0: 1, 10: 1} """ - return self.__f.monomial_coefficients() + return self.__f.monomial_coefficients(coyp=copy) dict = monomial_coefficients From 4f0410c0aefb787bfd58cadec5bdb9e826c9d9db Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 27 Nov 2024 16:22:52 +0100 Subject: [PATCH 145/210] fix typo --- src/sage/rings/power_series_poly.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index 8b7bcf04dad..c284b06a5e4 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -814,7 +814,7 @@ cdef class PowerSeries_poly(PowerSeries): sage: f.dict() {0: 1, 10: 1} """ - return self.__f.monomial_coefficients(coyp=copy) + return self.__f.monomial_coefficients(copy=copy) dict = monomial_coefficients From 72ae2bcac84e5a49124224cf11425c1b8ae11097 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 27 Nov 2024 17:36:45 +0100 Subject: [PATCH 146/210] add support for term orders and doctests --- src/sage/categories/modules_with_basis.py | 96 ++++++++++++++++++- .../rings/polynomial/multi_polynomial.pyx | 52 +++++++++- 2 files changed, 145 insertions(+), 3 deletions(-) diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py index 0fab5826239..cda4ecdca68 100644 --- a/src/sage/categories/modules_with_basis.py +++ b/src/sage/categories/modules_with_basis.py @@ -1860,6 +1860,18 @@ def leading_item(self, *args, **kwds): sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules sage: f.leading_item() # needs sage.combinat sage.modules ([3], -5) + + The term ordering of polynomial rings is taken into account:: + + sage: R. = QQ[] + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_item() + ((0, 4, 0), 1) + sage: R. = PolynomialRing(QQ, order='lex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_item() + ((1, 2, 0), 3) + sage: R. = PolynomialRing(QQ, order='invlex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_item() + ((0, 1, 3), 2) """ k = self.leading_support(*args, **kwds) return k, self[k] @@ -1890,6 +1902,18 @@ def leading_monomial(self, *args, **kwds): sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules sage: f.leading_monomial() # needs sage.combinat sage.modules s[3] + + The term ordering of polynomial rings is taken into account:: + + sage: R. = QQ[] + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_monomial() + y^4 + sage: R. = PolynomialRing(QQ, order='lex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_monomial() + x*y^2 + sage: R. = PolynomialRing(QQ, order='invlex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_monomial() + y*z^3 """ return self.parent().monomial(self.leading_support(*args, **kwds)) @@ -1920,9 +1944,17 @@ def leading_coefficient(self, *args, **kwds): sage: f.leading_coefficient() # needs sage.combinat sage.modules -5 - sage: P. = QQ[] - sage: (3*x^2*y + y^2*x).leading_coefficient() + The term ordering of polynomial rings is taken into account:: + + sage: R. = QQ[] + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_coefficient() + 1 + sage: R. = PolynomialRing(QQ, order='lex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_coefficient() 3 + sage: R. = PolynomialRing(QQ, order='invlex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_coefficient() + 2 """ return self.leading_item(*args, **kwds)[1] @@ -1952,6 +1984,18 @@ def leading_term(self, *args, **kwds): sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules sage: f.leading_term() # needs sage.combinat sage.modules -5*s[3] + + The term ordering of polynomial rings is taken into account:: + + sage: R. = QQ[] + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_term() + y^4 + sage: R. = PolynomialRing(QQ, order='lex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_term() + 3*x*y^2 + sage: R. = PolynomialRing(QQ, order='invlex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_term() + 2*y*z^3 """ return self.parent().term(*self.leading_item(*args, **kwds)) @@ -2009,6 +2053,18 @@ def trailing_item(self, *args, **kwds): sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules sage: f.trailing_item() # needs sage.combinat sage.modules ([1], 2) + + The term ordering of polynomial rings is taken into account:: + + sage: R. = QQ[] + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_item() + ((1, 1, 1), 4) + sage: R. = PolynomialRing(QQ, order='lex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_item() + ((0, 1, 3), 2) + sage: R. = PolynomialRing(QQ, order='invlex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_item() + ((1, 2, 0), 3) """ k = self.trailing_support(*args, **kwds) return k, self[k] @@ -2039,6 +2095,18 @@ def trailing_monomial(self, *args, **kwds): sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules sage: f.trailing_monomial() # needs sage.combinat sage.modules s[1] + + The term ordering of polynomial rings is taken into account:: + + sage: R. = QQ[] + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_monomial() + x*y*z + sage: R. = PolynomialRing(QQ, order='lex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_monomial() + y*z^3 + sage: R. = PolynomialRing(QQ, order='invlex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_monomial() + x*y^2 """ return self.parent().monomial(self.trailing_support(*args, **kwds)) @@ -2068,6 +2136,18 @@ def trailing_coefficient(self, *args, **kwds): sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules sage: f.trailing_coefficient() # needs sage.combinat sage.modules 2 + + The term ordering of polynomial rings is taken into account:: + + sage: R. = QQ[] + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_coefficient() + 4 + sage: R. = PolynomialRing(QQ, order='lex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_coefficient() + 2 + sage: R. = PolynomialRing(QQ, order='invlex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_coefficient() + 3 """ return self.trailing_item(*args, **kwds)[1] @@ -2097,6 +2177,18 @@ def trailing_term(self, *args, **kwds): sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules sage: f.trailing_term() # needs sage.combinat sage.modules 2*s[1] + + The term ordering of polynomial rings is taken into account:: + + sage: R. = QQ[] + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_term() + 4*x*y*z + sage: R. = PolynomialRing(QQ, order='lex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_term() + 2*y*z^3 + sage: R. = PolynomialRing(QQ, order='invlex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_term() + 3*x*y^2 """ return self.parent().term(*self.trailing_item(*args, **kwds)) diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index 1b54a1fd0aa..222e76d4bec 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -208,8 +208,58 @@ cdef class MPolynomial(CommutativePolynomial): return R(self.polynomial(self._parent(var))) return R([self]) - def coefficients(self): + def leading_support(self, *args, **kwds): + r""" + Return the maximal element of the support of ``self``, + according to the term order. + + If the term ordering of the basis elements is not what is + desired, a comparison key, ``key(x)``, can be provided. + + EXAMPLES:: + + sage: R. = PolynomialRing(QQ) + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_support() + (0, 4, 0) + sage: R. = PolynomialRing(QQ, order='lex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_support() + (1, 2, 0) + sage: R. = PolynomialRing(QQ, order='invlex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_support() + (0, 1, 3) + """ + if 'key' in kwds: + return max(self.support(), *args, **kwds) + kwds['key'] = self._parent.term_order().sortkey + return max(self.support(), *args, **kwds) + + def trailing_support(self, *args, **kwds): r""" + Return the minimal element of the support of ``self``, + according to the term order. + + If the term ordering of the basis elements is not what is + desired, a comparison key, ``key(x)``, can be provided. + + EXAMPLES:: + + sage: R. = PolynomialRing(QQ) + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_support() + (1, 1, 1) + sage: R. = PolynomialRing(QQ, order='lex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_support() + (0, 1, 3) + sage: R. = PolynomialRing(QQ, order='invlex') + sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_support() + (1, 2, 0) + """ + if 'key' in kwds: + return min(self.support(), *args, **kwds) + kwds['key'] = self._parent.term_order().sortkey + return min(self.support(), *args, **kwds) + + def coefficients(self): + """ Return the nonzero coefficients of this polynomial in a list. The returned list is decreasingly ordered by the term ordering From 6689899cafcf553c6321648ffc632067322db8a8 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 27 Nov 2024 19:14:38 +0100 Subject: [PATCH 147/210] add forgotten optional argument --- src/sage/rings/polynomial/polynomial_element_generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index 7bbd4e611a9..db8139bddad 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -128,7 +128,7 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): if check: self.__normalize() - def monomial_coefficients(self): + def monomial_coefficients(self, copy=None): """ Return a new copy of the dict of the underlying elements of ``self``. From e7abaf6ef2cad05904e8c02460c1f2b74a6cc082 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 27 Nov 2024 19:55:23 +0100 Subject: [PATCH 148/210] fix a few pycodestyle issues --- .../rings/polynomial/multi_polynomial.pyx | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index 222e76d4bec..0e25b72dbb9 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -259,7 +259,7 @@ cdef class MPolynomial(CommutativePolynomial): return min(self.support(), *args, **kwds) def coefficients(self): - """ + r""" Return the nonzero coefficients of this polynomial in a list. The returned list is decreasingly ordered by the term ordering @@ -479,7 +479,7 @@ cdef class MPolynomial(CommutativePolynomial): for e, val in self.monomial_coefficients().items() if not e[ind]} v = [B(w)] # coefficients that don't involve var z = var - for i in range(1,d+1): + for i in range(1, d+1): c = self.coefficient(z).monomial_coefficients() w = {remove_from_tuple(e, ind): val for e, val in c.items()} v.append(B(w)) @@ -537,7 +537,7 @@ cdef class MPolynomial(CommutativePolynomial): elif my_vars[-1] not in vars: x = base_ring(self) if base_ring is not None else self const_ix = ETuple((0,)*len(vars)) - return { const_ix: x } + return {const_ix: x} elif not set(my_vars).issubset(set(vars)): # we need to split it up p = self.polynomial(self._parent.gen(len(my_vars)-1)) @@ -819,7 +819,7 @@ cdef class MPolynomial(CommutativePolynomial): subclasses. """ M = self.monomials() - if M==[]: + if M == []: return True d = M.pop().degree() for m in M: @@ -1149,14 +1149,14 @@ cdef class MPolynomial(CommutativePolynomial): g = R.gen_names() v = [] for m, c in zip(self.monomials(), self.coefficients()): - v.append('(%s)*%s'%( c._magma_init_(magma), - m._repr_with_changed_varnames(g))) + v.append('(%s)*%s' % (c._magma_init_(magma), + m._repr_with_changed_varnames(g))) if len(v) == 0: s = '0' else: s = '+'.join(v) - return '%s!(%s)'%(R.name(), s) + return '%s!(%s)' % (R.name(), s) def _giac_init_(self): r""" @@ -1233,7 +1233,7 @@ cdef class MPolynomial(CommutativePolynomial): """ from sage.geometry.polyhedron.constructor import Polyhedron e = self.exponents() - P = Polyhedron(vertices = e, base_ring=ZZ) + P = Polyhedron(vertices=e, base_ring=ZZ) return P def __iter__(self): @@ -1449,7 +1449,7 @@ cdef class MPolynomial(CommutativePolynomial): raise TypeError("k must be a finite field") p = k.characteristic() e = k.degree() - v = [self] + [self.map_coefficients(k.hom([k.gen()**(p**i)])) for i in range(1,e)] + v = [self] + [self.map_coefficients(k.hom([k.gen()**(p**i)])) for i in range(1, e)] return prod(v).change_ring(k.prime_subfield()) def sylvester_matrix(self, right, variable=None): @@ -1904,7 +1904,7 @@ cdef class MPolynomial(CommutativePolynomial): for y in x: d = d.lcm(y.denominator()) return d - except(AttributeError): + except AttributeError: return self.base_ring().one() def numerator(self): @@ -2025,7 +2025,7 @@ cdef class MPolynomial(CommutativePolynomial): ArithmeticError: element is non-invertible """ P = self.parent() - B = I.gens() + B = I.gens() try: XY = P.one().lift((self,) + tuple(B)) return P(XY[0]) @@ -2111,7 +2111,7 @@ cdef class MPolynomial(CommutativePolynomial): #Corner case, note that the degree of zero is an Integer return Integer(-1) - if len(weights) == 1: + if len(weights) == 1: # First unwrap it if it is given as one element argument weights = weights[0] @@ -2132,9 +2132,9 @@ cdef class MPolynomial(CommutativePolynomial): for i in range(n): l += weights[i]*m[i] deg = l - for j in range(1,len(A)): + for j in range(1, len(A)): l = Integer(0) - m = A[j] + m = A[j] for i in range(n): l += weights[i]*m[i] if deg < l: @@ -2560,12 +2560,12 @@ cdef class MPolynomial(CommutativePolynomial): from sage.rings.real_mpfr import RealField if self.parent().ngens() != 2: - raise ValueError("(=%s) must have two variables"%self) + raise ValueError("(=%s) must have two variables" % self) if not self.is_homogeneous(): - raise ValueError("(=%s) must be homogeneous"%self) + raise ValueError("(=%s) must be homogeneous" % self) prec = kwds.get('prec', 300) - return_conjugation =kwds.get('return_conjugation', True) + return_conjugation = kwds.get('return_conjugation', True) error_limit = kwds.get('error_limit', 0.000001) emb = kwds.get('emb', None) @@ -2573,14 +2573,14 @@ cdef class MPolynomial(CommutativePolynomial): CF = ComplexIntervalField(prec=prec) # keeps trac of our precision error RF = RealField(prec=prec) R = self.parent() - x,y = R.gens() + x, y = R.gens() # finding quadratic Q_0, gives us our covariant, z_0 from sage.rings.polynomial.binary_form_reduce import covariant_z0 try: z, th = covariant_z0(self, prec=prec, emb=emb, z0_cov=True) except ValueError:# multiple roots - F = self.lc()*prod([p for p,e in self.factor()]) + F = self.lc()*prod([p for p, e in self.factor()]) z, th = covariant_z0(F, prec=prec, emb=emb, z0_cov=True) z = CF(z) # this moves z_0 to our fundamental domain using the three steps laid @@ -2594,11 +2594,11 @@ cdef class MPolynomial(CommutativePolynomial): # moves z into fundamental domain by m m = zc.real().round() # finds amount to move z's real part by Qm = QQ(m) - M = M * matrix(QQ, [[1,Qm], [0,1]]) # move + M = M * matrix(QQ, [[1, Qm], [0, 1]]) # move z -= m # M.inverse()*z is supposed to move z by m elif (zc.real() <= RF(0) and zc.abs() < RF(1)) or (zc.real() > RF(0) and zc.abs() <= RF(1)): # flips z z = -1/z - M = M * matrix(QQ, [[0,-1], [1,0]])# multiply on left because we are taking inverse matrices + M = M * matrix(QQ, [[0, -1], [1, 0]])# multiply on left because we are taking inverse matrices zc = z.center() smallest_coeffs = kwds.get('smallest_coeffs', True) From 25be314496a6f8c784f15761cb933cb25484f6c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 27 Nov 2024 19:59:18 +0100 Subject: [PATCH 149/210] pep8 cleanup in libs --- src/sage/libs/coxeter3/coxeter_group.py | 17 +++--- src/sage/libs/eclib/interface.py | 19 ++++--- src/sage/libs/gap/gap_globals.py | 62 +++++++++++----------- src/sage/libs/gap/test_long.py | 2 +- src/sage/libs/giac/__init__.py | 6 +-- src/sage/libs/pari/__init__.py | 5 +- src/sage/libs/singular/standard_options.py | 2 +- 7 files changed, 60 insertions(+), 53 deletions(-) diff --git a/src/sage/libs/coxeter3/coxeter_group.py b/src/sage/libs/coxeter3/coxeter_group.py index 845feb2fd38..858a0f24d6e 100644 --- a/src/sage/libs/coxeter3/coxeter_group.py +++ b/src/sage/libs/coxeter3/coxeter_group.py @@ -279,7 +279,7 @@ def m(self, i, j): """ from sage.misc.superseded import deprecation deprecation(30237, "the .m(i, j) method has been deprecated; use .coxeter_matrix()[i,j] instead.") - return self.coxeter_matrix()[i,j] + return self.coxeter_matrix()[i, j] def kazhdan_lusztig_polynomial(self, u, v, constant_term_one=True): r""" @@ -354,8 +354,9 @@ def kazhdan_lusztig_polynomial(self, u, v, constant_term_one=True): return p ZZq = PolynomialRing(ZZ, 'q', sparse=True) # This is the same as q**len_diff * p(q**(-2)) - len_diff = v.length()-u.length() - d = {-2*deg+len_diff: coeff for deg,coeff in enumerate(p) if coeff != 0} + len_diff = v.length() - u.length() + d = {-2 * deg + len_diff: coeff for deg, coeff in enumerate(p) + if coeff != 0} return ZZq(d) def parabolic_kazhdan_lusztig_polynomial(self, u, v, J, constant_term_one=True): @@ -414,11 +415,11 @@ def parabolic_kazhdan_lusztig_polynomial(self, u, v, J, constant_term_one=True): WOI = self.weak_order_ideal(lambda x: J_set.issuperset(x.descents())) if constant_term_one: P = PolynomialRing(ZZ, 'q') - return P.sum((-1)**(z.length()) * self.kazhdan_lusztig_polynomial(u*z,v) - for z in WOI if (u*z).bruhat_le(v)) + return P.sum((-1)**(z.length()) * self.kazhdan_lusztig_polynomial(u * z, v) + for z in WOI if (u * z).bruhat_le(v)) P = PolynomialRing(ZZ, 'q', sparse=True) - return P.sum((-1)**(z.length()) * self.kazhdan_lusztig_polynomial(u*z,v, constant_term_one=False).shift(z.length()) - for z in WOI if (u*z).bruhat_le(v)) + return P.sum((-1)**(z.length()) * self.kazhdan_lusztig_polynomial(u * z, v, constant_term_one=False).shift(z.length()) + for z in WOI if (u * z).bruhat_le(v)) class Element(ElementWrapper): wrapped_class = CoxGroupElement @@ -701,7 +702,7 @@ def action_on_rational_function(self, f): for exponent in exponents: # Construct something in the root lattice from the exponent vector - exponent = sum(e*b for e, b in zip(exponent, basis_elements)) + exponent = sum(e * b for e, b in zip(exponent, basis_elements)) exponent = self.action(exponent) monomial = 1 diff --git a/src/sage/libs/eclib/interface.py b/src/sage/libs/eclib/interface.py index a5e65a37d4d..34db6fe2504 100644 --- a/src/sage/libs/eclib/interface.py +++ b/src/sage/libs/eclib/interface.py @@ -246,8 +246,11 @@ def __repr__(self): """ a1, a2, a3, a4, a6 = self.__ainvs # we do not assume a1, a2, a3 are reduced to {0,1}, {-1,0,1}, {0,1} - coeff = lambda a: ''.join([" +" if a > 0 else " -", - " " + str(abs(a)) if abs(a) > 1 else ""]) + + def coeff(a): + return ''.join([" +" if a > 0 else " -", + " " + str(abs(a)) if abs(a) > 1 else ""]) + return ''.join(['y^2', ' '.join([coeff(a1), 'xy']) if a1 else '', ' '.join([coeff(a3), 'y']) if a3 else '', @@ -606,12 +609,14 @@ def certain(self): """ return bool(self.__two_descent_data().getcertain()) - #def fullmw(self): - # return self.__two_descent_data().getfullmw() + # def fullmw(self): + # return self.__two_descent_data().getfullmw() def CPS_height_bound(self): r""" - Return the Cremona-Prickett-Siksek height bound. This is a + Return the Cremona-Prickett-Siksek height bound. + + This is a floating point number `B` such that if `P` is a point on the curve, then the naive logarithmic height `h(P)` is less than `B+\hat{h}(P)`, where `\hat{h}(P)` is the canonical height of @@ -1282,9 +1287,9 @@ def search(self, height_limit=18, verbose=False): """ height_limit = float(height_limit) int_bits = sys.maxsize.bit_length() - max_height_limit = int_bits * 0.693147 # log(2.0) = 0.693147 approx + max_height_limit = int_bits * 0.693147 # log(2.0) = 0.693147 approx if height_limit >= max_height_limit: - raise ValueError("The height limit must be < {} = {}log(2) on a {}-bit machine.".format(max_height_limit, int_bits, int_bits+1)) + raise ValueError("The height limit must be < {} = {}log(2) on a {}-bit machine.".format(max_height_limit, int_bits, int_bits + 1)) moduli_option = 0 # Use Stoll's sieving program... see strategies in ratpoints-1.4.c diff --git a/src/sage/libs/gap/gap_globals.py b/src/sage/libs/gap/gap_globals.py index 4c3e6eb3aae..f8061a173a2 100644 --- a/src/sage/libs/gap/gap_globals.py +++ b/src/sage/libs/gap/gap_globals.py @@ -15,34 +15,34 @@ # selected gap globals to use in tab completion -common_gap_globals = set([ - 'Assert', - 'Cyclotomics', - 'GaussianIntegers', - 'GaussianRationals', - 'GlobalMersenneTwister', - 'GlobalRandomSource', - 'InfoAlgebra', - 'InfoAttributes', - 'InfoBckt', - 'InfoCharacterTable', - 'InfoCoh', - 'InfoComplement', - 'InfoCoset', - 'InfoFpGroup', - 'InfoGroebner', - 'InfoGroup', - 'InfoLattice', - 'InfoMatrix', - 'InfoMonomial', - 'InfoNumtheor', - 'InfoOptions', - 'InfoPackageLoading', - 'InfoPcSubgroup', - 'InfoWarning', - 'Integers', - 'NiceBasisFiltersInfo', - 'Primes', - 'Rationals', - 'TableOfMarksComponents' -]) | common_gap_functions +common_gap_globals = { + 'Assert', + 'Cyclotomics', + 'GaussianIntegers', + 'GaussianRationals', + 'GlobalMersenneTwister', + 'GlobalRandomSource', + 'InfoAlgebra', + 'InfoAttributes', + 'InfoBckt', + 'InfoCharacterTable', + 'InfoCoh', + 'InfoComplement', + 'InfoCoset', + 'InfoFpGroup', + 'InfoGroebner', + 'InfoGroup', + 'InfoLattice', + 'InfoMatrix', + 'InfoMonomial', + 'InfoNumtheor', + 'InfoOptions', + 'InfoPackageLoading', + 'InfoPcSubgroup', + 'InfoWarning', + 'Integers', + 'NiceBasisFiltersInfo', + 'Primes', + 'Rationals', + 'TableOfMarksComponents' +} | common_gap_functions diff --git a/src/sage/libs/gap/test_long.py b/src/sage/libs/gap/test_long.py index c92ff9d5223..262f3b00e28 100644 --- a/src/sage/libs/gap/test_long.py +++ b/src/sage/libs/gap/test_long.py @@ -28,7 +28,7 @@ def test_loop_2(): G = libgap.FreeGroup(2) a, b = G.GeneratorsOfGroup() for i in range(100): - rel = libgap([a**2, b**2, a*b*a*b]) + rel = libgap([a**2, b**2, a * b * a * b]) H = G / rel H1 = H.GeneratorsOfGroup()[0] n = H1.Order() diff --git a/src/sage/libs/giac/__init__.py b/src/sage/libs/giac/__init__.py index ba0be068152..49bbe254947 100644 --- a/src/sage/libs/giac/__init__.py +++ b/src/sage/libs/giac/__init__.py @@ -287,7 +287,7 @@ def groebner_basis(gens, proba_epsilon=None, threads=None, prot=False, return PolynomialSequence([P(0)], P, immutable=True) # check for name confusions - blackgiacconstants = ['i', 'e'] # NB e^k is expanded to exp(k) + blackgiacconstants = ['i', 'e'] # NB e^k is expanded to exp(k) blacklist = blackgiacconstants + [str(j) for j in libgiac.VARS()] problematicnames = sorted(set(P.gens_dict()).intersection(blacklist)) @@ -336,8 +336,8 @@ def groebner_basis(gens, proba_epsilon=None, threads=None, prot=False, var_names = var_names[:len(blocks[0])] else: raise NotImplementedError( - "%s is not a supported term order in " - "Giac Groebner bases." % P.term_order()) + "%s is not a supported term order in " + "Giac Groebner bases." % P.term_order()) # compute de groebner basis with giac gb_giac = F.gbasis(list(var_names), giac_order) diff --git a/src/sage/libs/pari/__init__.py b/src/sage/libs/pari/__init__.py index ccb18792918..b5bc281db4d 100644 --- a/src/sage/libs/pari/__init__.py +++ b/src/sage/libs/pari/__init__.py @@ -173,6 +173,7 @@ 3.60546360143265208591582056420772677481026899659802474544 # 32-bit """ + def _get_pari_instance(): """ TESTS:: @@ -181,8 +182,8 @@ def _get_pari_instance(): Interface to the PARI C library """ from cypari2 import Pari - stack_initial = 1024*1024 - stack_max = 1024*stack_initial + stack_initial = 1024 * 1024 + stack_max = 1024 * stack_initial P = Pari(stack_initial, stack_max) # pari_init_opts() overrides MPIR's memory allocation functions, diff --git a/src/sage/libs/singular/standard_options.py b/src/sage/libs/singular/standard_options.py index 476961b2f09..38d41585ee9 100644 --- a/src/sage/libs/singular/standard_options.py +++ b/src/sage/libs/singular/standard_options.py @@ -95,7 +95,7 @@ def __exit__(self, typ, value, tb): b - 3*d^6 + 2*d^4 + d^3 + 2*d^2 - 3*d, a - 2*d^6 + d^5 - 2*d^4 + 3*d^3 + 3*d^2 - 2*d - 1] """ - self.libsingular_option_context.__exit__(typ,value,tb) + self.libsingular_option_context.__exit__(typ, value, tb) def libsingular_gb_standard_options(func): r""" From fe38d3b4bcef92747c41d9558b155993fdc0fe6c Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 28 Nov 2024 13:11:09 +0900 Subject: [PATCH 150/210] Fixing typo with g_i^-1 implementation in Yokonuma-Hecke algebras. --- src/sage/algebras/yokonuma_hecke_algebra.py | 25 ++++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/sage/algebras/yokonuma_hecke_algebra.py b/src/sage/algebras/yokonuma_hecke_algebra.py index 7de8ff07798..f8e8f724adc 100644 --- a/src/sage/algebras/yokonuma_hecke_algebra.py +++ b/src/sage/algebras/yokonuma_hecke_algebra.py @@ -447,13 +447,17 @@ def inverse_g(self, i): sage: Y = algebras.YokonumaHecke(2, 4) sage: [2*Y.inverse_g(i) for i in range(1, 4)] - [(q^-1+q) + 2*g[1] + (q^-1+q)*t1*t2, - (q^-1+q) + 2*g[2] + (q^-1+q)*t2*t3, - (q^-1+q) + 2*g[3] + (q^-1+q)*t3*t4] + [(q^-1-q) + 2*g[1] + (q^-1-q)*t1*t2, + (q^-1-q) + 2*g[2] + (q^-1-q)*t2*t3, + (q^-1-q) + 2*g[3] + (q^-1-q)*t3*t4] + sage: all(Y.inverse_g(i) * Y.g(i) == Y.one() for i in range(1, 4)) + True + sage: all(Y.g(i) * Y.inverse_g(i) == Y.one() for i in range(1, 4)) + True """ if i < 1 or i >= self._n: raise ValueError("invalid index") - return self.g(i) + (~self._q + self._q) * self.e(i) + return self.g(i) + (~self._q - self._q) * self.e(i) class Element(CombinatorialFreeModule.Element): def __invert__(self): @@ -468,10 +472,15 @@ def __invert__(self): sage: t.inverse() # indirect doctest t1^2*t2^2*t3^2 sage: [3*~(t*g) for g in Y.g()] - [(q^-1+q)*t2*t3^2 + (q^-1+q)*t1*t3^2 - + (q^-1+q)*t1^2*t2^2*t3^2 + 3*t1^2*t2^2*t3^2*g[1], - (q^-1+q)*t1^2*t3 + (q^-1+q)*t1^2*t2 - + (q^-1+q)*t1^2*t2^2*t3^2 + 3*t1^2*t2^2*t3^2*g[2]] + [(q^-1-q)*t2*t3^2 + (q^-1-q)*t1*t3^2 + + (q^-1-q)*t1^2*t2^2*t3^2 + 3*t1^2*t2^2*t3^2*g[1], + (q^-1-q)*t1^2*t3 + (q^-1-q)*t1^2*t2 + + (q^-1-q)*t1^2*t2^2*t3^2 + 3*t1^2*t2^2*t3^2*g[2]] + sage: g = prod(Y.g()) + sage: ~g * g == Y.one() + True + sage: g * ~g == Y.one() + True TESTS: From 3ca55fefb6d4ad58e2912354b1d130a932d8892f Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 28 Nov 2024 14:15:01 +0700 Subject: [PATCH 151/210] Fix exactify caching when interrupted --- src/sage/rings/qqbar.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 72df892337b..3806663eaf0 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -7098,12 +7098,26 @@ def exactify(self): sage: cp.exactify() sage: cp._exact True + + TESTS: + + Check that interrupting ``exactify()`` does not lead to incoherent state:: + + sage: x = polygen(AA) + sage: p = AA(2)^(1/100) * x + AA(3)^(1/100) + sage: cp = AA.common_polynomial(p) + sage: alarm(0.5); cp.generator() + Traceback (most recent call last): + ... + AlarmInterrupt + sage: alarm(0.5); cp.generator() + Traceback (most recent call last): + ... + AlarmInterrupt """ if self._exact: return - self._exact = True - if self._poly.base_ring() is QQ: self._factors = [fac_exp[0] for fac_exp in self._poly.factor()] self._gen = qq_generator @@ -7128,6 +7142,8 @@ def exactify(self): self._factors = [fac_exp[0] for fac_exp in fp.factor()] + self._exact = True + def factors(self): r""" EXAMPLES:: From 079fc8c944fdc2191a24155d99cea368ec717a5e Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Wed, 14 Aug 2024 09:51:30 +0900 Subject: [PATCH 152/210] Adding a hash to affine group elements and making sure the elements are immutable. --- src/sage/groups/affine_gps/group_element.py | 56 ++++++++++++++++++--- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/src/sage/groups/affine_gps/group_element.py b/src/sage/groups/affine_gps/group_element.py index b1e3cd1e0cb..7bd4ecc15d1 100644 --- a/src/sage/groups/affine_gps/group_element.py +++ b/src/sage/groups/affine_gps/group_element.py @@ -119,15 +119,17 @@ def __init__(self, parent, A, b=0, convert=True, check=True): A = A.matrix() except AttributeError: pass - if isinstance(A, Matrix) and A.nrows() == A.ncols() == parent.degree()+1: + if isinstance(A, Matrix) and A.nrows() == A.ncols() == parent.degree() + 1: g = A d = parent.degree() A = g.submatrix(0, 0, d, d) - b = [ g[i,d] for i in range(d) ] + b = [g[i,d] for i in range(d)] convert = True if convert: A = parent.matrix_space()(A) b = parent.vector_space()(b) + A.set_immutable() + b.set_immutable() if check: # Note: the coercion framework expects that we raise TypeError for invalid input if not isinstance(A, Matrix): @@ -138,6 +140,14 @@ def __init__(self, parent, A, b=0, convert=True, check=True): raise TypeError('b must be an element of ' + str(parent.vector_space())) parent._element_constructor_check(A, b) super().__init__(parent) + if not A.is_immutable(): + from copy import copy + A = copy(A) + A.set_immutable() + if not b.is_immutable(): + from copy import copy + b = copy(b) + b.set_immutable() self._A = A self._b = b @@ -151,10 +161,12 @@ def A(self): sage: G = AffineGroup(3, QQ) sage: g = G([1,2,3,4,5,6,7,8,0], [10,11,12]) - sage: g.A() + sage: A = g.A(); A [1 2 3] [4 5 6] [7 8 0] + sage: A.is_immutable() + True """ return self._A @@ -168,8 +180,10 @@ def b(self): sage: G = AffineGroup(3, QQ) sage: g = G([1,2,3,4,5,6,7,8,0], [10,11,12]) - sage: g.b() + sage: b = g.b(); b (10, 11, 12) + sage: b.is_immutable() + True """ return self._b @@ -345,7 +359,9 @@ def _mul_(self, other): parent = self.parent() A = self._A * other._A b = self._b + self._A * other._b - return parent.element_class(parent, A, b, check=False) + A.set_immutable() + b.set_immutable() + return parent.element_class(parent, A, b, convert=False, check=False) def __call__(self, v): """ @@ -439,13 +455,14 @@ def _act_on_(self, x, self_on_left): x |-> [0 1] x + [0] sage: v = vector(GF(3), [1,-1]); v (1, 2) - sage: g*v + sage: g * v (1, 2) - sage: g*v == g.A() * v + g.b() + sage: g * v == g.A() * v + g.b() True """ if self_on_left: return self(x) + return None def __invert__(self): """ @@ -472,7 +489,9 @@ def __invert__(self): parent = self.parent() A = parent.matrix_space()(~self._A) b = -A * self.b() - return parent.element_class(parent, A, b, check=False) + A.set_immutable() + b.set_immutable() + return parent.element_class(parent, A, b, convert=False, check=False) def _richcmp_(self, other, op): """ @@ -497,6 +516,27 @@ def _richcmp_(self, other, op): return richcmp(self._b, other._b, op) + def __hash__(self): + """ + Return the hash of ``self``. + + OUTPUT: int + + EXAMPLES:: + + sage: F = AffineGroup(3, QQ) + sage: g = F([1,2,3,4,5,6,7,8,0], [10,11,12]) + sage: h = F([1,2,3,4,5,6,7,8,0], [10,11,0]) + sage: hash(g) == hash(h) + False + sage: hash(g) == hash(copy(g)) + True + sage: f = g * h + sage: hash(f) == hash((f.A(), f.b())) + True + """ + return hash((self._A, self._b)) + def list(self): """ Return list representation of ``self``. From c018e295eed98837117dec81b5afda68c4ea7dd4 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 20 Aug 2024 14:36:33 +0900 Subject: [PATCH 153/210] Moving the copy import. --- src/sage/groups/affine_gps/group_element.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/groups/affine_gps/group_element.py b/src/sage/groups/affine_gps/group_element.py index 7bd4ecc15d1..0bbede1b025 100644 --- a/src/sage/groups/affine_gps/group_element.py +++ b/src/sage/groups/affine_gps/group_element.py @@ -45,6 +45,7 @@ from sage.structure.element import MultiplicativeGroupElement from sage.structure.richcmp import richcmp, richcmp_not_equal +from copy import copy class AffineGroupElement(MultiplicativeGroupElement): r""" @@ -141,11 +142,9 @@ def __init__(self, parent, A, b=0, convert=True, check=True): parent._element_constructor_check(A, b) super().__init__(parent) if not A.is_immutable(): - from copy import copy A = copy(A) A.set_immutable() if not b.is_immutable(): - from copy import copy b = copy(b) b.set_immutable() self._A = A From f3ec5b3ff97d615b9e83e0c4ff678f667db9dc75 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 28 Nov 2024 18:00:03 +0900 Subject: [PATCH 154/210] Addressing reviewer comments. --- src/sage/groups/affine_gps/group_element.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/groups/affine_gps/group_element.py b/src/sage/groups/affine_gps/group_element.py index 0bbede1b025..a3b856a05d5 100644 --- a/src/sage/groups/affine_gps/group_element.py +++ b/src/sage/groups/affine_gps/group_element.py @@ -40,13 +40,13 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +from copy import copy + from sage.structure.element import Matrix from sage.misc.cachefunc import cached_method from sage.structure.element import MultiplicativeGroupElement from sage.structure.richcmp import richcmp, richcmp_not_equal -from copy import copy - class AffineGroupElement(MultiplicativeGroupElement): r""" An affine group element. @@ -531,8 +531,8 @@ def __hash__(self): sage: hash(g) == hash(copy(g)) True sage: f = g * h - sage: hash(f) == hash((f.A(), f.b())) - True + sage: hash(f) == hash(~f) + False """ return hash((self._A, self._b)) From f1c6b07aa9b926cb22cc14901f8581c48444b5a6 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 28 Nov 2024 16:27:11 +0700 Subject: [PATCH 155/210] More copy paste, apply changes --- src/sage/libs/eclib/interface.py | 2 +- .../elliptic_curves/ell_rational_field.py | 29 +++++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/sage/libs/eclib/interface.py b/src/sage/libs/eclib/interface.py index ded015e5c7c..59c3c8b78d8 100644 --- a/src/sage/libs/eclib/interface.py +++ b/src/sage/libs/eclib/interface.py @@ -272,7 +272,7 @@ def two_descent(self, verbose=True, selmer_only=False, first_limit=20, testing local solubility; very simple search with no overheads). - - ``second_limit`` -- integer (default: 8); naive height bound on + - ``second_limit`` -- integer (default: 8); logarithmic height bound on second point search on quartic homogeneous spaces (after testing local solubility; sieve-assisted search) diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 639519a2ed5..134531ad1a5 100755 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -808,8 +808,28 @@ def two_descent(self, verbose=True, - ``selmer_only`` -- boolean (default: ``False``); selmer_only switch - - ``first_limit``, ``second_limit``, ``n_aux``, ``second_descent`` -- - see :meth:`~sage.libs.eclib.interface.mwrank_EllipticCurve.two_descent` + - ``first_limit`` -- integer (default: 20); naive height bound on + first point search on quartic homogeneous spaces (before + testing local solubility; very simple search with no + overheads). + + - ``second_limit`` -- integer (default: 8); logarithmic height bound on + second point search on quartic homogeneous spaces (after + testing local solubility; sieve-assisted search) + + - ``n_aux`` -- integer (default: -1); if positive, the number of + auxiliary primes used in sieve-assisted search for quartics. + If -1 (the default) use a default value (set in the eclib + code in ``src/qrank/mrank1.cc`` in DEFAULT_NAUX: currently 8). + Only relevant for curves with no 2-torsion, where full + 2-descent is carried out. Worth increasing for curves + expected to be of rank > 6 to one or two more than the + expected rank. + + - ``second_descent`` -- boolean (default: ``True``); flag specifying + whether or not a second descent will be carried out. Only relevant + for curves with 2-torsion. Recommended left as the default except for + experts interested in details of Selmer groups. OUTPUT: @@ -2260,7 +2280,10 @@ def gens(self, proof=None, **kwds): - ``use_database`` -- boolean (default: ``True``); if ``True``, attempts to find curve and gens in the (optional) database - - ``descent_second_limit`` -- (default: 12) used in 2-descent. See ``second_limit`` + - ``descent_second_limit`` -- (default: 12); logarithmic height bound on + second point search on quartic homogeneous spaces (after + testing local solubility; sieve-assisted search). Used in 2-descent. + See also ``second_limit`` in :meth:`~sage.libs.eclib.interface.mwrank_EllipticCurve.two_descent` - ``sat_bound`` -- (default: 1000) bound on primes used in From 0e3ed643a65ae1964c2d3c4ca1151f3b42518756 Mon Sep 17 00:00:00 2001 From: Soham Rane Date: Thu, 28 Nov 2024 15:01:34 +0530 Subject: [PATCH 156/210] Update changelog_trigger.yml: removed unnecessary secret 'CHANGELOG_TRIGGER_SECRET' --- .github/workflows/changelog_trigger.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/changelog_trigger.yml b/.github/workflows/changelog_trigger.yml index 374a002c4f9..71e8aec9ae1 100644 --- a/.github/workflows/changelog_trigger.yml +++ b/.github/workflows/changelog_trigger.yml @@ -11,7 +11,6 @@ jobs: - name: Trigger Workflow in website repo env: GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} - TRIGGER_SECRET: ${{ secrets.CHANGELOG_TRIGGER_SECRET }} RELEASE_TAG: ${{ github.event.release.tag_name }} run: | curl -L \ @@ -20,4 +19,4 @@ jobs: -H "Authorization: Bearer $GH_TOKEN" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/repos/sagemath/website/actions/workflows/generate_changelog.yml/dispatches \ - -d '{"ref":"master","inputs":{"release_tag":"'"$RELEASE_TAG"'","trigger_secret":"'"$TRIGGER_SECRET"'"}}' + -d '{"ref":"master","inputs":{"release_tag":"'"$RELEASE_TAG"'"}}' From da1f749b0b0882e50ba20efd17740fad51d52c34 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 28 Nov 2024 16:33:08 +0700 Subject: [PATCH 157/210] Apply suggestion Co-authored-by: Travis Scrimshaw --- src/sage/modular/modform/element.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index 6768fbc1c03..8a9a6a955ce 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -265,6 +265,7 @@ def __call__(self, x, prec=None): sage: f(0) 0 + EXAMPLES: Evaluate numerically:: From b3fcaab9c66861403e4b4170f7ff9fc5eef3ad06 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 28 Nov 2024 16:43:58 +0700 Subject: [PATCH 158/210] Some minor changes --- src/sage/modular/modform/element.py | 50 ++++++++++++++++++----------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index 8a9a6a955ce..a9fde3f4139 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -265,16 +265,17 @@ def __call__(self, x, prec=None): sage: f(0) 0 + EXAMPLES: Evaluate numerically:: sage: f = ModularForms(1, 12).0 sage: f(0.3) # rel tol 1e-12 - 2.3452457654859093943911095448677943331e-6 + 2.34524576548591e-6 sage: f = EisensteinForms(1, 4).0 sage: f(0.9) # rel tol 1e-12 - 1.2647594220924141255379137476604196202e7 + 1.26475942209241e7 TESTS:: @@ -286,10 +287,10 @@ def __call__(self, x, prec=None): Higher precision:: - sage: f(ComplexField(1024)(0.3)) # rel tol 1e-300 - 0.299999997396191310292851660587501640585287966606926712372685051052183848485101271417891225951099656119402111562859500035032541015715233392211176407057239620967660312966086779337994327624536037187214146041831261633868799976346085552246983798477217725916938994733822571999849908529513379575860920140944745353698614348900664409173 - sage: f(ComplexField(1024)(1+2*I)/3) # rel tol 1e-300 - 0.321653845723568825567905326693899006909160675826045434571915911867833071589696569615194893689901721899490426373845744862497953969333193682758406183041097473225418603897622369265087989491842075279034290073993079800285909375526425931622610153626461152157393613063055863371355916362145445869467929251660349223775541765403069287756 + 0.670612446383675863028207907112577773897857202143717552376205630684889727243085419317012486309756101468259545944957593645365938699136657674117927754488042563377649540662343013944001734211314704342435690945950614217421684269575557390763317106676805075226392963322227027538349081598725382171963223815408532667527371217267163311545*I + sage: f(ComplexField(128)(0.3)) # rel tol 1e-36 + 0.29999999739619131029285166058750164058 + sage: f(ComplexField(128)(1+2*I)/3) # rel tol 1e-36 + 0.32165384572356882556790532669389900691 + 0.67061244638367586302820790711257777390*I Confirm numerical evaluation matches the q-expansion:: @@ -303,21 +304,21 @@ def __call__(self, x, prec=None): sage: M = ModularForms(DirichletGroup(17).0^2, 2) sage: M.0(0.5) # rel tol 1e-12 - 0.166916655031616406 + 0.0111529051752428267*I - sage: M.0.qexp(50).polynomial()(0.5) # rel tol 1e-12 - 0.166916655031612 + 0.0111529051752446*I + 0.166916655031616 + 0.0111529051752428*I + sage: M.0.qexp(60).polynomial()(0.5) # rel tol 1e-12 + 0.166916655031616 + 0.0111529051752428*I Higher precision:: - sage: f(ComplexField(1024)(1+2*I)/3) # rel tol 1e-300 - 429.199948322062942786880853990563596327120079065066254109432103144473221199829480785902664748868493907769441449473555229387561526629665655661427945472113572803307694967838236473063580602746440482717293005228669958745844625512025507948139637569777953993158796185335086681612581007434046175713336414282554064647719988594288913120 - 786.157362841882433511538308248529749947718853411006076221833170249528876337224355907958857459245137532046109965098912535988424738933052981899295555982842062176345159766720738928291892050139943952864992573038108609831401219671626805315734950245686731132797235451098295774853868203027469066869512246697946206845252244686704009880*I - sage: f.qexp(3000).polynomial()(ComplexField(1024)(1+2*I)/3) # rel tol 1e-300 - 429.1999483220629427868808539905635963271200790650662541094321031444732211998294807859026647488684939077694414494735552293875615266296656556614279454721135728033076949678382364730635806027464404827172930052286699587458446255120255079481396375697779539931587961853350866816125810074340461757133364142825540647 - 786.1573628418824335115383082485297499477188534110060762218331702495288763372243559079588574592451375320461099650989125359884247389330529818992955559828420621763451597667207389282918920501399439528649925730381086098314012196716268053157349502456867311327972354510982957748538682030274690668695122466979462069*I + sage: f(ComplexField(128)(1+2*I)/3) # rel tol 1e-36 + 429.19994832206294278688085399056359632 - 786.15736284188243351153830824852974995*I + sage: f.qexp(400).polynomial()(ComplexField(128)(1+2*I)/3) # rel tol 1e-36 + 429.19994832206294278688085399056359631 - 786.15736284188243351153830824852974999*I Check ``SR`` does not make the result lose precision:: - sage: f(ComplexField(1024)(1+2*I)/3 + x - x) # rel tol 1e-300 - 429.199948322062942786880853990563596327120079065066254109432103144473221199829480785902664748868493907769441449473555229387561526629665655661427945472113572803307694967838236473063580602746440482717293005228669958745844625512025507948139637569777953993158796185335086681612581007434046175713336414282554064647719988594288913120 - 786.157362841882433511538308248529749947718853411006076221833170249528876337224355907958857459245137532046109965098912535988424738933052981899295555982842062176345159766720738928291892050139943952864992573038108609831401219671626805315734950245686731132797235451098295774853868203027469066869512246697946206845252244686704009880*I + sage: f(ComplexField(128)(1+2*I)/3 + x - x) # rel tol 1e-36 + 429.19994832206294278688085399056359632 - 786.15736284188243351153830824852974995*I """ from sage.rings.integer import Integer from sage.misc.functional import log @@ -347,17 +348,23 @@ def eval_at_tau(self, tau): Evaluate this modular form at the half-period ratio `\tau`. This is related to `q` by `q = e^{2\pi i \tau}`. + EXAMPLES:: + + sage: f = ModularForms(1, 12).0 + sage: f.eval_at_tau(0.3 * I) # rel tol 1e-12 + 0.00150904633897550 + TESTS: Check ``SR`` does not make the result lose precision:: sage: f = EisensteinForms(1, 4).0 - sage: f.eval_at_tau(ComplexField(1024)(1+2*I)/3 + x - x) # rel tol 1e-300 - -1.04515705822020600561978783142860369660026850501222224469267227428610961984014327083815700740447933744582038996915609186529679911598578009500436771124828467825291523495268250908979376807788900006209591385867335039616941215684551066086395842278498086825793727621839992525301493298760414972421090964300343066954661155411439536627 + 2.72251120985198030982039335832865902741427458369769410157055618486577347595364447691251370354689965324163927321325893070988471497088161774220563106128912211718551704485285953814944589707973769813648021661388772620343922776832791016518443400344473023932887976990908175600815202111437107948718799541078554987252368104803278882956*I + sage: f.eval_at_tau(ComplexField(128)(1+2*I)/3 + x - x) # rel tol 1e-36 + -1.0451570582202060056197878314286036966 + 2.7225112098519803098203933583286590274*I """ from sage.libs.pari.convert_sage import gen_to_sage from sage.libs.pari import pari - from sage.rings.complex_mpfr import ComplexNumber + from sage.rings.complex_mpfr import ComplexNumber, ComplexField from sage.rings.real_mpfr import RealNumber from sage.symbolic.expression import Expression if isinstance(tau, Expression): @@ -369,7 +376,12 @@ def eval_at_tau(self, tau): precision = tau.prec() else: precision = 53 - return gen_to_sage(pari(self.parent()).mfeval(self, tau, precision=precision)) + result = gen_to_sage(pari(self.parent()).mfeval(self, tau, precision=precision)) + if isinstance(tau, (float, complex)): + result = complex(result) + elif isinstance(tau, (RealNumber, ComplexNumber)): + result = ComplexField(precision)(result) + return result @cached_method def valuation(self): From 65ffb0ca9d33e115f14380d91e482fd324f44b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 28 Nov 2024 10:45:39 +0100 Subject: [PATCH 159/210] fix : no Alphabet --- src/sage/algebras/free_algebra.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 30941a0ef26..3b56a949f4c 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -168,7 +168,6 @@ IdentityConstructionFunctor) from sage.categories.rings import Rings from sage.combinat.free_module import CombinatorialFreeModule -from sage.combinat.words.alphabet import Alphabet from sage.combinat.words.word import Word from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import lazy_import @@ -1637,7 +1636,7 @@ def merge(self, other): cur_vars = set(ret) ret.extend(v for v in other.vars if v not in cur_vars) # degrees are ignored for the moment ; TODO - return AssociativeFunctor(Alphabet(ret)) + return AssociativeFunctor(tuple(ret)) return None From b10beaebe2bbead97aaca9551f5f7a232a492f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 28 Nov 2024 10:57:56 +0100 Subject: [PATCH 160/210] fix minor details --- src/sage/groups/affine_gps/group_element.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/groups/affine_gps/group_element.py b/src/sage/groups/affine_gps/group_element.py index a3b856a05d5..190a0180d1b 100644 --- a/src/sage/groups/affine_gps/group_element.py +++ b/src/sage/groups/affine_gps/group_element.py @@ -30,15 +30,15 @@ - Volker Braun """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013 Volker Braun # # 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 @@ -47,6 +47,7 @@ from sage.structure.element import MultiplicativeGroupElement from sage.structure.richcmp import richcmp, richcmp_not_equal + class AffineGroupElement(MultiplicativeGroupElement): r""" An affine group element. From a3ea98161e5cd31c0dc88aa18686aa8017d1a093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 28 Nov 2024 13:23:05 +0100 Subject: [PATCH 161/210] more robust substitution --- src/sage/combinat/triangles_FHM.py | 38 ++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/sage/combinat/triangles_FHM.py b/src/sage/combinat/triangles_FHM.py index cfd1d5f0f3c..9bd07daa5fe 100644 --- a/src/sage/combinat/triangles_FHM.py +++ b/src/sage/combinat/triangles_FHM.py @@ -427,7 +427,8 @@ def h(self): """ x, y = self._vars n = self._n - step = self._poly(x=y / (y - 1), y=(y - 1) * x / (1 + (y - 1) * x)) + step = self._poly.subs({x: y / (y - 1), + y: (y - 1) * x / (1 + (y - 1) * x)}) step *= (1 + (y - 1) * x)**n polyh = step.numerator() return H_triangle(polyh, variables=(x, y)) @@ -503,7 +504,8 @@ def m(self): """ x, y = self._vars n = self._n - step = self._poly(x=(x - 1) * y / (1 - y), y=x / (x - 1)) * (1 - y)**n + step = self._poly.subs({x: (x - 1) * y / (1 - y), + y: x / (x - 1)}) * (1 - y)**n polym = step.numerator() return M_triangle(polym, variables=(x, y)) @@ -536,8 +538,8 @@ def f(self): """ x, y = self._vars n = self._n - step1 = self._poly(x=x / (1 + x), y=y) * (x + 1)**n - step2 = step1(x=x, y=y / x) + step1 = self._poly.subs({x: x / (1 + x), y: y}) * (x + 1)**n + step2 = step1.subs({x: x, y: y / x}) polyf = step2.numerator() return F_triangle(polyf, variables=(x, y)) @@ -585,8 +587,9 @@ def vector(self): sage: H_triangle(ht).vector() x^2 + 3*x + 1 """ - anneau = PolynomialRing(ZZ, 'x') - return anneau(self._poly(y=1)) + x, y = self._vars + anneau = PolynomialRing(ZZ, "x") + return anneau(self._poly.subs({y: 1})) class F_triangle(Triangle): @@ -617,7 +620,8 @@ def h(self): """ x, y = self._vars n = self._n - step = (1 - x)**n * self._poly(x=x / (1 - x), y=x * y / (1 - x)) + step = (1 - x)**n * self._poly.subs({x: x / (1 - x), + y: x * y / (1 - x)}) polyh = step.numerator() return H_triangle(polyh, variables=(x, y)) @@ -662,7 +666,8 @@ def m(self): """ x, y = self._vars n = self._n - step = self._poly(x=y * (x - 1) / (1 - x * y), y=x * y / (1 - x * y)) + step = self._poly.subs({x: y * (x - 1) / (1 - x * y), + y: x * y / (1 - x * y)}) step *= (1 - x * y)**n polym = step.numerator() return M_triangle(polym, variables=(x, y)) @@ -681,9 +686,17 @@ def parabolic(self): F: x + y + 1 sage: _.parabolic() F: x + y + + TESTS:: + + sage: a, b = polygens(ZZ,'a,b') + sage: H_triangle(1+a*b).f() + F: a + b + 1 + sage: _.parabolic() + F: a + b """ x, y = self._vars - polyf = self._poly(y=y - 1) + polyf = self._poly.subs({y: y - 1}) return F_triangle(polyf, variables=(x, y)) def vector(self): @@ -700,9 +713,10 @@ def vector(self): sage: F_triangle(ft).vector() 5*x^2 + 5*x + 1 """ - anneau = PolynomialRing(ZZ, 'x') - x = anneau.gen() - return anneau(self._poly(y=x)) + x, y = self._vars + anneau = PolynomialRing(ZZ, "x") + nx = anneau.gen() + return anneau(self._poly.subs({x: nx, y: nx})) class Gamma_triangle(Triangle): From b44dee6c472aa2f2d3b9fc886bf7eb6f76d50d2d Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 28 Nov 2024 19:48:04 +0700 Subject: [PATCH 162/210] Revert spurious addition of EXAMPLES: --- src/sage/modular/modform/element.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index a9fde3f4139..0038534a2f2 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -266,8 +266,6 @@ def __call__(self, x, prec=None): sage: f(0) 0 - EXAMPLES: - Evaluate numerically:: sage: f = ModularForms(1, 12).0 From 680498918d37e6cd7ba8f2551d20cb344f82df0b Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 28 Nov 2024 20:08:27 +0700 Subject: [PATCH 163/210] More coverage and small behavior change --- src/sage/modular/modform/element.py | 48 +++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index 0038534a2f2..441812135b6 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -283,6 +283,25 @@ def __call__(self, x, prec=None): sage: f(0.0+0.0*I) 0 + For simplicity, ``float`` or ``complex`` input are converted to ``CC``, except for + input ``0`` where exact result is returned:: + + sage: result = f(0.3r); result # rel tol 1e-12 + 0.299999997396191 + sage: result.parent() + Complex Field with 53 bits of precision + sage: result = f(0.3r + 0.3jr); result # rel tol 1e-12 + 0.299999359878484 + 0.299999359878484*I + sage: result.parent() + Complex Field with 53 bits of precision + + Symbolic numerical values use precision of ``CC`` by default:: + + sage: f(sqrt(1/2)) # rel tol 1e-12 + 0.700041406692037 + sage: f(sqrt(1/2)*QQbar.zeta(8)) # rel tol 1e-12 + 0.496956554651376 + 0.496956554651376*I + Higher precision:: sage: f(ComplexField(128)(0.3)) # rel tol 1e-36 @@ -354,6 +373,20 @@ def eval_at_tau(self, tau): TESTS: + Symbolic numerical values use precision of ``CC`` by default:: + + sage: f.eval_at_tau(sqrt(1/5)*I) # rel tol 1e-12 + 0.0123633234207127 + sage: f.eval_at_tau(sqrt(1/2)*QQbar.zeta(8)) # rel tol 1e-12 + -0.114263670441098 + + For simplicity, ``complex`` input are converted to ``CC``:: + + sage: result = f.eval_at_tau(0.3jr); result # rel tol 1e-12 + 0.00150904633897550 + sage: result.parent() + Complex Field with 53 bits of precision + Check ``SR`` does not make the result lose precision:: sage: f = EisensteinForms(1, 4).0 @@ -362,6 +395,7 @@ def eval_at_tau(self, tau): """ from sage.libs.pari.convert_sage import gen_to_sage from sage.libs.pari import pari + from sage.rings.cc import CC from sage.rings.complex_mpfr import ComplexNumber, ComplexField from sage.rings.real_mpfr import RealNumber from sage.symbolic.expression import Expression @@ -370,16 +404,10 @@ def eval_at_tau(self, tau): tau = tau.pyobject() except TypeError: pass - if isinstance(tau, (RealNumber, ComplexNumber)): - precision = tau.prec() - else: - precision = 53 - result = gen_to_sage(pari(self.parent()).mfeval(self, tau, precision=precision)) - if isinstance(tau, (float, complex)): - result = complex(result) - elif isinstance(tau, (RealNumber, ComplexNumber)): - result = ComplexField(precision)(result) - return result + if not isinstance(tau, (RealNumber, ComplexNumber)): + tau = CC(tau) + precision = tau.prec() + return ComplexField(precision)(pari.mfeval(self.parent(), self, tau, precision=precision)) @cached_method def valuation(self): From 3fa12a6b1951a39a88f494d379617ac04fcce5a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 28 Nov 2024 14:24:46 +0100 Subject: [PATCH 164/210] handling the degrees in the merge --- src/sage/algebras/free_algebra.py | 49 ++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 3b56a949f4c..a18e15c1df6 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -1515,6 +1515,10 @@ def __init__(self, vars, degs=None): Free Algebra on 2 generators (x, y) over Integer Ring """ Functor.__init__(self, Rings(), Rings()) + if not isinstance(vars, (list, tuple)): + raise TypeError("vars must be a list or tuple") + if degs is not None and not isinstance(degs, (list, tuple, dict)): + raise TypeError("degs must be a list, tuple or dict") self.vars = vars self.degs = degs @@ -1613,6 +1617,16 @@ def merge(self, other): sage: F.merge(F) Associative[x,y] + With degrees:: + + sage: F = AssociativeFunctor(['x','y'], (2,3)) + sage: G = AssociativeFunctor(['t'], (4,)) + sage: H = AssociativeFunctor(['z','y'], (5,3)) + sage: F.merge(G) + Associative[x,y,t] with degrees (2, 3, 4) + sage: F.merge(H) + Associative[x,y,z] with degrees (2, 3, 5) + Now some actual use cases:: sage: R = algebras.Free(ZZ, 3, 'x,y,z') @@ -1628,15 +1642,42 @@ def merge(self, other): t + x sage: parent(x + t) Free Algebra on 4 generators (z, t, x, y) over Rational Field + + TESTS:: + + sage: F = AssociativeFunctor(['x','y'], (2,3)) + sage: H = AssociativeFunctor(['z','y'], (5,4)) + sage: F.merge(H) """ if isinstance(other, AssociativeFunctor): if self.vars == other.vars and self.degs == other.degs: return self + ret = list(self.vars) - cur_vars = set(ret) - ret.extend(v for v in other.vars if v not in cur_vars) - # degrees are ignored for the moment ; TODO - return AssociativeFunctor(tuple(ret)) + self_vars = set(ret) + ret.extend(v for v in other.vars if v not in self_vars) + + # first case: no degrees + if self.degs is None and other.degs is None: + return AssociativeFunctor(tuple(ret)) + + # second case: merge the degrees + if self.degs is None: + deg = [1] * len(self.vars) + else: + deg = list(self.degs) + if other.degs is None: + o_degs = [1] * len(other.vars) + else: + o_degs = list(other.degs) + self_table = {w: d for w, d in zip(self.vars, deg)} + for v, d in zip(other.vars, o_degs): + if v not in self_vars: + deg.append(d) + elif d != self_table[v]: + # incompatible degrees + return None + return AssociativeFunctor(tuple(ret), tuple(deg)) return None From ee6b71cd91bd2eeab3367fcfab4ce83fc730f034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 28 Nov 2024 15:39:29 +0100 Subject: [PATCH 165/210] manually adding meson (beurk) --- src/sage/rings/polynomial/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/rings/polynomial/meson.build b/src/sage/rings/polynomial/meson.build index 94a0a0c8b9a..cbd48976335 100644 --- a/src/sage/rings/polynomial/meson.build +++ b/src/sage/rings/polynomial/meson.build @@ -52,6 +52,7 @@ py.install_sources( 'polynomial_singular_interface.py', 'polynomial_zmod_flint.pxd', 'polynomial_zz_pex.pxd', + 'q_integer_valued_polynomials.py', 'real_roots.pxd', 'skew_polynomial_element.pxd', 'skew_polynomial_finite_field.pxd', From d754ceffcb5223e3d680b81e7e8a90a09982e2a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 28 Nov 2024 17:26:25 +0100 Subject: [PATCH 166/210] fix side-effects --- src/sage/algebras/lie_algebras/free_lie_algebra.py | 2 +- src/sage/structure/coerce.pyx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/algebras/lie_algebras/free_lie_algebra.py b/src/sage/algebras/lie_algebras/free_lie_algebra.py index f5217231263..e841be77a59 100644 --- a/src/sage/algebras/lie_algebras/free_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/free_lie_algebra.py @@ -202,7 +202,7 @@ def _construct_UEA(self): Free Algebra on 2 generators (x, y) over Rational Field sage: L. = LieAlgebra(QQ) sage: L._construct_UEA() - Free Algebra on 1 generators (x,) over Rational Field + Free Algebra on 1 generator (x,) over Rational Field """ return FreeAlgebra(self.base_ring(), len(self._names), self._names) diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index cc2f1124cb4..6861cfb5be3 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -1891,7 +1891,7 @@ cdef class CoercionModel: 1/2*x sage: cm.discover_action(F, ZZ, operator.truediv) Right inverse action by Rational Field on - Free Algebra on 1 generators (x,) over Rational Field + Free Algebra on 1 generator (x,) over Rational Field with precomposition on right by Natural morphism: From: Integer Ring To: Rational Field From 04bc0da08d8c573277061d544e275965b0ec80bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 28 Nov 2024 21:14:04 +0100 Subject: [PATCH 167/210] small-scale refresh for the sandpile file --- src/sage/sandpiles/sandpile.py | 304 ++++++++++++++++++--------------- 1 file changed, 170 insertions(+), 134 deletions(-) diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index 6fb9720b945..0ecca117630 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -318,7 +318,7 @@ # Copyright (C) 2011 David Perkinson # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ # **************************************************************************** from collections import Counter @@ -525,10 +525,10 @@ def __init__(self, g, sink=None): EXAMPLES: - Below, ``g`` represents a square with directed, multiple edges with three - vertices, ``a``, ``b``, ``c``, and ``d``. The vertex ``a`` has - outgoing edges to itself (weight 2), to vertex ``b`` (weight 1), and - vertex ``c`` (weight 3), for example. + Below, ``g`` represents a square with directed, multiple edges + with three vertices, ``a``, ``b``, ``c``, and ``d``. + The vertex ``a`` has outgoing edges to itself (weight 2), to + vertex ``b`` (weight 1), and vertex ``c`` (weight 3), for example. :: @@ -552,7 +552,9 @@ def __init__(self, g, sink=None): [-1 -2 3 0] [ 0 0 0 0] sage: s.dict() - {0: {1: 1, 2: 1, 3: 1}, 1: {0: 1, 1: 1, 2: 3}, 2: {0: 1, 1: 2, 2: 4}} + {0: {1: 1, 2: 1, 3: 1}, + 1: {0: 1, 1: 1, 2: 3}, + 2: {0: 1, 1: 2, 2: 4}} Sandpiles can be created from Graphs and DiGraphs. :: @@ -571,14 +573,16 @@ def __init__(self, g, sink=None): .. NOTE:: - Loops are allowed. There are four admissible input formats. Two of - these are dictionaries whose keys are the vertex names. In one, the - values are dictionaries with keys the names of vertices which are the - heads of outgoing edges and with values the weights of the edges. In - the other format, the values are lists of names of vertices which are - the heads of the outgoing edges, with weights determined by the number - of times a name of a vertex appears in the list. Both Graphs and - DiGraphs can also be used as inputs. + Loops are allowed. There are four admissible input + formats. Two of these are dictionaries whose keys are the + vertex names. In one, the values are dictionaries with + keys the names of vertices which are the heads of outgoing + edges and with values the weights of the edges. In the + other format, the values are lists of names of vertices + which are the heads of the outgoing edges, with weights + determined by the number of times a name of a vertex + appears in the list. Both Graphs and DiGraphs can also be + used as inputs. TESTS:: @@ -684,7 +688,7 @@ def __getattr__(self, name): elif name == '_in_degrees': self._set_in_degrees() return deepcopy(self.__dict__[name]) - elif name == '_burning_config' or name == '_burning_script': + elif name in ['_burning_config', '_burning_script']: self._set_burning_config() return deepcopy(self.__dict__[name]) elif name == '_identity': @@ -726,7 +730,7 @@ def __getattr__(self, name): elif name in ['_postulation', '_h_vector', '_hilbert_function']: self._set_hilbert_function() return deepcopy(self.__dict__[name]) - elif (name == '_ring' or name == '_unsaturated_ideal'): + elif name in ['_ring', '_unsaturated_ideal']: self._set_ring() return self.__dict__[name] elif name == '_ideal': @@ -762,7 +766,7 @@ def __str__(self) -> str: """ return self.name() - def _repr_(self): + def _repr_(self) -> str: r""" String representation of ``self``. @@ -803,7 +807,8 @@ def show3d(self, **kwds): INPUT: - - ``kwds`` -- (optional) arguments passed to the show method for Graph or DiGraph + - ``kwds`` -- (optional) arguments passed to the show method + for Graph or DiGraph EXAMPLES:: @@ -856,7 +861,9 @@ def sink(self): def laplacian(self): r""" - The Laplacian matrix of the graph. Its *rows* encode the vertex firing rules. + The Laplacian matrix of the graph. + + Its *rows* encode the vertex firing rules. OUTPUT: matrix @@ -1125,12 +1132,12 @@ def burning_config(self): nonnegative entries and such that every vertex has a path from some vertex in its support. The corresponding *burning script* gives the integer-linear combination needed to obtain the burning - configuration. So if `b` is the burning configuration, `\sigma` is its - script, and `\tilde{L}` is the reduced Laplacian, then `\sigma\cdot - \tilde{L} = b`. The *minimal burning configuration* is the one - with the minimal script (its components are no larger than the - components of any other script - for a burning configuration). + configuration. So if `b` is the burning configuration, `\sigma` + is its script, and `\tilde{L}` is the reduced Laplacian, + then `\sigma\cdot \tilde{L} = b`. The *minimal burning + configuration* is the one with the minimal script (its + components are no larger than the components of any other + script for a burning configuration). The following are equivalent for a configuration `c` with burning configuration `b` having script `\sigma`: @@ -1266,7 +1273,9 @@ def _set_identity(self): def identity(self, verbose=True): r""" - The identity configuration. If ``verbose`` is ``False``, the + The identity configuration. + + If ``verbose`` is ``False``, the configuration is converted to a list of integers. INPUT: @@ -1339,7 +1348,9 @@ def recurrents(self, verbose=True): sage: r = Sandpile(graphs.HouseXGraph(),0).recurrents() sage: r[:3] - [{1: 2, 2: 3, 3: 3, 4: 1}, {1: 1, 2: 3, 3: 3, 4: 0}, {1: 1, 2: 3, 3: 3, 4: 1}] + [{1: 2, 2: 3, 3: 3, 4: 1}, + {1: 1, 2: 3, 3: 3, 4: 0}, + {1: 1, 2: 3, 3: 3, 4: 1}] sage: sandpiles.Complete(4).recurrents(False) # needs sage.combinat [[2, 2, 2], [2, 2, 1], @@ -1395,7 +1406,9 @@ def superstables(self, verbose=True): sage: sp = Sandpile(graphs.HouseXGraph(),0).superstables() sage: sp[:3] - [{1: 0, 2: 0, 3: 0, 4: 0}, {1: 1, 2: 0, 3: 0, 4: 1}, {1: 1, 2: 0, 3: 0, 4: 0}] + [{1: 0, 2: 0, 3: 0, 4: 0}, + {1: 1, 2: 0, 3: 0, 4: 1}, + {1: 1, 2: 0, 3: 0, 4: 0}] sage: sandpiles.Complete(4).superstables(False) # needs sage.combinat [[0, 0, 0], [0, 0, 1], @@ -1437,9 +1450,11 @@ def _set_group_gens(self): self._group_gens = [SandpileConfig(self, [Integer(j) for j in F.column(i)]).equivalent_recurrent() for i in range(F.nrows()) if D[i][i] != 1] - def group_gens(self, verbose=True): + def group_gens(self, verbose=True) -> list: r""" - A minimal list of generators for the sandpile group. If ``verbose`` is ``False`` + A minimal list of generators for the sandpile group. + + If ``verbose`` is ``False`` then the generators are represented as lists of integers. INPUT: @@ -1448,7 +1463,8 @@ def group_gens(self, verbose=True): OUTPUT: - list of SandpileConfig (or of lists of integers if ``verbose`` is ``False``) + list of SandpileConfig + (or of lists of integers if ``verbose`` is ``False``) EXAMPLES:: @@ -1683,7 +1699,7 @@ def avalanche_polynomial(self, multivariable=True): return self._avalanche_polynomial.subs({X[i]: X[0] for i in range(1, self.num_verts() - 1)}) - def nonspecial_divisors(self, verbose=True): + def nonspecial_divisors(self, verbose=True) -> list: r""" The nonspecial divisors. Only for undirected graphs. (See NOTE.) @@ -1708,11 +1724,12 @@ def nonspecial_divisors(self, verbose=True): .. NOTE:: - The "nonspecial divisors" are those divisors of degree `g-1` with - empty linear system. The term is only defined for undirected graphs. - Here, `g = |E| - |V| + 1` is the genus of the graph (not counting loops - as part of `|E|`). If ``verbose`` is ``False``, the divisors are converted - to lists of integers. + The "nonspecial divisors" are those divisors of degree + `g-1` with empty linear system. The term is only defined + for undirected graphs. Here, `g = |E| - |V| + 1` is the + genus of the graph (not counting loops as part of `|E|`). + If ``verbose`` is ``False``, the divisors are converted to + lists of integers. .. WARNING:: @@ -1750,7 +1767,8 @@ def canonical_divisor(self): The underlying graph must be undirected. """ if self.is_undirected(): - return SandpileDivisor(self, [self.laplacian()[i][i] - 2 for i in range(self.num_verts())]) + return SandpileDivisor(self, [self.laplacian()[i][i] - 2 + for i in range(self.num_verts())]) raise TypeError("only for undirected graphs") def _set_invariant_factors(self): @@ -1868,7 +1886,7 @@ def _set_smith_form(self): """ self._smith_form = self.laplacian().transpose().smith_form() - def smith_form(self): + def smith_form(self) -> list: r""" The Smith normal form for the Laplacian. In detail: a list of integer matrices `D, U, V` such that `ULV = D` where `L` is the transpose of the @@ -2011,8 +2029,8 @@ def jacobian_representatives(self, verbose=True): .. NOTE:: - The Jacobian group is the set of all divisors of degree zero modulo the - integer rowspan of the Laplacian matrix. + The Jacobian group is the set of all divisors of degree + zero modulo the integer rowspan of the Laplacian matrix. """ if verbose: return deepcopy(self._jacobian_representatives) @@ -2021,8 +2039,9 @@ def jacobian_representatives(self, verbose=True): def picard_representatives(self, d, verbose=True): r""" - Representatives of the divisor classes of degree `d` in the Picard group. (Also - see the documentation for ``jacobian_representatives``.) + Representatives of the divisor classes of degree `d` in the Picard group. + + (Also see the documentation for ``jacobian_representatives``.) INPUT: @@ -2051,10 +2070,12 @@ def picard_representatives(self, d, verbose=True): def stable_configs(self, smax=None): r""" - Generator for all stable configurations. If ``smax`` is provided, then - the generator gives all stable configurations less than or equal to - ``smax``. If ``smax`` does not represent a stable configuration, then each - component of ``smax`` is replaced by the corresponding component of the + Generator for all stable configurations. + + If ``smax`` is provided, then the generator gives all stable + configurations less than or equal to ``smax``. If ``smax`` + does not represent a stable configuration, then each component + of ``smax`` is replaced by the corresponding component of the maximal stable configuration. INPUT: @@ -2080,7 +2101,8 @@ def stable_configs(self, smax=None): else: c = SandpileConfig(self, smax) if not c <= self.max_stable(): - smax = [min(c[v], self.max_stable()[v]) for v in self.nonsink_vertices()] + smax = [min(c[v], self.max_stable()[v]) + for v in self.nonsink_vertices()] else: smax = c.values() for c in IntegerVectorsIterator(smax): @@ -2145,20 +2167,25 @@ def markov_chain(self, state, distrib=None): .. NOTE:: - The ``closed sandpile Markov chain`` has state space consisting of the configurations - on a sandpile. It transitions from a state by choosing a vertex at random - (according to the probability distribution ``distrib``), dropping a grain of sand at - that vertex, and stabilizing. If the chosen vertex is the sink, the chain stays - at the current state. - - The ``open sandpile Markov chain`` has state space consisting of the recurrent elements, - i.e., the state space is the sandpile group. It transitions from the configuration `c` - by choosing a vertex `v` at random according to ``distrib``. The next state is the - stabilization of `c+v`. If `v` is the sink vertex, then the stabilization of `c+v` - is defined to be `c`. - - Note that in either case, if ``distrib`` is specified, its length is equal to - the total number of vertices (including the sink). + The ``closed sandpile Markov chain`` has state space + consisting of the configurations on a sandpile. It + transitions from a state by choosing a vertex at random + (according to the probability distribution ``distrib``), + dropping a grain of sand at that vertex, and stabilizing. + If the chosen vertex is the sink, the chain stays at the + current state. + + The ``open sandpile Markov chain`` has state space + consisting of the recurrent elements, i.e., the state + space is the sandpile group. It transitions from the + configuration `c` by choosing a vertex `v` at random + according to ``distrib``. The next state is the + stabilization of `c+v`. If `v` is the sink vertex, then + the stabilization of `c+v` is defined to be `c`. + + Note that in either case, if ``distrib`` is specified, its + length is equal to the total number of vertices (including + the sink). REFERENCES: @@ -2248,9 +2275,9 @@ def stationary_density(self): .. NOTE:: - The stationary density of a sandpile is the sum `\sum_c (\deg(c) + \deg(s))` - where `\deg(s)` is the degree of the sink and the sum is over all - recurrent configurations. + The stationary density of a sandpile is the sum `\sum_c + (\deg(c) + \deg(s))` where `\deg(s)` is the degree of the + sink and the sum is over all recurrent configurations. REFERENCES: @@ -2308,16 +2335,17 @@ def _set_betti_complexes(self): r = self.recurrents() for D in r: d = D.deg() - # change D to a dict since SandpileConfig will not allow adding a key - D = dict(D) - D[self.sink()] = -d - D = SandpileDivisor(self, D) + # change D to a dict since SandpileConfig will not allow + # adding a key + dD = dict(D) + dD[self.sink()] = -d + sD = SandpileDivisor(self, dD) test = True while test: - D[self.sink()] += 1 - complex = D.Dcomplex() + sD[self.sink()] += 1 + complex = sD.Dcomplex() if sum(complex.betti().values()) > 1: # change from 0 to 1 - results.append([deepcopy(D), complex]) + results.append([deepcopy(sD), complex]) if len(complex.maximal_faces()) == 1 and list(complex.maximal_faces()[0]) == verts: test = False self._betti_complexes = results @@ -2529,9 +2557,10 @@ def _set_resolution(self): def resolution(self, verbose=False): r""" - A minimal free resolution of the homogeneous toppling ideal. If - ``verbose`` is ``True``, then all of the mappings are returned. - Otherwise, the resolution is summarized. + A minimal free resolution of the homogeneous toppling ideal. + + If ``verbose`` is ``True``, then all of the mappings are + returned. Otherwise, the resolution is summarized. INPUT: @@ -2756,8 +2785,9 @@ def symmetric_recurrents(self, orbits): .. NOTE:: - The user is responsible for ensuring that the list of orbits comes from - a group of symmetries of the underlying graph. + The user is responsible for ensuring that the list of + orbits comes from a group of symmetries of the underlying + graph. """ sym_recurrents = [] active = [self._max_stable] @@ -2784,7 +2814,9 @@ class SandpileConfig(dict): @staticmethod def help(verbose=True): r""" - List of SandpileConfig methods. If ``verbose``, include short descriptions. + List of SandpileConfig methods. + + If ``verbose``, include short descriptions. INPUT: @@ -2920,8 +2952,9 @@ def __setitem__(self, key, item): .. NOTE:: - In the example, above, changing the value of ``c`` at some vertex makes - a call to setitem, which resets some of the stored variables for ``c``. + In the example, above, changing the value of ``c`` at some + vertex makes a call to setitem, which resets some of the + stored variables for ``c``. """ if key in self: dict.__setitem__(self, key, item) @@ -3086,7 +3119,8 @@ def __neg__(self): sage: -c {1: -1, 2: -2} """ - return SandpileConfig(self._sandpile, [-self[v] for v in self._vertices]) + return SandpileConfig(self._sandpile, + [-self[v] for v in self._vertices]) # recurrent addition or multiplication on the right by an integer def __mul__(self, other): @@ -3123,7 +3157,8 @@ def __mul__(self, other): if isinstance(other, SandpileConfig): return (self+other).equivalent_recurrent() if isinstance(other, Integer): - return SandpileConfig(self.sandpile(), [other*i for i in self.values()]) + return SandpileConfig(self.sandpile(), + [other*i for i in self.values()]) raise TypeError(other) def __rmul__(self, other): @@ -3149,7 +3184,7 @@ def __rmul__(self, other): """ return SandpileConfig(self.sandpile(), [other*i for i in self.values()]) - def __le__(self, other): + def __le__(self, other) -> bool: r""" Return ``True`` if every component of ``self`` is at most that of ``other``. @@ -3179,7 +3214,7 @@ def __le__(self, other): """ return all(self[v] <= other[v] for v in self._vertices) - def __lt__(self, other): + def __lt__(self, other) -> bool: r""" Return ``True`` if every component of ``self`` is at most that of ``other`` and the two configurations are not equal. @@ -3204,7 +3239,7 @@ def __lt__(self, other): """ return self <= other and self != other - def __ge__(self, other): + def __ge__(self, other) -> bool: r""" Return ``True`` if every component of ``self`` is at least that of ``other``. @@ -3234,7 +3269,7 @@ def __ge__(self, other): """ return all(self[v] >= other[v] for v in self._vertices) - def __gt__(self, other): + def __gt__(self, other) -> bool: r""" Return ``True`` if every component of ``self`` is at least that of ``other`` and the two configurations are not equal. @@ -3352,8 +3387,6 @@ def values(self): OUTPUT: list of integers - boolean - EXAMPLES:: sage: S = Sandpile({'a':['c','b'], 'b':['c','a'], 'c':['a']},'a') @@ -3444,7 +3477,7 @@ def fire_script(self, sigma): c[e[1]] += sigma[i]*e[2] return SandpileConfig(self._sandpile, c) - def unstable(self): + def unstable(self) -> list: r""" The unstable vertices. @@ -3457,8 +3490,8 @@ def unstable(self): sage: c.unstable() [2, 3] """ - return [v for v in self._vertices if - self[v] >= self._sandpile.out_degree(v)] + return [v for v in self._vertices + if self[v] >= self._sandpile.out_degree(v)] def fire_unstable(self): r""" @@ -3576,13 +3609,17 @@ def support(self): def add_random(self, distrib=None): r""" - Add one grain of sand to a random vertex. Optionally, a probability - distribution, ``distrib``, may be placed on the vertices or the nonsink vertices. + Add one grain of sand to a random vertex. + + Optionally, a probability distribution, ``distrib``, may be + placed on the vertices or the nonsink vertices. + See NOTE for details. INPUT: - - ``distrib`` -- (optional) list of nonnegative numbers summing to 1 (representing a prob. dist.) + - ``distrib`` -- (optional) list of nonnegative numbers + summing to 1 (representing a prob. dist.) OUTPUT: SandpileConfig @@ -3998,7 +4035,7 @@ def show(self, sink=True, colors=True, heights=False, directed=None, **kwds): a[i] = str(i)+":"+str(self[i]) T.relabel(a) if colors: - vc = {} # vertex colors + vc: dict[str, list] = {} # vertex colors r = rainbow(max_height) # colors # noqa: F821 for i in range(max_height): vc[r[i]] = [] @@ -4305,7 +4342,7 @@ def __mul__(self, other): sage: 3*D == D*3 True """ - return SandpileDivisor(self.sandpile(),[i*other for i in self.values()]) + return SandpileDivisor(self.sandpile(), [i*other for i in self.values()]) def __rmul__(self, other): r""" @@ -4328,7 +4365,7 @@ def __rmul__(self, other): sage: 3*D == D*3 True """ - return SandpileDivisor(self.sandpile(),[other*i for i in self.values()]) + return SandpileDivisor(self.sandpile(), [other*i for i in self.values()]) def __radd__(self, other): r""" @@ -4604,7 +4641,7 @@ def fire_vertex(self, v): D[v] -= self._sandpile.out_degree(v) for e in self._sandpile.outgoing_edge_iterator(v): D[e[1]] += e[2] - return SandpileDivisor(self._sandpile,D) + return SandpileDivisor(self._sandpile, D) def fire_script(self, sigma): r""" @@ -4673,7 +4710,7 @@ def fire_unstable(self): D[v] -= self._sandpile.out_degree(v) for e in self._sandpile.outgoing_edge_iterator(v): D[e[1]] += e[2] - return SandpileDivisor(self._sandpile,D) + return SandpileDivisor(self._sandpile, D) def _set_q_reduced(self): r""" @@ -4688,11 +4725,11 @@ def _set_q_reduced(self): True """ S = self.sandpile() - c = SandpileConfig(S,[self[i] for i in S.nonsink_vertices()]) + c = SandpileConfig(S, [self[i] for i in S.nonsink_vertices()]) c = c.equivalent_superstable() - D = {v:c[v] for v in S.nonsink_vertices()} + D = {v: c[v] for v in S.nonsink_vertices()} D[S.sink()] = self.deg() - c.deg() - self._q_reduced = SandpileDivisor(S,D) + self._q_reduced = SandpileDivisor(S, D) def q_reduced(self, verbose=True): r""" @@ -4758,7 +4795,7 @@ def is_q_reduced(self): True """ S = self.sandpile() - c = SandpileConfig(S,[self[v] for v in S.nonsink_vertices()]) + c = SandpileConfig(S, [self[v] for v in S.nonsink_vertices()]) return c.is_superstable() def is_linearly_equivalent(self, D, with_firing_vector=False): @@ -4800,12 +4837,12 @@ def is_linearly_equivalent(self, D, with_firing_vector=False): """ # First try to convert D into a vector. v = vector(self.values()) - if isinstance(D,SandpileDivisor): + if isinstance(D, SandpileDivisor): w = vector(D.values()) else: w = vector(D) # Now test for linear equivalence and find firing vector - D,U,V = self.sandpile()._smith_form + D, U, V = self.sandpile()._smith_form b = v - w ub = U*b if ub[-1] != 0: @@ -4815,7 +4852,7 @@ def is_linearly_equivalent(self, D, with_firing_vector=False): return False else: try: - x = vector(ZZ,[ub[i]/D[i][i] for i in range(D.nrows()-1)]+[0]) + x = vector(ZZ, [ub[i]/D[i][i] for i in range(D.nrows()-1)]+[0]) if with_firing_vector: return V*x else: @@ -4903,7 +4940,7 @@ def _set_linear_system(self): mat_file.write(str(n)+' ') mat_file.write(str(n)+'\n') for r in L: - mat_file.write(''.join(map(str,r))) + mat_file.write(''.join(map(str, r))) mat_file.write('\n') # relations file with open(lin_sys_rel, 'w') as rel_file: @@ -4977,7 +5014,7 @@ def _set_polytope(self): """ S = self.sandpile() myL = S.laplacian().transpose().delete_columns([S._sink_ind]) - my_ieqs = [[self[v]] + list(-myL[i]) for i,v in enumerate(S.vertices(sort=True))] + my_ieqs = [[self[v]] + list(-myL[i]) for i, v in enumerate(S.vertices(sort=True))] self._polytope = Polyhedron(ieqs=my_ieqs) def polytope(self): @@ -5067,7 +5104,7 @@ def _set_effective_div(self): S = self.sandpile() myL = S.laplacian().transpose().delete_columns([S._sink_ind]) dv = vector(ZZ, self.values()) - self._effective_div = [SandpileDivisor(S,list(dv - myL*i)) + self._effective_div = [SandpileDivisor(S, list(dv - myL*i)) for i in self._polytope_integer_pts] def effective_div(self, verbose=True, with_firing_vectors=False): @@ -5193,14 +5230,14 @@ def _set_rank(self, set_witness=False): while k >= 0: rk += 1 try: - d = next(i for i,j in enumerate(c) if i == j and i != 0) + d = next(i for i, j in enumerate(c) if i == j and i != 0) except Exception: d = n - 1 k = k - d if k >= 0: c[0] = n - 1 - d - b1 = [c[i] + n - d for i in range(1,d)] - b2 = [c[i] - d for i in range(d,n-1)] + b1 = [c[i] + n - d for i in range(1, d)] + b2 = [c[i] - d for i in range(d, n-1)] c = b2 + [c[0]] + b1 self._rank = rk # All other cases. @@ -5319,10 +5356,10 @@ def _set_r_of_D(self, verbose=False): if w not in new_level: new_level.append(w) C = d - w - C = SandpileDivisor(self._sandpile,list(C)) + C = SandpileDivisor(self._sandpile, list(C)) eff = C.effective_div() if not eff: - self._r_of_D = (r, SandpileDivisor(self._sandpile,list(w))) + self._r_of_D = (r, SandpileDivisor(self._sandpile, list(w))) return level = new_level @@ -5355,7 +5392,7 @@ def weierstrass_rank_seq(self, v='sink'): verts = s.vertices(sort=True) Ei = s.zero_div() Ei[verts.index(v)] = 1 - Ei = SandpileDivisor(s,Ei) + Ei = SandpileDivisor(s, Ei) r = D.rank() seq = [r] while r != -1: @@ -5916,28 +5953,28 @@ def triangle_sandpile(n): sage: T.group_order() 135418115000 """ - T = {(-1, -1):{}} + T = {(-1, -1): {}} for i in range(n): for j in range(n-i): - T[(i,j)] = {} + T[(i, j)] = {} if i < n-j-1: - T[(i,j)][(i+1,j)] = 1 - T[(i,j)][(i,j+1)] = 1 + T[(i, j)][(i+1, j)] = 1 + T[(i, j)][(i, j+1)] = 1 if i > 0: - T[(i,j)][(i-1,j+1)] = 1 - T[(i,j)][(i-1,j)] = 1 + T[(i, j)][(i-1, j+1)] = 1 + T[(i, j)][(i-1, j)] = 1 if j > 0: - T[(i,j)][(i,j-1)] = 1 - T[(i,j)][(i+1,j-1)] = 1 - d = len(T[(i,j)]) + T[(i, j)][(i, j-1)] = 1 + T[(i, j)][(i+1, j-1)] = 1 + d = len(T[(i, j)]) if d < 6: - T[(i,j)][(-1, -1)] = 6-d + T[(i, j)][(-1, -1)] = 6-d T = Sandpile(T, (-1, -1)) pos = {} for x in T.nonsink_vertices(): coords = list(x) coords[0] += QQ(1)/2*coords[1] - pos[x] = coords + pos[x] = tuple(coords) pos[(-1, -1)] = (-1, -1) T.set_pos(pos) return T @@ -6206,7 +6243,7 @@ def admissible_partitions(S, k): yield p -def partition_sandpile(S, p): +def partition_sandpile(S, p) -> Sandpile: r""" Each set of vertices in `p` is regarded as a single vertex, with and edge between `A` and `B` if some element of `A` is connected by an edge to some @@ -6252,7 +6289,7 @@ def partition_sandpile(S, p): return Sandpile(g, i) -def min_cycles(G, v): +def min_cycles(G, v) -> list: r""" Minimal length cycles in the digraph `G` starting at vertex `v`. @@ -6271,9 +6308,8 @@ def min_cycles(G, v): sage: [min_cycles(T, i) for i in T.vertices(sort=True)] [[], [[1, 3]], [[2, 3, 1], [2, 3]], [[3, 1], [3, 2]]] """ - pr = G.neighbors_in(v) sp = G.shortest_paths(v) - return [sp[i] for i in pr if i in sp] + return [sp[i] for i in G.neighbor_in_iterator(v) if i in sp] def wilmes_algorithm(M): @@ -6289,6 +6325,7 @@ def wilmes_algorithm(M): EXAMPLES:: + sage: from sage.sandpiles.sandpile import wilmes_algorithm sage: P = matrix([[2,3,-7,-3],[5,2,-5,5],[8,2,5,4],[-5,-9,6,6]]) sage: wilmes_algorithm(P) [ 3279 -79 -1599 -1600] @@ -6303,13 +6340,12 @@ def wilmes_algorithm(M): # find the gcd of the row-sums, and perform the corresponding row # operations on M if M.matrix_over_field().is_invertible(): - L = deepcopy(M) - L = matrix(ZZ, L) + L = matrix(ZZ, M) U = matrix(ZZ, [sum(i) for i in L]).smith_form()[2].transpose() L = U*M for k in range(1, M.nrows()-1): - smith = matrix(ZZ, [i[k-1] for i in L[k:]]).smith_form()[2].transpose() - U = identity_matrix(ZZ, k).block_sum(smith) + sm = matrix(ZZ, [i[k-1] for i in L[k:]]).smith_form()[2].transpose() + U = identity_matrix(ZZ, k).block_sum(sm) L = U*L L[k] = -L[k] if L[-1][-2] > 0: From 942142089965d12f34e951bbebbf873e22f94c3e Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Thu, 28 Nov 2024 14:23:18 -0600 Subject: [PATCH 168/210] fix linting in 38161 --- src/sage/dynamics/arithmetic_dynamics/projective_ds.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 8afcbcb5cf0..1ad65e8bdc4 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -2119,8 +2119,7 @@ def green_function(self, P, v, **kwds): h = max([R(v)**(-R(c.valuation(v))) for c in poly.coefficients()]) else: h = max([R(c.abs_non_arch(v, prec=prec)) for c in poly.coefficients()]) - if h > maxh: - maxh = h + maxh = max(h, maxh) if maxh == 0: maxh = 1 #avoid division by 0 if isinstance(v, RingHomomorphism_im_gens): #archimedean From 5d27ea98b77abdefe451ba5b31b738545f97f9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 29 Nov 2024 13:45:10 +0100 Subject: [PATCH 169/210] pep8 cleanup for structure/ --- src/sage/structure/__init__.py | 2 +- src/sage/structure/all.py | 8 +++---- src/sage/structure/formal_sum.py | 18 +++++++++------- src/sage/structure/gens_py.py | 6 +++--- src/sage/structure/indexed_generators.py | 4 ++-- src/sage/structure/list_clone_timings.py | 8 +++---- src/sage/structure/proof/all.py | 4 +--- src/sage/structure/proof/proof.py | 3 ++- src/sage/structure/sequence.py | 23 ++++++++++----------- src/sage/structure/set_factories.py | 13 ++++++------ src/sage/structure/set_factories_example.py | 8 +++---- src/sage/structure/test_factory.py | 6 +++--- 12 files changed, 52 insertions(+), 51 deletions(-) diff --git a/src/sage/structure/__init__.py b/src/sage/structure/__init__.py index 2534e5a71f8..bf977ccc379 100644 --- a/src/sage/structure/__init__.py +++ b/src/sage/structure/__init__.py @@ -1,3 +1,3 @@ # sage_setup: distribution = sagemath-objects # Resolve a cyclic import -import sage.structure.element \ No newline at end of file +import sage.structure.element diff --git a/src/sage/structure/all.py b/src/sage/structure/all.py index 40b9daa67e8..785acc174e3 100644 --- a/src/sage/structure/all.py +++ b/src/sage/structure/all.py @@ -21,10 +21,10 @@ from sage.structure.proof import all as proof -from sage.misc.lazy_import import lazy_import -lazy_import('sage.structure.formal_sum', ['FormalSums', 'FormalSum']) -del lazy_import - from sage.structure.mutability import Mutability from sage.structure.element_wrapper import ElementWrapper + +from sage.misc.lazy_import import lazy_import +lazy_import('sage.structure.formal_sum', ['FormalSums', 'FormalSum']) +del lazy_import diff --git a/src/sage/structure/formal_sum.py b/src/sage/structure/formal_sum.py index ab72ff5eb2d..662e3b33240 100644 --- a/src/sage/structure/formal_sum.py +++ b/src/sage/structure/formal_sum.py @@ -65,11 +65,11 @@ # # https://www.gnu.org/licenses/ # **************************************************************************** - -from sage.misc.repr import repr_lincomb import operator from collections import OrderedDict +from sage.misc.persist import register_unpickle_override +from sage.misc.repr import repr_lincomb from sage.modules.module import Module from sage.structure.element import ModuleElement from sage.structure.richcmp import richcmp @@ -392,11 +392,14 @@ def _element_constructor_(self, x, check=True, reduce=True): else: x = x._data if isinstance(x, list): - return self.element_class(x, check=check,reduce=reduce,parent=self) + return self.element_class(x, check=check, + reduce=reduce, parent=self) if x == 0: - return self.element_class([], check=False, reduce=False, parent=self) + return self.element_class([], check=False, + reduce=False, parent=self) else: - return self.element_class([(self.base_ring()(1), x)], check=False, reduce=False, parent=self) + return self.element_class([(self.base_ring()(1), x)], + check=False, reduce=False, parent=self) def _coerce_map_from_(self, X): r""" @@ -413,7 +416,7 @@ def _coerce_map_from_(self, X): From: Abelian Group of all Formal Finite Sums over Integer Ring To: Abelian Group of all Formal Finite Sums over Rational Field """ - if isinstance(X,FormalSums): + if isinstance(X, FormalSums): if self.base_ring().has_coerce_map_from(X.base_ring()): return True return False @@ -475,7 +478,7 @@ def _an_element_(self, check=False, reduce=False): 1/2 """ return self.element_class([(self.base_ring().an_element(), 1)], - check=check, reduce=reduce, parent=self) + check=check, reduce=reduce, parent=self) formal_sums = FormalSums() @@ -483,5 +486,4 @@ def _an_element_(self, check=False, reduce=False): # Formal sums now derives from UniqueRepresentation, which makes the # factory function unnecessary. This is why the name was changed from # class FormalSums_generic to class FormalSums. -from sage.misc.persist import register_unpickle_override register_unpickle_override('sage.structure.formal_sum', 'FormalSums_generic', FormalSums) diff --git a/src/sage/structure/gens_py.py b/src/sage/structure/gens_py.py index 6d3fcae2520..99d881ae2cd 100644 --- a/src/sage/structure/gens_py.py +++ b/src/sage/structure/gens_py.py @@ -3,7 +3,7 @@ Pure python code for abstract base class for objects with generators """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2005 William Stein # # Distributed under the terms of the GNU General Public License (GPL) @@ -15,8 +15,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** def multiplicative_iterator(M): diff --git a/src/sage/structure/indexed_generators.py b/src/sage/structure/indexed_generators.py index 7586eb06aaf..259398761bc 100644 --- a/src/sage/structure/indexed_generators.py +++ b/src/sage/structure/indexed_generators.py @@ -316,7 +316,7 @@ def _parse_names(self, m, use_latex): return names[m] except KeyError: return None - else: # treat it like a list + else: # treat it like a list try: i = self._indices.rank(m) except (AttributeError, TypeError, KeyError, ValueError): @@ -458,7 +458,7 @@ def _repr_generator(self, m): return self.prefix() + left + (', '.join(repr(val) for val in m)) + right if not quotes and isinstance(m, str): return self.prefix() + left + m + right - return self.prefix() + left + repr(m) + right # mind the (m), to accept a tuple for m + return self.prefix() + left + repr(m) + right # mind the (m), to accept a tuple for m def _ascii_art_generator(self, m): r""" diff --git a/src/sage/structure/list_clone_timings.py b/src/sage/structure/list_clone_timings.py index a072b7287a5..500167b1157 100644 --- a/src/sage/structure/list_clone_timings.py +++ b/src/sage/structure/list_clone_timings.py @@ -73,12 +73,12 @@ cy_add1_mutable(e) : 625 loops, best of 3: 14.1 µs per loop cy_add1_with(e) : 625 loops, best of 3: 17.5 µs per loop """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2009-2010 Florent Hivert # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.structure.list_clone import ClonableArray from sage.structure.list_clone_demo import IncreasingArrays @@ -116,7 +116,7 @@ def check(self): ##################################################################### -###### Timings functions ###### +# Timings functions # ##################################################################### def add1_internal(bla): """ diff --git a/src/sage/structure/proof/all.py b/src/sage/structure/proof/all.py index 0db573b93ce..271109fb2e2 100644 --- a/src/sage/structure/proof/all.py +++ b/src/sage/structure/proof/all.py @@ -1,4 +1,5 @@ # sage_setup: distribution = sagemath-objects +from sage.structure.proof.proof import WithProof def arithmetic(t=None): @@ -240,6 +241,3 @@ def all(t=None): return _proof_prefs._require_proof.copy() for s in _proof_prefs._require_proof: _proof_prefs._require_proof[s] = bool(t) - - -from sage.structure.proof.proof import WithProof diff --git a/src/sage/structure/proof/proof.py b/src/sage/structure/proof/proof.py index c8c2df4cafe..b6b7d8b0509 100644 --- a/src/sage/structure/proof/proof.py +++ b/src/sage/structure/proof/proof.py @@ -225,7 +225,8 @@ def get_flag(t=None, subsystem=None): False """ if t is None: - if subsystem in ["arithmetic", "elliptic_curve", "linear_algebra", "number_field","polynomial"]: + if subsystem in ["arithmetic", "elliptic_curve", + "linear_algebra", "number_field", "polynomial"]: return _proof_prefs._require_proof[subsystem] else: return _proof_prefs._require_proof["other"] diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index cc9fcedadfe..71a67d4e20b 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -70,7 +70,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** - +from sage.misc.persist import register_unpickle_override import sage.structure.sage_object import sage.structure.coerce @@ -239,7 +239,7 @@ def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=Non # start the pairwise coercion for i in range(len(x) - 1): try: - x[i], x[i+1] = sage.structure.element.canonical_coercion(x[i],x[i+1]) + x[i], x[i+1] = sage.structure.element.canonical_coercion(x[i], x[i+1]) except TypeError: from sage.categories.objects import Objects universe = Objects() @@ -515,16 +515,16 @@ def __getitem__(self, n): check=False, immutable=False, cr=self.__cr) - else: - return list.__getitem__(self,n) + + return list.__getitem__(self, n) # We have to define the *slice functions as long as Sage uses Python 2.* # otherwise the inherited *slice functions from list are called def __getslice__(self, i, j): - return self.__getitem__(slice(i,j)) + return self.__getitem__(slice(i, j)) def __setslice__(self, i, j, value): - return self.__setitem__(slice(i,j), value) + return self.__setitem__(slice(i, j), value) def append(self, x): """ @@ -863,19 +863,19 @@ def __getattr__(self, name): sage: hash(S) 34 """ - if name == "_Sequence_generic__cr" and hasattr(self,"_Sequence__cr"): + if name == "_Sequence_generic__cr" and hasattr(self, "_Sequence__cr"): self.__cr = self._Sequence__cr return self.__cr - elif name == "_Sequence_generic__cr_str" and hasattr(self,"_Sequence__cr_str"): + elif name == "_Sequence_generic__cr_str" and hasattr(self, "_Sequence__cr_str"): self.__cr_str = self._Sequence__cr_str return self.__cr_str - elif name == "_Sequence_generic__immutable" and hasattr(self,"_Sequence__immutable"): + elif name == "_Sequence_generic__immutable" and hasattr(self, "_Sequence__immutable"): self.__immutable = self._Sequence__immutable return self.__immutable - elif name == "_Sequence_generic__universe" and hasattr(self,"_Sequence__universe"): + elif name == "_Sequence_generic__universe" and hasattr(self, "_Sequence__universe"): self.__universe = self._Sequence__universe return self.__universe - elif name == "_Sequence_generic__hash" and hasattr(self,"_Sequence__hash"): + elif name == "_Sequence_generic__hash" and hasattr(self, "_Sequence__hash"): self.__hash = self._Sequence__hash return self.__hash else: @@ -884,5 +884,4 @@ def __getattr__(self, name): seq = Sequence -from sage.misc.persist import register_unpickle_override register_unpickle_override('sage.structure.sequence', 'Sequence', Sequence_generic) diff --git a/src/sage/structure/set_factories.py b/src/sage/structure/set_factories.py index c65a31089e8..ca46a413d7a 100644 --- a/src/sage/structure/set_factories.py +++ b/src/sage/structure/set_factories.py @@ -306,12 +306,12 @@ - Florent Hivert (2011-2012): initial revision """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Florent Hivert # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.structure.sage_object import SageObject @@ -846,7 +846,8 @@ def element_constructor_attributes(self, constraints): sage: pol.element_constructor_attributes(()) {'_element_constructor_': <... 'tuple'>, '_parent_for': None} """ - return {'_element_constructor_' : self._constructor, '_parent_for' : None} + return {'_element_constructor_': self._constructor, + '_parent_for': None} def _repr_(self): r""" @@ -1107,7 +1108,7 @@ def __contains__(self, x): False """ if (isinstance(x, self.element_class) and - x.parent() == self._parent_for): # TODO: is_parent_of ??? + x.parent() == self._parent_for): # TODO: is_parent_of ??? try: self.check_element(x, True) except ValueError: @@ -1140,7 +1141,7 @@ def __call__(self, *args, **keywords): # Ensure idempotence of element construction if (len(args) == 1 and isinstance(args[0], self.element_class) and - args[0].parent() == self._parent_for): + args[0].parent() == self._parent_for): check = keywords.get("check", True) if check: self.check_element(args[0], check) diff --git a/src/sage/structure/set_factories_example.py b/src/sage/structure/set_factories_example.py index df4db63ef89..0e5a735c532 100644 --- a/src/sage/structure/set_factories_example.py +++ b/src/sage/structure/set_factories_example.py @@ -25,12 +25,12 @@ S_a^b := \{(x,y) \in S \mid x = a, y = b\}. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Florent Hivert # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.structure.unique_representation import UniqueRepresentation from sage.structure.element_wrapper import ElementWrapper @@ -100,7 +100,7 @@ def __call__(self, x=None, y=None, policy=None): return SingletonPair(x, y, policy) return PairsX_(x, policy) elif isinstance(y, (Integer, int)): - return Pairs_Y(y, policy) + return Pairs_Y(y, policy) return AllPairs(policy) def add_constraints(self, cons, args_opts): diff --git a/src/sage/structure/test_factory.py b/src/sage/structure/test_factory.py index 707feb0d409..216c0d6d3d9 100644 --- a/src/sage/structure/test_factory.py +++ b/src/sage/structure/test_factory.py @@ -3,7 +3,7 @@ Test of the :mod:`~sage.structure.factory` module """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 Robert Bradshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -15,8 +15,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#****************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** from sage.structure.factory import UniqueFactory From da024a000bcf832c73a56e19251b2c4197196559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 29 Nov 2024 13:54:56 +0100 Subject: [PATCH 170/210] pep8 cleanup in repl/ and sat/ --- src/sage/repl/configuration.py | 7 ++--- src/sage/repl/interpreter.py | 3 +- src/sage/repl/ipython_extension.py | 4 +-- src/sage/repl/rich_output/backend_doctest.py | 8 +++--- src/sage/repl/rich_output/backend_ipython.py | 16 +++++------ src/sage/repl/rich_output/output_basic.py | 6 ++-- src/sage/repl/rich_output/output_catalog.py | 6 ++-- src/sage/repl/rich_output/test_backend.py | 6 ++-- src/sage/sat/boolean_polynomials.py | 4 +-- src/sage/sat/converters/polybori.py | 30 ++++++++++---------- src/sage/sat/solvers/picosat.py | 4 +-- src/sage/sat/solvers/sat_lp.py | 4 +-- src/sage/stats/distributions/catalog.py | 6 ++-- 13 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/sage/repl/configuration.py b/src/sage/repl/configuration.py index 68b2fbb9f8b..7016e12837b 100644 --- a/src/sage/repl/configuration.py +++ b/src/sage/repl/configuration.py @@ -15,15 +15,14 @@ sage: 'sage: [False, True]' in output # needs pexpect True """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2016 Volker Braun # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import sys diff --git a/src/sage/repl/interpreter.py b/src/sage/repl/interpreter.py index 3a269592917..83d22127cd3 100644 --- a/src/sage/repl/interpreter.py +++ b/src/sage/repl/interpreter.py @@ -772,7 +772,8 @@ def __init__(self, app): contact_email = 'sage-support@googlegroups.com' bug_tracker = 'https://github.com/sagemath/sage/issues' CrashHandler.__init__(self, - app, contact_name, contact_email, bug_tracker, show_crash_traceback=True) + app, contact_name, contact_email, + bug_tracker, show_crash_traceback=True) self.crash_report_fname = 'Sage_crash_report.txt' diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index b6fc42bbb37..b49e91b83ba 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -302,7 +302,7 @@ def display(self, args): max_width = 0 if max_width <= 0: raise ValueError( - "max width must be a positive integer") + "max width must be a positive integer") import sage.typeset.character_art as character_art character_art.MAX_WIDTH = max_width dm.preferences.text = arg0 @@ -435,7 +435,7 @@ def __init__(self, shell=None): self.init_line_transforms() try: - import sage.all # until sage's import hell is fixed + import sage.all # until sage's import hell is fixed except ImportError: import sage.all__sagemath_repl diff --git a/src/sage/repl/rich_output/backend_doctest.py b/src/sage/repl/rich_output/backend_doctest.py index 5113b5845b4..0f347281e82 100644 --- a/src/sage/repl/rich_output/backend_doctest.py +++ b/src/sage/repl/rich_output/backend_doctest.py @@ -13,14 +13,14 @@ The Sage display manager using the doctest backend """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2015 Volker Braun # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import sys @@ -295,7 +295,7 @@ def validate(self, rich_output): assert data.startswith(b'\0\0\0') # See http://www.ftyps.com/ ftyps = [data[i:i+4] for i in range(8, data[3], 4)] - del ftyps[1] # version number, not an ftyp + del ftyps[1] # version number, not an ftyp expected = [b'avc1', b'iso2', b'mp41', b'mp42'] assert any(i in ftyps for i in expected) elif isinstance(rich_output, OutputVideoFlash): diff --git a/src/sage/repl/rich_output/backend_ipython.py b/src/sage/repl/rich_output/backend_ipython.py index b736aca9538..5b013574507 100644 --- a/src/sage/repl/rich_output/backend_ipython.py +++ b/src/sage/repl/rich_output/backend_ipython.py @@ -525,7 +525,7 @@ def displayhook(self, plain_text, rich_output): elif isinstance(rich_output, OutputLatex): return ({'text/latex': rich_output.latex.get_str(), 'text/plain': plain_text.text.get_str(), - }, {}) + }, {}) elif isinstance(rich_output, OutputHtml): data = {'text/html': rich_output.html.get_str(), 'text/plain': plain_text.text.get_str()} @@ -535,29 +535,29 @@ def displayhook(self, plain_text, rich_output): elif isinstance(rich_output, OutputImagePng): return ({'image/png': rich_output.png.get(), 'text/plain': plain_text.text.get_str(), - }, {}) + }, {}) elif isinstance(rich_output, OutputImageGif): return ({'text/html': rich_output.html_fragment(), 'text/plain': plain_text.text.get_str(), - }, {}) + }, {}) elif isinstance(rich_output, OutputImageJpg): return ({'image/jpeg': rich_output.jpg.get(), 'text/plain': plain_text.text.get_str(), - }, {}) + }, {}) elif isinstance(rich_output, OutputImageSvg): return ({'image/svg+xml': rich_output.svg.get(), 'text/plain': plain_text.text.get_str(), - }, {}) + }, {}) elif isinstance(rich_output, OutputImagePdf): return ({'image/png': rich_output.png.get(), 'text/plain': plain_text.text.get_str(), - }, {}) + }, {}) elif isinstance(rich_output, OutputSceneJmol): from sage.repl.display.jsmol_iframe import JSMolHtml jsmol = JSMolHtml(rich_output, height=500) return ({'text/html': jsmol.iframe(), 'text/plain': plain_text.text.get_str(), - }, {}) + }, {}) elif isinstance(rich_output, OutputSceneThreejs): escaped_html = html.escape(rich_output.html.get_str()) iframe = IFRAME_TEMPLATE.format( @@ -567,7 +567,7 @@ def displayhook(self, plain_text, rich_output): ) return ({'text/html': iframe, 'text/plain': plain_text.text.get_str(), - }, {}) + }, {}) else: raise TypeError('rich_output type not supported') diff --git a/src/sage/repl/rich_output/output_basic.py b/src/sage/repl/rich_output/output_basic.py index 70257f7f4ed..05cff326eb9 100644 --- a/src/sage/repl/rich_output/output_basic.py +++ b/src/sage/repl/rich_output/output_basic.py @@ -32,14 +32,14 @@ class is independent of user preferences and of the display file system. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2015 Volker Braun # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.structure.sage_object import SageObject diff --git a/src/sage/repl/rich_output/output_catalog.py b/src/sage/repl/rich_output/output_catalog.py index 542182eee69..584a077781c 100644 --- a/src/sage/repl/rich_output/output_catalog.py +++ b/src/sage/repl/rich_output/output_catalog.py @@ -5,14 +5,14 @@ If you define another output type then you must add it to the imports here. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2015 Volker Braun # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from .output_basic import ( diff --git a/src/sage/repl/rich_output/test_backend.py b/src/sage/repl/rich_output/test_backend.py index 133fb35ae5d..059eda5de3e 100644 --- a/src/sage/repl/rich_output/test_backend.py +++ b/src/sage/repl/rich_output/test_backend.py @@ -30,14 +30,14 @@ TestOutputPlainText container """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2015 Volker Braun # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.structure.sage_object import SageObject diff --git a/src/sage/sat/boolean_polynomials.py b/src/sage/sat/boolean_polynomials.py index bad6b33d4d3..ab6567d37fb 100644 --- a/src/sage/sat/boolean_polynomials.py +++ b/src/sage/sat/boolean_polynomials.py @@ -303,7 +303,7 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): if S[0] is None: return None elif S[-1] is False: - return S[0:-1] + return S[0:-1] return S @@ -395,7 +395,7 @@ def learn(F, converter=None, solver=None, max_learnt_length=3, interreduction=Fa try: lc = solver.learnt_clauses() except (AttributeError, NotImplementedError): - # solver does not support recovering learnt clauses + # solver does not support recovering learnt clauses lc = [] for c in lc: if len(c) <= max_learnt_length: diff --git a/src/sage/sat/converters/polybori.py b/src/sage/sat/converters/polybori.py index 27437c472ec..860a8a7e093 100644 --- a/src/sage/sat/converters/polybori.py +++ b/src/sage/sat/converters/polybori.py @@ -128,7 +128,7 @@ def __init__(self, solver, ring, max_vars_sparse=6, use_xor_clauses=None, cuttin self.cutting_number = cutting_number if use_xor_clauses is None: - use_xor_clauses = hasattr(solver,"add_xor_clause") + use_xor_clauses = hasattr(solver, "add_xor_clause") self.use_xor_clauses = use_xor_clauses self.ring = ring @@ -222,7 +222,7 @@ def choose(s): indices.append(nav.value()) nav = t else: - if self.random_generator.randint(0,1): + if self.random_generator.randint(0, 1): indices.append(nav.value()) nav = t @@ -337,11 +337,11 @@ def clauses_dense(self, f): for fpart, this_equal_zero in self.split_xor(f, equal_zero): ll = len(fpart) for p in self.permutations(ll, this_equal_zero): - self.solver.add_clause([ p[i]*fpart[i] for i in range(ll) ]) + self.solver.add_clause([p[i] * fpart[i] for i in range(ll)]) else: ll = len(f) for p in self.permutations(ll, equal_zero): - self.solver.add_clause([ p[i]*f[i] for i in range(ll) ]) + self.solver.add_clause([p[i] * f[i] for i in range(ll)]) @cached_method def monomial(self, m): @@ -387,19 +387,19 @@ def monomial(self, m): For correctness, this function is cached. """ if m.deg() == 1: - return m.index()+1 - else: - # we need to encode the relationship between the monomial - # and its variables - variables = [self.monomial(v) for v in m.variables()] - monomial = self.var(m) + return m.index() + 1 - # (a | -w) & (b | -w) & (w | -a | -b) <=> w == a*b - for v in variables: - self.solver.add_clause( (v, -monomial) ) - self.solver.add_clause( tuple([monomial] + [-v for v in variables]) ) + # we need to encode the relationship between the monomial + # and its variables + variables = [self.monomial(v) for v in m.variables()] + monomial = self.var(m) + + # (a | -w) & (b | -w) & (w | -a | -b) <=> w == a*b + for v in variables: + self.solver.add_clause((v, -monomial)) + self.solver.add_clause(tuple([monomial] + [-v for v in variables])) - return monomial + return monomial @cached_function def permutations(length, equal_zero): diff --git a/src/sage/sat/solvers/picosat.py b/src/sage/sat/solvers/picosat.py index fb8c10afd80..736aeebd05a 100644 --- a/src/sage/sat/solvers/picosat.py +++ b/src/sage/sat/solvers/picosat.py @@ -160,8 +160,8 @@ def __call__(self, assumptions=None): sage: solver() # optional - pycosat False """ - #import pycosat - #self._solve = pycosat.solve + # import pycosat + # self._solve = pycosat.solve sol = self._solve(self._clauses, verbose=self._verbosity, prop_limit=self._prop_limit, vars=self._nvars) # sol = pycosat.solve(self._clauses) diff --git a/src/sage/sat/solvers/sat_lp.py b/src/sage/sat/solvers/sat_lp.py index 5a027f6ae9b..05aa4812230 100644 --- a/src/sage/sat/solvers/sat_lp.py +++ b/src/sage/sat/solvers/sat_lp.py @@ -57,7 +57,7 @@ def var(self): nvars = n = self._LP.number_of_variables() while nvars == self._LP.number_of_variables(): n += 1 - self._vars[n] # creates the variable if needed + self._vars[n] # creates the variable if needed return n def nvars(self): @@ -143,7 +143,7 @@ def __call__(self): b = self._LP.get_values(self._vars, convert=bool, tolerance=self._integrality_tolerance) n = max(b) - return [None]+[b.get(i, False) for i in range(1,n+1)] + return [None] + [b.get(i, False) for i in range(1, n + 1)] def __repr__(self): """ diff --git a/src/sage/stats/distributions/catalog.py b/src/sage/stats/distributions/catalog.py index f03bdd97ae3..8ae97fb24c4 100644 --- a/src/sage/stats/distributions/catalog.py +++ b/src/sage/stats/distributions/catalog.py @@ -17,14 +17,14 @@ sage: from sage.stats.distributions.catalog import * """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2024 Gareth Ma # # Distributed under the terms of the GNU General Public License (GPL), # version 2 or later (at your preference). # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.misc.lazy_import import lazy_import lazy_import("sage.stats.distributions.discrete_gaussian_integer", ["DiscreteGaussianDistributionIntegerSampler"]) From 65c6011538d2a5a998ee43a21e2dbd0e90f22a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 29 Nov 2024 14:03:12 +0100 Subject: [PATCH 171/210] miscellanous pep8 cleanup --- src/sage/matrix/matrix_misc.py | 6 +++--- src/sage/matroids/chow_ring.py | 3 ++- src/sage/matroids/constructor.py | 14 ++++++-------- .../free_quadratic_module_integer_symmetric.py | 11 ++++++----- src/sage/quadratic_forms/all.py | 12 ++++++++---- .../quadratic_form__local_density_congruence.py | 2 +- src/sage/quivers/ar_quiver.py | 4 ++-- 7 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/sage/matrix/matrix_misc.py b/src/sage/matrix/matrix_misc.py index 35591735e57..a539f22ddff 100644 --- a/src/sage/matrix/matrix_misc.py +++ b/src/sage/matrix/matrix_misc.py @@ -14,8 +14,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.categories.fields import Fields _Fields = Fields() @@ -309,4 +309,4 @@ def permanental_minor_polynomial(A, permanent_only=False, var='t', prec=None): " algorithm... please contact sage-devel@googlegroups.com") p = p[0] - return p[min(nrows,ncols)] if permanent_only else p + return p[min(nrows, ncols)] if permanent_only else p diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 173c8db7f84..92e48f7147f 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -11,6 +11,7 @@ from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.commutative_rings import CommutativeRings + class ChowRing(QuotientRing_generic): r""" The Chow ring of a matroid. @@ -336,4 +337,4 @@ def homogeneous_degree(self): f = self.lift() if not f.is_homogeneous(): raise ValueError("element is not homogeneous") - return f.degree() \ No newline at end of file + return f.degree() diff --git a/src/sage/matroids/constructor.py b/src/sage/matroids/constructor.py index 8548b2bfede..f1c0af7bea7 100644 --- a/src/sage/matroids/constructor.py +++ b/src/sage/matroids/constructor.py @@ -805,11 +805,11 @@ def Matroid(groundset=None, data=None, **kwds): if isinstance(data, Graph): key = 'graph' elif isinstance(data, Matrix) or ( - isinstance(data, tuple) and isinstance(data[0], Matrix)): + isinstance(data, tuple) and isinstance(data[0], Matrix)): key = 'matrix' elif isinstance(data, sage.modules.with_basis.morphism.ModuleMorphism) or ( - isinstance(data, tuple) and - isinstance(data[0], sage.modules.with_basis.morphism.ModuleMorphism)): + isinstance(data, tuple) and + isinstance(data[0], sage.modules.with_basis.morphism.ModuleMorphism)): key = 'morphism' elif isinstance(data, sage.matroids.matroid.Matroid): key = 'matroid' @@ -1032,11 +1032,9 @@ def revlex_sort_key(s): subsets = sorted(combinations(range(N), rk), key=revlex_sort_key) if len(data) != len(subsets): raise ValueError("expected string of length %s (%s choose %s), got %s" % - (len(subsets), N, rk, len(data))) - bases = [] - for i, x in enumerate(data): - if x != '0': - bases.append([groundset[c] for c in subsets[i]]) + (len(subsets), N, rk, len(data))) + bases = [[groundset[c] for c in subsets[i]] + for i, x in enumerate(data) if x != '0'] M = BasisMatroid(groundset=groundset, bases=bases) # Circuit closures: diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index c58f0f3ea1e..3f6a34e778c 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -1556,7 +1556,7 @@ def _fplll_enumerate(self, target=None): gmat = fpylll.IntegerMatrix(dim, dim) for i in range(dim): for j in range(dim): - gmat[i,j] = gram[i,j] + gmat[i, j] = gram[i, j] gso = fpylll.GSO.Mat(gmat, gram=True) ok = gso.update_gso() assert ok @@ -1564,11 +1564,12 @@ def _fplll_enumerate(self, target=None): coord = None if target is not None: coord = basis.solve_left(target) - Mu = 1 + matrix([gso.get_mu(i,j) for j in range(dim)] for i in range(dim)) + Mu = 1 + matrix([gso.get_mu(i, j) for j in range(dim)] + for i in range(dim)) coord *= Mu count = 8 - bound = gso.get_r(dim-1, dim-1) + bound = gso.get_r(dim - 1, dim - 1) seen = set() while True: enum = fpylll.Enumeration(gso, count, fpylll.EvaluatorStrategy.BEST_N_SOLUTIONS) @@ -1579,8 +1580,8 @@ def _fplll_enumerate(self, target=None): if len(combs) < count: bound *= 2 continue - for length,comb in combs: - vec = sum(ZZ(c)*b for c,b in zip(comb,basis)) + for length, comb in combs: + vec = sum(ZZ(c) * b for c, b in zip(comb, basis)) if tuple(vec) not in seen: yield vec seen.add(tuple(vec)) diff --git a/src/sage/quadratic_forms/all.py b/src/sage/quadratic_forms/all.py index 5982c6b8a5a..c4832168378 100644 --- a/src/sage/quadratic_forms/all.py +++ b/src/sage/quadratic_forms/all.py @@ -6,13 +6,17 @@ from sage.quadratic_forms.quadratic_form import QuadraticForm, DiagonalQuadraticForm, quadratic_form_from_invariants -from sage.quadratic_forms.random_quadraticform import (random_quadraticform, random_quadraticform_with_conditions, - random_ternaryqf, random_ternaryqf_with_conditions) +from sage.quadratic_forms.random_quadraticform import (random_quadraticform, + random_quadraticform_with_conditions, + random_ternaryqf, + random_ternaryqf_with_conditions) from sage.quadratic_forms.extras import least_quadratic_nonresidue, extend_to_primitive, is_triangular_number -from sage.quadratic_forms.special_values import (gamma__exact, zeta__exact, QuadraticBernoulliNumber, - quadratic_L_function__exact, quadratic_L_function__numerical) +from sage.quadratic_forms.special_values import (gamma__exact, zeta__exact, + QuadraticBernoulliNumber, + quadratic_L_function__exact, + quadratic_L_function__numerical) from sage.quadratic_forms.genera.genus import Genus diff --git a/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py b/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py index dc9b30aa763..a88cf660412 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py +++ b/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py @@ -291,7 +291,7 @@ def local_good_density_congruence_even(self, m, Zvec, NZvec): # Take cases on the existence of additional nonzero congruence conditions (mod 2) if NZvec is None: total = (4 ** len(Z_Is8)) * (8 ** len(Is8_minus_Z)) \ - * count_all_local_good_types_normal_form(Q_Not8,2, 3, m, list(Z_Not8), None) + * count_all_local_good_types_normal_form(Q_Not8, 2, 3, m, list(Z_Not8), None) else: ZNZ = Z + Set(NZvec) ZNZ_Not8 = Not8.intersection(ZNZ) diff --git a/src/sage/quivers/ar_quiver.py b/src/sage/quivers/ar_quiver.py index f13c67dfa32..f0b2193eece 100644 --- a/src/sage/quivers/ar_quiver.py +++ b/src/sage/quivers/ar_quiver.py @@ -9,8 +9,8 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent From f34e921a39adc74374556ab756d52c00ee737ed5 Mon Sep 17 00:00:00 2001 From: Soham Rane Date: Fri, 29 Nov 2024 19:16:35 +0530 Subject: [PATCH 172/210] Update changelog_trigger.yml : changed name 'PERSONAL_ACCESS_TOKEN' to 'WEBSITE_ACCESS_TOKEN' --- .github/workflows/changelog_trigger.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/changelog_trigger.yml b/.github/workflows/changelog_trigger.yml index 71e8aec9ae1..a2192e62230 100644 --- a/.github/workflows/changelog_trigger.yml +++ b/.github/workflows/changelog_trigger.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Trigger Workflow in website repo env: - GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + GH_TOKEN: ${{ secrets.WEBSITE_ACCESS_TOKEN }} RELEASE_TAG: ${{ github.event.release.tag_name }} run: | curl -L \ From 4c3674dd124d46edb1f05b933d61b20e79dea98a Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sat, 30 Nov 2024 07:42:21 +0700 Subject: [PATCH 173/210] Make multivariate ideal reduce() work on integer --- src/sage/rings/polynomial/multi_polynomial_ideal.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index d06f07d722e..544ef1f4655 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -4965,6 +4965,15 @@ def reduce(self, f): Requires computation of a Groebner basis, which can be a very expensive operation. + + TESTS: + + Check for :issue:`38560`:: + + sage: I.reduce(1) + 1 + sage: I.reduce(pi.n()) # unfortunate side effect + 245850922/78256779 """ try: strat = self._groebner_strategy() @@ -4973,7 +4982,7 @@ def reduce(self, f): pass gb = self.groebner_basis() - return f.reduce(gb) + return self.ring()(f).reduce(gb) def _contains_(self, f): r""" From 13031c5b07ebf3957b653749e478b24fde77506f Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sat, 30 Nov 2024 10:51:45 +0800 Subject: [PATCH 174/210] Revert nonsingular Co-authored-by: gmou3 <32706872+gmou3@users.noreply.github.com> --- src/sage/manifolds/vector_bundle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/manifolds/vector_bundle.py b/src/sage/manifolds/vector_bundle.py index 0acfa14e70a..ad830d68469 100644 --- a/src/sage/manifolds/vector_bundle.py +++ b/src/sage/manifolds/vector_bundle.py @@ -796,7 +796,7 @@ def local_frame(self, *args, **kwargs): resu._init_from_family(sections) except ArithmeticError as err: linked = str(err) in ["non-invertible matrix", - "input matrix must be non-singular"] + "input matrix must be nonsingular"] if linked: raise ValueError("the provided sections are not linearly " "independent") From bf16199c92824caf46197468bea60f7d68f0809c Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sat, 30 Nov 2024 11:15:58 +0100 Subject: [PATCH 175/210] Updated SageMath version to 10.5.rc2 --- CITATION.cff | 4 ++-- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 4 ++-- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/version_requirements.txt | 2 +- build/pkgs/sage_docbuild/version_requirements.txt | 2 +- build/pkgs/sage_setup/version_requirements.txt | 2 +- build/pkgs/sage_sws2rst/version_requirements.txt | 2 +- build/pkgs/sagelib/version_requirements.txt | 2 +- build/pkgs/sagemath_bliss/version_requirements.txt | 2 +- build/pkgs/sagemath_categories/version_requirements.txt | 2 +- build/pkgs/sagemath_coxeter3/version_requirements.txt | 2 +- build/pkgs/sagemath_environment/version_requirements.txt | 2 +- build/pkgs/sagemath_mcqd/version_requirements.txt | 2 +- build/pkgs/sagemath_meataxe/version_requirements.txt | 2 +- build/pkgs/sagemath_objects/version_requirements.txt | 2 +- build/pkgs/sagemath_repl/version_requirements.txt | 2 +- build/pkgs/sagemath_sirocco/version_requirements.txt | 2 +- build/pkgs/sagemath_tdlib/version_requirements.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 38 files changed, 44 insertions(+), 44 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 846dc8d56de..c0dbf3d6a37 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.5.rc1 +version: 10.5.rc2 doi: 10.5281/zenodo.8042260 -date-released: 2024-11-23 +date-released: 2024-11-30 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index eb2ad2d41d0..219cada0e3f 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.5.rc1, Release Date: 2024-11-23 +SageMath version 10.5.rc2, Release Date: 2024-11-30 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 40047be516c..7d0a957c854 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,3 +1,3 @@ tarball=configure-VERSION.tar.gz -sha1=873cdf7d49278239555a9887f13f22da05fb20a6 -sha256=2e02aa16c42dab86849ca6d53d6148a414c56e93177bb9cf7346df84a8315b2f +sha1=4d6de7b4a5aff43a508a1e64078fe409554869fe +sha256=18cc6fa95c0bd6ae0bf1f9b447ae2dd9da7d596d17bec5e961b980b9687e1a7e diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 1ec5d4eba60..8c7663a9fa1 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -34bd0eca0efef4b5aae919be1286ec45a9622f64 +68f446ad3f1abcea6e1a9b679a04242597f439f6 diff --git a/build/pkgs/sage_conf/version_requirements.txt b/build/pkgs/sage_conf/version_requirements.txt index 9d4b482d5a4..11ae1c5d2a5 100644 --- a/build/pkgs/sage_conf/version_requirements.txt +++ b/build/pkgs/sage_conf/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.5rc1 +sage-conf ~= 10.5rc2 diff --git a/build/pkgs/sage_docbuild/version_requirements.txt b/build/pkgs/sage_docbuild/version_requirements.txt index cc82b61571d..b2dd3fbec85 100644 --- a/build/pkgs/sage_docbuild/version_requirements.txt +++ b/build/pkgs/sage_docbuild/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.5rc1 +sage-docbuild ~= 10.5rc2 diff --git a/build/pkgs/sage_setup/version_requirements.txt b/build/pkgs/sage_setup/version_requirements.txt index 1ff54dc7d60..c9bffddf1dc 100644 --- a/build/pkgs/sage_setup/version_requirements.txt +++ b/build/pkgs/sage_setup/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.5rc1 +sage-setup ~= 10.5rc2 diff --git a/build/pkgs/sage_sws2rst/version_requirements.txt b/build/pkgs/sage_sws2rst/version_requirements.txt index 1c2539d939c..44d72b63d93 100644 --- a/build/pkgs/sage_sws2rst/version_requirements.txt +++ b/build/pkgs/sage_sws2rst/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.5rc1 +sage-sws2rst ~= 10.5rc2 diff --git a/build/pkgs/sagelib/version_requirements.txt b/build/pkgs/sagelib/version_requirements.txt index 43b9a42f129..49cf1f431c8 100644 --- a/build/pkgs/sagelib/version_requirements.txt +++ b/build/pkgs/sagelib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-standard ~= 10.5rc1 +sagemath-standard ~= 10.5rc2 diff --git a/build/pkgs/sagemath_bliss/version_requirements.txt b/build/pkgs/sagemath_bliss/version_requirements.txt index 2368924f603..97488091046 100644 --- a/build/pkgs/sagemath_bliss/version_requirements.txt +++ b/build/pkgs/sagemath_bliss/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.5rc1 +sagemath-bliss ~= 10.5rc2 diff --git a/build/pkgs/sagemath_categories/version_requirements.txt b/build/pkgs/sagemath_categories/version_requirements.txt index 12dbd988f69..38d0f576482 100644 --- a/build/pkgs/sagemath_categories/version_requirements.txt +++ b/build/pkgs/sagemath_categories/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.5rc1 +sagemath-categories ~= 10.5rc2 diff --git a/build/pkgs/sagemath_coxeter3/version_requirements.txt b/build/pkgs/sagemath_coxeter3/version_requirements.txt index 68b68b8849a..74fcc5180f1 100644 --- a/build/pkgs/sagemath_coxeter3/version_requirements.txt +++ b/build/pkgs/sagemath_coxeter3/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.5rc1 +sagemath-coxeter3 ~= 10.5rc2 diff --git a/build/pkgs/sagemath_environment/version_requirements.txt b/build/pkgs/sagemath_environment/version_requirements.txt index 90066e303ad..17b0f996c23 100644 --- a/build/pkgs/sagemath_environment/version_requirements.txt +++ b/build/pkgs/sagemath_environment/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.5rc1 +sagemath-environment ~= 10.5rc2 diff --git a/build/pkgs/sagemath_mcqd/version_requirements.txt b/build/pkgs/sagemath_mcqd/version_requirements.txt index f41ce17c20b..e25bbd7cbf5 100644 --- a/build/pkgs/sagemath_mcqd/version_requirements.txt +++ b/build/pkgs/sagemath_mcqd/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.5rc1 +sagemath-mcqd ~= 10.5rc2 diff --git a/build/pkgs/sagemath_meataxe/version_requirements.txt b/build/pkgs/sagemath_meataxe/version_requirements.txt index f8304228dbc..839d6691290 100644 --- a/build/pkgs/sagemath_meataxe/version_requirements.txt +++ b/build/pkgs/sagemath_meataxe/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.5rc1 +sagemath-meataxe ~= 10.5rc2 diff --git a/build/pkgs/sagemath_objects/version_requirements.txt b/build/pkgs/sagemath_objects/version_requirements.txt index 990a0601e08..2087671be40 100644 --- a/build/pkgs/sagemath_objects/version_requirements.txt +++ b/build/pkgs/sagemath_objects/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.5rc1 +sagemath-objects ~= 10.5rc2 diff --git a/build/pkgs/sagemath_repl/version_requirements.txt b/build/pkgs/sagemath_repl/version_requirements.txt index 7ab5cec5f5b..cf19972eb63 100644 --- a/build/pkgs/sagemath_repl/version_requirements.txt +++ b/build/pkgs/sagemath_repl/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.5rc1 +sagemath-repl ~= 10.5rc2 diff --git a/build/pkgs/sagemath_sirocco/version_requirements.txt b/build/pkgs/sagemath_sirocco/version_requirements.txt index 0863567dacc..eb2af632ca7 100644 --- a/build/pkgs/sagemath_sirocco/version_requirements.txt +++ b/build/pkgs/sagemath_sirocco/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.5rc1 +sagemath-sirocco ~= 10.5rc2 diff --git a/build/pkgs/sagemath_tdlib/version_requirements.txt b/build/pkgs/sagemath_tdlib/version_requirements.txt index 847534f161e..ebd9f2961a9 100644 --- a/build/pkgs/sagemath_tdlib/version_requirements.txt +++ b/build/pkgs/sagemath_tdlib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.5rc1 +sagemath-tdlib ~= 10.5rc2 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index d2205320557..861a196a402 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/src/VERSION.txt b/src/VERSION.txt index d2205320557..861a196a402 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.5.rc1 +10.5.rc2 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index bafb8fc6368..0386f6ef5aa 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.5.rc1' -SAGE_RELEASE_DATE='2024-11-23' -SAGE_VERSION_BANNER='SageMath version 10.5.rc1, Release Date: 2024-11-23' +SAGE_VERSION='10.5.rc2' +SAGE_RELEASE_DATE='2024-11-30' +SAGE_VERSION_BANNER='SageMath version 10.5.rc2, Release Date: 2024-11-30' diff --git a/src/sage/version.py b/src/sage/version.py index eeb9eae6692..8e15dcf37c7 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '10.5.rc1' -date = '2024-11-23' -banner = 'SageMath version 10.5.rc1, Release Date: 2024-11-23' +version = '10.5.rc2' +date = '2024-11-30' +banner = 'SageMath version 10.5.rc2, Release Date: 2024-11-30' From e1d341144e3e6bcc24156a849555a00f3d5effe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 30 Nov 2024 14:47:11 +0100 Subject: [PATCH 176/210] suggested details --- src/sage/sandpiles/sandpile.py | 44 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index 0ecca117630..90201a39116 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -682,71 +682,71 @@ def __getattr__(self, name): if name == '_max_stable_div': self._set_max_stable_div() return deepcopy(self.__dict__[name]) - elif name == '_out_degrees': + if name == '_out_degrees': self._set_out_degrees() return deepcopy(self.__dict__[name]) - elif name == '_in_degrees': + if name == '_in_degrees': self._set_in_degrees() return deepcopy(self.__dict__[name]) - elif name in ['_burning_config', '_burning_script']: + if name in ['_burning_config', '_burning_script']: self._set_burning_config() return deepcopy(self.__dict__[name]) - elif name == '_identity': + if name == '_identity': self._set_identity() return deepcopy(self.__dict__[name]) - elif name == '_recurrents': + if name == '_recurrents': self._set_recurrents() return deepcopy(self.__dict__[name]) - elif name == '_min_recurrents': + if name == '_min_recurrents': self._set_min_recurrents() return deepcopy(self.__dict__[name]) - elif name == '_superstables': + if name == '_superstables': self._set_superstables() return deepcopy(self.__dict__[name]) - elif name == '_group_gens': + if name == '_group_gens': self._set_group_gens() return deepcopy(self.__dict__[name]) elif name == '_group_order': self.__dict__[name] = det(self._reduced_laplacian.dense_matrix()) return self.__dict__[name] - elif name == '_invariant_factors': + if name == '_invariant_factors': self._set_invariant_factors() return deepcopy(self.__dict__[name]) - elif name == '_smith_form': + if name == '_smith_form': self._set_smith_form() return deepcopy(self.__dict__[name]) - elif name == '_jacobian_representatives': + if name == '_jacobian_representatives': self._set_jacobian_representatives() return deepcopy(self.__dict__[name]) - elif name == '_avalanche_polynomial': + if name == '_avalanche_polynomial': self._set_avalanche_polynomial() return deepcopy(self.__dict__[name]) - elif name == '_stationary_density': + if name == '_stationary_density': self._set_stationary_density() return self.__dict__[name] - elif name == '_betti_complexes': + if name == '_betti_complexes': self._set_betti_complexes() return deepcopy(self.__dict__[name]) elif name in ['_postulation', '_h_vector', '_hilbert_function']: self._set_hilbert_function() return deepcopy(self.__dict__[name]) - elif name in ['_ring', '_unsaturated_ideal']: + if name in ['_ring', '_unsaturated_ideal']: self._set_ring() return self.__dict__[name] - elif name == '_ideal': + if name == '_ideal': self._set_ideal() return self.__dict__[name] - elif name in ['_resolution', '_betti', '_singular_resolution']: + if name in ['_resolution', '_betti', '_singular_resolution']: self._set_resolution() return self.__dict__[name] - elif name == '_groebner': + if name == '_groebner': self._set_groebner() return self.__dict__[name] - elif name == '_points': + if name == '_points': self._set_points() return self.__dict__[name] - else: - raise AttributeError(name) + + raise AttributeError(name) def __str__(self) -> str: r""" @@ -2100,7 +2100,7 @@ def stable_configs(self, smax=None): smax = self.max_stable().values() else: c = SandpileConfig(self, smax) - if not c <= self.max_stable(): + if c > self.max_stable(): smax = [min(c[v], self.max_stable()[v]) for v in self.nonsink_vertices()] else: From d4cb8f1bdf780c62d7fa458232e93e6d41e39911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 30 Nov 2024 14:50:10 +0100 Subject: [PATCH 177/210] suggested details --- src/sage/structure/sequence.py | 12 ++++++------ src/sage/structure/set_factories_example.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index 71a67d4e20b..a25e9bf12a6 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -866,20 +866,20 @@ def __getattr__(self, name): if name == "_Sequence_generic__cr" and hasattr(self, "_Sequence__cr"): self.__cr = self._Sequence__cr return self.__cr - elif name == "_Sequence_generic__cr_str" and hasattr(self, "_Sequence__cr_str"): + if name == "_Sequence_generic__cr_str" and hasattr(self, "_Sequence__cr_str"): self.__cr_str = self._Sequence__cr_str return self.__cr_str - elif name == "_Sequence_generic__immutable" and hasattr(self, "_Sequence__immutable"): + if name == "_Sequence_generic__immutable" and hasattr(self, "_Sequence__immutable"): self.__immutable = self._Sequence__immutable return self.__immutable - elif name == "_Sequence_generic__universe" and hasattr(self, "_Sequence__universe"): + if name == "_Sequence_generic__universe" and hasattr(self, "_Sequence__universe"): self.__universe = self._Sequence__universe return self.__universe - elif name == "_Sequence_generic__hash" and hasattr(self, "_Sequence__hash"): + if name == "_Sequence_generic__hash" and hasattr(self, "_Sequence__hash"): self.__hash = self._Sequence__hash return self.__hash - else: - raise AttributeError("'Sequence_generic' object has no attribute '%s'" % name) + + raise AttributeError("'Sequence_generic' object has no attribute '%s'" % name) seq = Sequence diff --git a/src/sage/structure/set_factories_example.py b/src/sage/structure/set_factories_example.py index 0e5a735c532..ba7d0f782e4 100644 --- a/src/sage/structure/set_factories_example.py +++ b/src/sage/structure/set_factories_example.py @@ -99,7 +99,7 @@ def __call__(self, x=None, y=None, policy=None): if isinstance(y, (Integer, int)): return SingletonPair(x, y, policy) return PairsX_(x, policy) - elif isinstance(y, (Integer, int)): + if isinstance(y, (Integer, int)): return Pairs_Y(y, policy) return AllPairs(policy) From d8078d3789b26211ea3c6ac579896298858a7d86 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sat, 30 Nov 2024 23:36:50 +0100 Subject: [PATCH 178/210] PKG_CONFIG must be empty if not found Followup to https://github.com/sagemath/sage/pull/38954, where I followed the pkgconf documentation to set PKG_CONFIG=false if it is not found. But Sage uses "test -z $PKG_CONFIG", so it must instead be set to empty. This causes pkgconf not to be built if pkgconf/pkg-config is not found. Which is basically only macOS. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 1bf79ed7333..067b10c99d8 100644 --- a/configure.ac +++ b/configure.ac @@ -222,7 +222,7 @@ dnl Exit autoconf with exit code 16 in this case. This will be dnl caught by the bootstrap script. m4_exit(16)]) -PKG_PROG_PKG_CONFIG([0.29], [PKG_CONFIG=false]) +PKG_PROG_PKG_CONFIG([0.29], [PKG_CONFIG=]) AC_CHECK_PROG(found_ranlib, ranlib, yes, no) if test x$found_ranlib != xyes From 7412221144e7c507050c7b772764a72184582bc4 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 1 Dec 2024 13:36:24 +0800 Subject: [PATCH 179/210] Fix import formatting in `sage.manifolds` --- src/sage/manifolds/all.py | 1 + src/sage/manifolds/calculus_method.py | 12 ++-- src/sage/manifolds/catalog.py | 5 +- src/sage/manifolds/chart.py | 26 +++---- src/sage/manifolds/chart_func.py | 12 ++-- src/sage/manifolds/continuous_map.py | 6 +- .../differentiable/affine_connection.py | 13 ++-- .../differentiable/automorphismfield.py | 4 +- .../differentiable/automorphismfield_group.py | 16 +++-- .../differentiable/bundle_connection.py | 7 +- .../characteristic_cohomology_class.py | 22 +++--- src/sage/manifolds/differentiable/chart.py | 4 +- src/sage/manifolds/differentiable/curve.py | 12 ++-- .../differentiable/de_rham_cohomology.py | 12 ++-- .../manifolds/differentiable/degenerate.py | 7 +- .../differentiable/degenerate_submanifold.py | 14 ++-- .../manifolds/differentiable/diff_form.py | 24 ++++--- .../differentiable/diff_form_module.py | 12 ++-- .../differentiable/examples/euclidean.py | 14 ++-- .../differentiable/examples/real_line.py | 8 +-- .../differentiable/examples/sphere.py | 14 ++-- .../examples/symplectic_space.py | 6 +- .../examples/symplectic_space_test.py | 5 +- .../differentiable/integrated_curve.py | 24 +++---- .../differentiable/levi_civita_connection.py | 6 +- src/sage/manifolds/differentiable/manifold.py | 28 +++++--- .../differentiable/manifold_homset.py | 21 +++--- src/sage/manifolds/differentiable/metric.py | 5 +- .../manifolds/differentiable/mixed_form.py | 25 ++++--- .../differentiable/mixed_form_algebra.py | 12 ++-- .../differentiable/multivector_module.py | 10 +-- .../differentiable/multivectorfield.py | 8 +-- .../differentiable/poisson_tensor.py | 9 +-- .../differentiable/pseudo_riemannian.py | 9 ++- .../pseudo_riemannian_submanifold.py | 20 +++--- .../manifolds/differentiable/scalarfield.py | 8 ++- .../differentiable/scalarfield_algebra.py | 4 +- .../differentiable/symplectic_form.py | 13 ++-- .../differentiable/symplectic_form_test.py | 10 +-- .../differentiable/tangent_vector.py | 12 ++-- .../manifolds/differentiable/tensorfield.py | 22 +++--- .../differentiable/tensorfield_module.py | 47 +++++++------ .../differentiable/tensorfield_paral.py | 2 +- .../manifolds/differentiable/vector_bundle.py | 12 ++-- .../manifolds/differentiable/vectorfield.py | 14 ++-- .../differentiable/vectorfield_module.py | 68 +++++++++++-------- .../manifolds/differentiable/vectorframe.py | 7 +- src/sage/manifolds/family.py | 1 + src/sage/manifolds/local_frame.py | 5 +- src/sage/manifolds/manifold.py | 18 +++-- src/sage/manifolds/manifold_homset.py | 4 +- src/sage/manifolds/point.py | 10 +-- src/sage/manifolds/scalarfield.py | 36 ++++++---- src/sage/manifolds/scalarfield_algebra.py | 10 +-- src/sage/manifolds/section.py | 10 +-- src/sage/manifolds/section_module.py | 12 ++-- src/sage/manifolds/structure.py | 12 ++-- src/sage/manifolds/subset.py | 16 +++-- src/sage/manifolds/subsets/pullback.py | 20 +++--- src/sage/manifolds/topological_submanifold.py | 7 +- src/sage/manifolds/trivialization.py | 2 +- src/sage/manifolds/utilities.py | 13 ++-- src/sage/manifolds/vector_bundle.py | 20 +++--- src/sage/manifolds/vector_bundle_fiber.py | 2 +- 64 files changed, 470 insertions(+), 380 deletions(-) diff --git a/src/sage/manifolds/all.py b/src/sage/manifolds/all.py index e219a98dc32..425199da31a 100644 --- a/src/sage/manifolds/all.py +++ b/src/sage/manifolds/all.py @@ -1,4 +1,5 @@ from sage.misc.lazy_import import lazy_import + lazy_import('sage.manifolds.manifold', 'Manifold') lazy_import('sage.manifolds.differentiable.examples.euclidean', 'EuclideanSpace') lazy_import('sage.manifolds', 'catalog', 'manifolds') diff --git a/src/sage/manifolds/calculus_method.py b/src/sage/manifolds/calculus_method.py index a4888559c0f..f7193b12c16 100644 --- a/src/sage/manifolds/calculus_method.py +++ b/src/sage/manifolds/calculus_method.py @@ -19,13 +19,15 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # ***************************************************************************** +from sage.manifolds.utilities import ( + simplify_chain_generic, + simplify_chain_generic_sympy, + simplify_chain_real, + simplify_chain_real_sympy, +) +from sage.misc.latex import latex from sage.structure.sage_object import SageObject from sage.symbolic.ring import SR -from sage.manifolds.utilities import (simplify_chain_real, - simplify_chain_generic, - simplify_chain_real_sympy, - simplify_chain_generic_sympy,) -from sage.misc.latex import latex try: import sympy diff --git a/src/sage/manifolds/catalog.py b/src/sage/manifolds/catalog.py index c3c40c42b9a..fb6ba5634f2 100644 --- a/src/sage/manifolds/catalog.py +++ b/src/sage/manifolds/catalog.py @@ -34,6 +34,7 @@ # Lazy import from examples folders: from sage.misc.lazy_import import lazy_import as _lazy_import + _lazy_import('sage.manifolds.differentiable.examples.real_line', 'OpenInterval') _lazy_import('sage.manifolds.differentiable.examples.real_line', 'RealLine') _lazy_import('sage.manifolds.differentiable.examples.euclidean', 'EuclideanSpace') @@ -172,9 +173,9 @@ def Kerr(m=1, a=0, coordinates='BL', names=None): sage: K.default_chart().coord_range() t: (-oo, +oo); r: (0, +oo); th: (0, pi); ph: [-pi, pi] (periodic) """ - from sage.misc.functional import sqrt from sage.functions.trig import cos, sin from sage.manifolds.manifold import Manifold + from sage.misc.functional import sqrt M = Manifold(4, 'M', structure='Lorentzian') if coordinates == "Kerr": if names is None: @@ -252,8 +253,8 @@ def Torus(R=2, r=1, names=None): gamma = dtheta⊗dtheta + (cos(theta)^2 + 6*cos(theta) + 9) dphi⊗dphi """ from sage.functions.trig import cos, sin - from sage.manifolds.manifold import Manifold from sage.manifolds.differentiable.examples.euclidean import EuclideanSpace + from sage.manifolds.manifold import Manifold E = EuclideanSpace(3, symbols='X Y Z') M = Manifold(2, 'T', ambient=E, structure='Riemannian') if names is None: diff --git a/src/sage/manifolds/chart.py b/src/sage/manifolds/chart.py index d0d3148be7e..f20a0e2bab4 100644 --- a/src/sage/manifolds/chart.py +++ b/src/sage/manifolds/chart.py @@ -36,16 +36,16 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +from sage.ext.fast_callable import fast_callable +from sage.manifolds.calculus_method import CalculusMethod +from sage.manifolds.chart_func import ChartFunctionRing +from sage.misc.decorators import options +from sage.misc.latex import latex +from sage.rings.infinity import Infinity from sage.structure.sage_object import SageObject from sage.structure.unique_representation import UniqueRepresentation -from sage.symbolic.ring import SR -from sage.rings.infinity import Infinity -from sage.misc.latex import latex -from sage.misc.decorators import options -from sage.manifolds.chart_func import ChartFunctionRing -from sage.manifolds.calculus_method import CalculusMethod from sage.symbolic.expression import Expression -from sage.ext.fast_callable import fast_callable +from sage.symbolic.ring import SR class Chart(UniqueRepresentation, SageObject): @@ -1216,7 +1216,7 @@ def preimage(self, codomain_subset, name=None, latex_name=None): sage: R((-2,)) in McZ True """ - from .subsets.pullback import ManifoldSubsetPullback + from sage.manifolds.subsets.pullback import ManifoldSubsetPullback return ManifoldSubsetPullback(self, codomain_subset, name=name, latex_name=latex_name) @@ -2053,9 +2053,9 @@ def codomain(self): sage: c_spher1.codomain() The Cartesian product of ((0, +oo), (0, pi), [0, 2*pi)) """ - from sage.sets.real_set import RealSet - from sage.modules.free_module import VectorSpace from sage.categories.cartesian_product import cartesian_product + from sage.modules.free_module import VectorSpace + from sage.sets.real_set import RealSet intervals = tuple(RealSet.interval(xmin, xmax, lower_closed=(min_included == 'periodic' or min_included), upper_closed=(max_included != 'periodic' and max_included)) @@ -2554,7 +2554,7 @@ def valid_coordinates_numerical(self, *coordinates): return self._fast_valid_coordinates(*coordinates) # case fast callable has to be computed - from operator import lt, gt + from operator import gt, lt if not isinstance(self._restrictions, (list, set, frozenset)): if isinstance(self._restrictions, tuple): @@ -3003,11 +3003,11 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, sage: X.plot.reset() """ + from sage.manifolds.continuous_map import ContinuousMap + from sage.manifolds.utilities import set_axes_labels from sage.misc.functional import numerical_approx from sage.plot.graphics import Graphics from sage.plot.line import line - from sage.manifolds.continuous_map import ContinuousMap - from sage.manifolds.utilities import set_axes_labels # Extract the kwds options max_range = kwds['max_range'] diff --git a/src/sage/manifolds/chart_func.py b/src/sage/manifolds/chart_func.py index aae7a2b1fff..77006d5459a 100644 --- a/src/sage/manifolds/chart_func.py +++ b/src/sage/manifolds/chart_func.py @@ -32,16 +32,16 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.structure.element import AlgebraElement, ModuleElementWithMutability -from sage.structure.parent import Parent -from sage.structure.sage_object import SageObject -from sage.structure.unique_representation import UniqueRepresentation from sage.categories.commutative_algebras import CommutativeAlgebras from sage.manifolds.utilities import ExpressionNice from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import lazy_import -from sage.symbolic.ring import SR +from sage.structure.element import AlgebraElement, ModuleElementWithMutability from sage.structure.mutability import Mutability +from sage.structure.parent import Parent +from sage.structure.sage_object import SageObject +from sage.structure.unique_representation import UniqueRepresentation +from sage.symbolic.ring import SR try: import sympy @@ -671,8 +671,8 @@ def display(self): sage: X.zero_function().display() (x, y) ↦ 0 """ - from sage.typeset.unicode_characters import unicode_mapsto from sage.tensor.modules.format_utilities import FormattedExpansion + from sage.typeset.unicode_characters import unicode_mapsto curr = self._calc_method._current expr = self.expr(curr) if (curr == 'SR' and diff --git a/src/sage/manifolds/continuous_map.py b/src/sage/manifolds/continuous_map.py index 2c30b796aab..d8158deb1ce 100644 --- a/src/sage/manifolds/continuous_map.py +++ b/src/sage/manifolds/continuous_map.py @@ -843,7 +843,7 @@ def image(self, subset=None, inverse=None): sage: Phi_S.is_subset(M) True """ - from .continuous_map_image import ImageManifoldSubset + from sage.manifolds.continuous_map_image import ImageManifoldSubset if self._is_identity: if subset is None: return self.domain() @@ -1166,8 +1166,8 @@ def display(self, chart1=None, chart2=None): \end{array} """ from sage.misc.latex import latex - from sage.typeset.unicode_characters import unicode_to, unicode_mapsto from sage.tensor.modules.format_utilities import FormattedExpansion + from sage.typeset.unicode_characters import unicode_mapsto, unicode_to def _display_expression(self, chart1, chart2, result): r""" @@ -2045,8 +2045,8 @@ def __invert__(self): sage: si == s True """ - from sage.symbolic.ring import SR from sage.symbolic.relation import solve + from sage.symbolic.ring import SR if self._inverse is not None: return self._inverse if not self._is_isomorphism: diff --git a/src/sage/manifolds/differentiable/affine_connection.py b/src/sage/manifolds/differentiable/affine_connection.py index 73b6e5d42cd..a52c82ee1cc 100644 --- a/src/sage/manifolds/differentiable/affine_connection.py +++ b/src/sage/manifolds/differentiable/affine_connection.py @@ -28,12 +28,12 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.rings.integer import Integer -from sage.structure.sage_object import SageObject -from sage.misc.cachefunc import cached_method from sage.manifolds.differentiable.manifold import DifferentiableManifold +from sage.misc.cachefunc import cached_method from sage.parallel.decorate import parallel from sage.parallel.parallelism import Parallelism +from sage.rings.integer import Integer +from sage.structure.sage_object import SageObject class AffineConnection(SageObject): @@ -603,8 +603,8 @@ def _new_coef(self, frame): sage: nab._new_coef(X.frame()) 3-indices components w.r.t. Coordinate frame (M, (∂/∂x,∂/∂y)) """ - from sage.tensor.modules.comp import Components from sage.manifolds.differentiable.scalarfield import DiffScalarField + from sage.tensor.modules.comp import Components return Components(frame._domain.scalar_field_algebra(), frame, 3, start_index=self._domain._sindex, output_formatter=DiffScalarField.coord_function) @@ -1306,8 +1306,8 @@ def display(self, frame=None, chart=None, symbol=None, latex_symbol=None, Gam^ph_ph,r = 1/r Gam^ph_ph,th = cos(th)/sin(th) """ - from sage.misc.latex import latex from sage.manifolds.differentiable.vectorframe import CoordFrame + from sage.misc.latex import latex if frame is None: frame = self._domain.default_frame() if chart is None: @@ -1503,8 +1503,7 @@ def __call__(self, tensor): :class:`~sage.manifolds.differentiable.affine_connection.AffineConnection` for more examples. """ - from sage.manifolds.differentiable.tensorfield_paral import \ - TensorFieldParal + from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal from sage.tensor.modules.format_utilities import format_unop_latex dom_resu = self._domain.intersection(tensor._domain) tensor_r = tensor.restrict(dom_resu) diff --git a/src/sage/manifolds/differentiable/automorphismfield.py b/src/sage/manifolds/differentiable/automorphismfield.py index 3556fc56e95..c8f2143beb2 100644 --- a/src/sage/manifolds/differentiable/automorphismfield.py +++ b/src/sage/manifolds/differentiable/automorphismfield.py @@ -24,9 +24,9 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.tensor.modules.free_module_automorphism import FreeModuleAutomorphism from sage.manifolds.differentiable.tensorfield import TensorField from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal +from sage.tensor.modules.free_module_automorphism import FreeModuleAutomorphism class AutomorphismField(TensorField): @@ -1168,9 +1168,9 @@ def __invert__(self): sage: b is ~a True """ + from sage.manifolds.differentiable.vectorframe import CoordFrame from sage.matrix.constructor import matrix from sage.tensor.modules.comp import Components - from sage.manifolds.differentiable.vectorframe import CoordFrame if self._is_identity: return self if self._inverse is None: diff --git a/src/sage/manifolds/differentiable/automorphismfield_group.py b/src/sage/manifolds/differentiable/automorphismfield_group.py index c6315670c9e..45a2fad087a 100644 --- a/src/sage/manifolds/differentiable/automorphismfield_group.py +++ b/src/sage/manifolds/differentiable/automorphismfield_group.py @@ -38,15 +38,19 @@ # http://www.gnu.org/licenses/ #****************************************************************************** -from sage.structure.unique_representation import UniqueRepresentation -from sage.structure.parent import Parent from sage.categories.groups import Groups +from sage.manifolds.differentiable.automorphismfield import ( + AutomorphismField, + AutomorphismFieldParal, +) +from sage.manifolds.differentiable.vectorfield_module import ( + VectorFieldFreeModule, + VectorFieldModule, +) from sage.misc.cachefunc import cached_method +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation from sage.tensor.modules.free_module_linear_group import FreeModuleLinearGroup -from sage.manifolds.differentiable.vectorfield_module import (VectorFieldModule, - VectorFieldFreeModule) -from sage.manifolds.differentiable.automorphismfield import (AutomorphismField, - AutomorphismFieldParal) class AutomorphismFieldGroup(UniqueRepresentation, Parent): diff --git a/src/sage/manifolds/differentiable/bundle_connection.py b/src/sage/manifolds/differentiable/bundle_connection.py index 184e9641eeb..35d70c2e847 100644 --- a/src/sage/manifolds/differentiable/bundle_connection.py +++ b/src/sage/manifolds/differentiable/bundle_connection.py @@ -38,11 +38,10 @@ # https://www.gnu.org/licenses/ # ****************************************************************************** -from sage.structure.sage_object import SageObject -from sage.structure.mutability import Mutability +from sage.manifolds.differentiable.vector_bundle import DifferentiableVectorBundle from sage.rings.integer import Integer -from sage.manifolds.differentiable.vector_bundle import \ - DifferentiableVectorBundle +from sage.structure.mutability import Mutability +from sage.structure.sage_object import SageObject class BundleConnection(SageObject, Mutability): diff --git a/src/sage/manifolds/differentiable/characteristic_cohomology_class.py b/src/sage/manifolds/differentiable/characteristic_cohomology_class.py index 51f32ffb4b8..935b05a59fd 100644 --- a/src/sage/manifolds/differentiable/characteristic_cohomology_class.py +++ b/src/sage/manifolds/differentiable/characteristic_cohomology_class.py @@ -282,16 +282,16 @@ from sage.algebras.finite_gca import FiniteGCAlgebra from sage.combinat.free_module import IndexedFreeModuleElement -from sage.misc.fast_methods import Singleton -from sage.structure.sage_object import SageObject -from sage.misc.cachefunc import cached_method +from sage.manifolds.differentiable.affine_connection import AffineConnection +from sage.manifolds.differentiable.bundle_connection import BundleConnection +from sage.manifolds.differentiable.levi_civita_connection import LeviCivitaConnection from sage.misc.abstract_method import abstract_method -from .affine_connection import AffineConnection -from .bundle_connection import BundleConnection -from .levi_civita_connection import LeviCivitaConnection -from sage.symbolic.expression import Expression +from sage.misc.cachefunc import cached_method +from sage.misc.fast_methods import Singleton from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.structure.sage_object import SageObject +from sage.symbolic.expression import Expression class CharacteristicCohomologyClassRingElement(IndexedFreeModuleElement): @@ -894,7 +894,7 @@ def _build_element(self, *args, **kwargs): # predefined classes accessible via class names if isinstance(val, str): - from sage.arith.misc import factorial, bernoulli + from sage.arith.misc import bernoulli, factorial P = PolynomialRing(base_ring, 'x') x = P.gen() @@ -1085,8 +1085,8 @@ def multiplicative_sequence(q, n=None): e[] + e[1] - e[1, 1] + 3*e[2] - e[2, 1] + e[2, 2] + 4*e[3] - 3*e[3, 1] + e[3, 2] + 7*e[4] - 4*e[4, 1] + 11*e[5] """ - from sage.combinat.sf.sf import SymmetricFunctions from sage.combinat.partition import Partitions + from sage.combinat.sf.sf import SymmetricFunctions from sage.misc.misc_c import prod if n is None: @@ -1140,8 +1140,8 @@ def additive_sequence(q, k, n=None): sage: sym_1 = additive_sequence(f, 2, 1); sym_1 2*e[] + e[1] """ - from sage.combinat.sf.sf import SymmetricFunctions from sage.combinat.partition import Partitions + from sage.combinat.sf.sf import SymmetricFunctions if n is None: n = q.degree() @@ -1427,7 +1427,7 @@ def get_local(self, cmat): sage: algorithm.get_local(cmat) [2-form on the 2-dimensional Lorentzian manifold M] """ - from sage.symbolic.constants import pi, I + from sage.symbolic.constants import I, pi dom = cmat[0][0]._domain rk = len(cmat) diff --git a/src/sage/manifolds/differentiable/chart.py b/src/sage/manifolds/differentiable/chart.py index bcfa37dc237..c944a9d7815 100644 --- a/src/sage/manifolds/differentiable/chart.py +++ b/src/sage/manifolds/differentiable/chart.py @@ -31,9 +31,9 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.misc.cachefunc import cached_method -from sage.manifolds.chart import Chart, RealChart, CoordChange +from sage.manifolds.chart import Chart, CoordChange, RealChart from sage.manifolds.differentiable.vectorframe import CoordFrame +from sage.misc.cachefunc import cached_method class DiffChart(Chart): diff --git a/src/sage/manifolds/differentiable/curve.py b/src/sage/manifolds/differentiable/curve.py index e28e44b8adb..8a1cfc2e77e 100644 --- a/src/sage/manifolds/differentiable/curve.py +++ b/src/sage/manifolds/differentiable/curve.py @@ -32,10 +32,10 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.misc.latex import latex -from sage.misc.decorators import options -from sage.manifolds.point import ManifoldPoint from sage.manifolds.differentiable.diff_map import DiffMap +from sage.manifolds.point import ManifoldPoint +from sage.misc.decorators import options +from sage.misc.latex import latex class DifferentiableCurve(DiffMap): @@ -871,9 +871,9 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, prange=None, g = c.plot(parameters={a: 2, b: -3}, aspect_ratio=1) sphinx_plot(g) """ - from sage.rings.infinity import Infinity - from sage.misc.functional import numerical_approx from sage.manifolds.chart import RealChart + from sage.misc.functional import numerical_approx + from sage.rings.infinity import Infinity # # Get the @options from kwds @@ -995,9 +995,9 @@ def _graphics(self, plot_curve, ambient_coords, thickness=1, sage: graph._extra_kwds['axes_labels'] == l True """ + from sage.manifolds.utilities import set_axes_labels from sage.plot.graphics import Graphics from sage.plot.line import line - from sage.manifolds.utilities import set_axes_labels # # The plot diff --git a/src/sage/manifolds/differentiable/de_rham_cohomology.py b/src/sage/manifolds/differentiable/de_rham_cohomology.py index 9bc766f5a78..729ed375afa 100644 --- a/src/sage/manifolds/differentiable/de_rham_cohomology.py +++ b/src/sage/manifolds/differentiable/de_rham_cohomology.py @@ -45,13 +45,15 @@ # https://www.gnu.org/licenses/ #****************************************************************************** -from sage.structure.unique_representation import UniqueRepresentation +from sage.categories.algebras import Algebras +from sage.manifolds.differentiable.characteristic_cohomology_class import ( + CharacteristicCohomologyClassRing, + CharacteristicCohomologyClassRingElement, +) from sage.misc.cachefunc import cached_method -from sage.structure.parent import Parent from sage.structure.element import AlgebraElement -from sage.categories.algebras import Algebras -from .characteristic_cohomology_class import (CharacteristicCohomologyClassRing, - CharacteristicCohomologyClassRingElement) +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation class DeRhamCohomologyClass(AlgebraElement): diff --git a/src/sage/manifolds/differentiable/degenerate.py b/src/sage/manifolds/differentiable/degenerate.py index b34fefc3a89..80da669f083 100644 --- a/src/sage/manifolds/differentiable/degenerate.py +++ b/src/sage/manifolds/differentiable/degenerate.py @@ -11,11 +11,12 @@ # ***************************************************************************** from __future__ import annotations + from typing import TYPE_CHECKING -from sage.rings.infinity import infinity -from sage.manifolds.structure import DegenerateStructure from sage.manifolds.differentiable.manifold import DifferentiableManifold +from sage.manifolds.structure import DegenerateStructure +from sage.rings.infinity import infinity if TYPE_CHECKING: from sage.manifolds.differentiable.metric import DegenerateMetric @@ -368,8 +369,8 @@ def open_subset(self, name, latex_name=None, coord_def={}): #******************************************************************************************* -from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal from sage.manifolds.differentiable.tensorfield import TensorField +from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal class TangentTensor(TensorFieldParal): diff --git a/src/sage/manifolds/differentiable/degenerate_submanifold.py b/src/sage/manifolds/differentiable/degenerate_submanifold.py index a119fb57802..fcb843a8abe 100644 --- a/src/sage/manifolds/differentiable/degenerate_submanifold.py +++ b/src/sage/manifolds/differentiable/degenerate_submanifold.py @@ -156,17 +156,17 @@ # ***************************************************************************** from __future__ import annotations + from typing import TYPE_CHECKING -from sage.manifolds.differentiable.pseudo_riemannian import \ - PseudoRiemannianManifold -from sage.manifolds.differentiable.degenerate import (DegenerateManifold, - TangentTensor) -from sage.manifolds.differentiable.differentiable_submanifold import \ - DifferentiableSubmanifold +from sage.manifolds.differentiable.degenerate import DegenerateManifold, TangentTensor +from sage.manifolds.differentiable.differentiable_submanifold import ( + DifferentiableSubmanifold, +) +from sage.manifolds.differentiable.pseudo_riemannian import PseudoRiemannianManifold from sage.manifolds.differentiable.vectorfield_module import VectorFieldModule -from sage.rings.infinity import infinity from sage.matrix.constructor import matrix +from sage.rings.infinity import infinity from sage.symbolic.expression import Expression if TYPE_CHECKING: diff --git a/src/sage/manifolds/differentiable/diff_form.py b/src/sage/manifolds/differentiable/diff_form.py index fb58189796e..0457b815d8a 100644 --- a/src/sage/manifolds/differentiable/diff_form.py +++ b/src/sage/manifolds/differentiable/diff_form.py @@ -44,16 +44,18 @@ # ***************************************************************************** from __future__ import annotations -from typing import Optional, Union, TYPE_CHECKING -from sage.misc.cachefunc import cached_method -from sage.tensor.modules.free_module_alt_form import FreeModuleAltForm + +from typing import TYPE_CHECKING, Optional, Union + from sage.manifolds.differentiable.tensorfield import TensorField from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal +from sage.misc.cachefunc import cached_method +from sage.tensor.modules.free_module_alt_form import FreeModuleAltForm if TYPE_CHECKING: - from sage.manifolds.differentiable.vectorfield_module import VectorFieldModule from sage.manifolds.differentiable.metric import PseudoRiemannianMetric from sage.manifolds.differentiable.symplectic_form import SymplecticForm + from sage.manifolds.differentiable.vectorfield_module import VectorFieldModule class DiffForm(TensorField): @@ -442,8 +444,8 @@ def exterior_derivative(self) -> DiffForm: True """ from sage.tensor.modules.format_utilities import ( - format_unop_txt, format_unop_latex, + format_unop_txt, ) vmodule = self._vmodule # shortcut @@ -525,8 +527,8 @@ def wedge(self, other: DiffForm) -> DiffForm: """ if other._tensor_rank == 0: return self * other - from sage.typeset.unicode_characters import unicode_wedge from sage.tensor.modules.format_utilities import is_atomic + from sage.typeset.unicode_characters import unicode_wedge if self._domain.is_subset(other._domain): if not self._ambient_domain.is_subset(other._ambient_domain): raise ValueError("incompatible ambient domains for exterior product") @@ -762,8 +764,8 @@ def hodge_dual( """ from sage.functions.other import factorial from sage.tensor.modules.format_utilities import ( - format_unop_txt, format_unop_latex, + format_unop_txt, ) if nondegenerate_tensor is None: @@ -1438,10 +1440,12 @@ def exterior_derivative(self) -> DiffFormParal: sage: a.lie_der(v) == v.contract(diff(a)) + diff(a(v)) # long time True """ - from sage.tensor.modules.format_utilities import (format_unop_txt, - format_unop_latex) - from sage.tensor.modules.comp import CompFullyAntiSym from sage.manifolds.differentiable.vectorframe import CoordFrame + from sage.tensor.modules.comp import CompFullyAntiSym + from sage.tensor.modules.format_utilities import ( + format_unop_latex, + format_unop_txt, + ) fmodule = self._fmodule # shortcut rname = format_unop_txt('d', self._name) rlname = format_unop_latex(r'\mathrm{d}', self._latex_name) diff --git a/src/sage/manifolds/differentiable/diff_form_module.py b/src/sage/manifolds/differentiable/diff_form_module.py index ee0dd856697..d79686fb7b6 100644 --- a/src/sage/manifolds/differentiable/diff_form_module.py +++ b/src/sage/manifolds/differentiable/diff_form_module.py @@ -38,14 +38,14 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.misc.cachefunc import cached_method -from sage.structure.unique_representation import UniqueRepresentation -from sage.structure.parent import Parent from sage.categories.modules import Modules -from sage.tensor.modules.ext_pow_free_module import ExtPowerDualFreeModule from sage.manifolds.differentiable.diff_form import DiffForm, DiffFormParal from sage.manifolds.differentiable.tensorfield import TensorField from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal +from sage.misc.cachefunc import cached_method +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation +from sage.tensor.modules.ext_pow_free_module import ExtPowerDualFreeModule from sage.tensor.modules.reflexive_module import ReflexiveModule_abstract @@ -863,7 +863,9 @@ def _coerce_map_from_(self, other): and self._domain.is_subset(other._domain) and self._ambient_domain.is_subset(other._ambient_domain)) - from sage.manifolds.differentiable.tensorfield_module import TensorFieldFreeModule + from sage.manifolds.differentiable.tensorfield_module import ( + TensorFieldFreeModule, + ) if isinstance(other, TensorFieldFreeModule): # coercion of a type-(0,1) tensor to a linear form return (self._fmodule is other._fmodule and self._degree == 1 diff --git a/src/sage/manifolds/differentiable/examples/euclidean.py b/src/sage/manifolds/differentiable/examples/euclidean.py index ec0f30be82c..433993d36ad 100644 --- a/src/sage/manifolds/differentiable/examples/euclidean.py +++ b/src/sage/manifolds/differentiable/examples/euclidean.py @@ -408,14 +408,13 @@ # https://www.gnu.org/licenses/ #***************************************************************************** -from sage.functions.trig import cos, sin, atan2 +from sage.categories.manifolds import Manifolds +from sage.categories.metric_spaces import MetricSpaces +from sage.functions.trig import atan2, cos, sin +from sage.manifolds.differentiable.pseudo_riemannian import PseudoRiemannianManifold from sage.misc.functional import sqrt from sage.misc.latex import latex from sage.rings.real_mpfr import RR -from sage.categories.manifolds import Manifolds -from sage.categories.metric_spaces import MetricSpaces -from sage.manifolds.differentiable.pseudo_riemannian import \ - PseudoRiemannianManifold ############################################################################### @@ -696,8 +695,9 @@ def __classcall_private__(cls, n=None, name=None, latex_name=None, symbols = ' '.join(names) # Technical bit for UniqueRepresentation - from sage.misc.prandom import getrandbits from time import time + + from sage.misc.prandom import getrandbits if unique_tag is None: unique_tag = getrandbits(128) * time() @@ -1035,7 +1035,7 @@ def sphere(self, radius=1, center=None, name=None, latex_name=None, n = self._dim if n == 1: raise ValueError('Euclidean space must have dimension of at least 2') - from .sphere import Sphere + from sage.manifolds.differentiable.examples.sphere import Sphere return Sphere(n-1, radius=radius, ambient_space=self, center=center, name=name, latex_name=latex_name, coordinates=coordinates, names=names) diff --git a/src/sage/manifolds/differentiable/examples/real_line.py b/src/sage/manifolds/differentiable/examples/real_line.py index 52b3dfad182..ef71608529e 100644 --- a/src/sage/manifolds/differentiable/examples/real_line.py +++ b/src/sage/manifolds/differentiable/examples/real_line.py @@ -24,14 +24,14 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +from sage.categories.manifolds import Manifolds +from sage.manifolds.differentiable.manifold import DifferentiableManifold +from sage.manifolds.structure import RealDifferentialStructure from sage.misc.latex import latex from sage.rings.infinity import infinity, minus_infinity -from sage.symbolic.ring import SR from sage.rings.real_mpfr import RR +from sage.symbolic.ring import SR from sage.typeset.unicode_characters import unicode_mathbbR -from sage.manifolds.differentiable.manifold import DifferentiableManifold -from sage.manifolds.structure import RealDifferentialStructure -from sage.categories.manifolds import Manifolds class OpenInterval(DifferentiableManifold): diff --git a/src/sage/manifolds/differentiable/examples/sphere.py b/src/sage/manifolds/differentiable/examples/sphere.py index 43956a3ba1a..f1add71e110 100644 --- a/src/sage/manifolds/differentiable/examples/sphere.py +++ b/src/sage/manifolds/differentiable/examples/sphere.py @@ -165,13 +165,14 @@ eps_g = -dchi """ -from sage.manifolds.differentiable.pseudo_riemannian_submanifold import \ - PseudoRiemannianSubmanifold -from sage.categories.metric_spaces import MetricSpaces from sage.categories.manifolds import Manifolds +from sage.categories.metric_spaces import MetricSpaces from sage.categories.topological_spaces import TopologicalSpaces -from sage.rings.real_mpfr import RR from sage.manifolds.differentiable.examples.euclidean import EuclideanSpace +from sage.manifolds.differentiable.pseudo_riemannian_submanifold import ( + PseudoRiemannianSubmanifold, +) +from sage.rings.real_mpfr import RR class Sphere(PseudoRiemannianSubmanifold): @@ -315,8 +316,9 @@ def __classcall_private__(cls, n=None, radius=1, ambient_space=None, n = len(names) # Technical bit for UniqueRepresentation - from sage.misc.prandom import getrandbits from time import time + + from sage.misc.prandom import getrandbits if unique_tag is None: unique_tag = getrandbits(128) * time() @@ -609,8 +611,8 @@ def _init_spherical(self, names=None): A.set_default_frame(spher.frame()) # manage embedding... - from sage.misc.misc_c import prod from sage.functions.trig import cos, sin + from sage.misc.misc_c import prod R = self._radius diff --git a/src/sage/manifolds/differentiable/examples/symplectic_space.py b/src/sage/manifolds/differentiable/examples/symplectic_space.py index 5a78277d567..41d7defe25a 100644 --- a/src/sage/manifolds/differentiable/examples/symplectic_space.py +++ b/src/sage/manifolds/differentiable/examples/symplectic_space.py @@ -20,8 +20,10 @@ from sage.categories.manifolds import Manifolds from sage.manifolds.differentiable.examples.euclidean import EuclideanSpace -from sage.manifolds.differentiable.symplectic_form import (SymplecticForm, - SymplecticFormParal) +from sage.manifolds.differentiable.symplectic_form import ( + SymplecticForm, + SymplecticFormParal, +) from sage.rings.real_mpfr import RR diff --git a/src/sage/manifolds/differentiable/examples/symplectic_space_test.py b/src/sage/manifolds/differentiable/examples/symplectic_space_test.py index 9cfdf6da123..ca3dbcc5f41 100644 --- a/src/sage/manifolds/differentiable/examples/symplectic_space_test.py +++ b/src/sage/manifolds/differentiable/examples/symplectic_space_test.py @@ -1,9 +1,10 @@ +import pytest + import sage.all -from sage.manifolds.differentiable.symplectic_form import SymplecticForm from sage.manifolds.differentiable.examples.symplectic_space import ( StandardSymplecticSpace, ) -import pytest +from sage.manifolds.differentiable.symplectic_form import SymplecticForm class TestR2VectorSpace: diff --git a/src/sage/manifolds/differentiable/integrated_curve.py b/src/sage/manifolds/differentiable/integrated_curve.py index 17784f555e1..77d6a419325 100644 --- a/src/sage/manifolds/differentiable/integrated_curve.py +++ b/src/sage/manifolds/differentiable/integrated_curve.py @@ -106,21 +106,21 @@ # https://www.gnu.org/licenses/ # ********************************************************************** -from sage.symbolic.expression import Expression -from sage.rings.infinity import Infinity -from sage.calculus.desolvers import desolve_system_rk4 -from sage.calculus.desolvers import desolve_odeint +from random import shuffle + +from sage.arith.srange import srange +from sage.calculus.desolvers import desolve_odeint, desolve_system_rk4 +from sage.calculus.interpolation import Spline +from sage.ext.fast_callable import fast_callable from sage.manifolds.chart import Chart from sage.manifolds.differentiable.curve import DifferentiableCurve from sage.manifolds.differentiable.tangent_vector import TangentVector -from sage.calculus.interpolation import Spline from sage.misc.decorators import options from sage.misc.functional import numerical_approx from sage.misc.lazy_import import lazy_import -from sage.arith.srange import srange -from sage.ext.fast_callable import fast_callable +from sage.rings.infinity import Infinity +from sage.symbolic.expression import Expression from sage.symbolic.ring import SR -from random import shuffle lazy_import('scipy.integrate', 'ode') @@ -857,9 +857,9 @@ def solve_analytical(self, verbose=False): Dx3_0*t + x3_0) """ - from sage.calculus.var import function - from sage.calculus.functional import diff from sage.calculus.desolvers import desolve_system + from sage.calculus.functional import diff + from sage.calculus.var import function from sage.symbolic.assumptions import assume, forget from sage.symbolic.ring import var @@ -2559,8 +2559,8 @@ def plot_integrated(self, chart=None, ambient_coords=None, t += dt if display_tangent: - from sage.plot.graphics import Graphics from sage.plot.arrow import arrow2d + from sage.plot.graphics import Graphics from sage.plot.plot3d.shapes import arrow3d scale = kwds.pop('scale') @@ -2746,8 +2746,8 @@ def plot_integrated(self, chart=None, ambient_coords=None, t += dt if display_tangent: - from sage.plot.graphics import Graphics from sage.plot.arrow import arrow2d + from sage.plot.graphics import Graphics from sage.plot.plot3d.shapes import arrow3d scale = kwds.pop('scale') diff --git a/src/sage/manifolds/differentiable/levi_civita_connection.py b/src/sage/manifolds/differentiable/levi_civita_connection.py index 215756f00d3..7768efbad23 100644 --- a/src/sage/manifolds/differentiable/levi_civita_connection.py +++ b/src/sage/manifolds/differentiable/levi_civita_connection.py @@ -29,10 +29,10 @@ # http://www.gnu.org/licenses/ #****************************************************************************** -from sage.parallel.decorate import parallel -from sage.parallel.parallelism import Parallelism from sage.manifolds.differentiable.affine_connection import AffineConnection from sage.manifolds.differentiable.vectorframe import CoordFrame +from sage.parallel.decorate import parallel +from sage.parallel.parallelism import Parallelism class LeviCivitaConnection(AffineConnection): @@ -364,9 +364,9 @@ def _new_coef(self, frame): sage: nab._new_coef(e) 3-indices components w.r.t. Vector frame (M, (e_0,e_1)) """ - from sage.tensor.modules.comp import Components, CompWithSym from sage.manifolds.differentiable.scalarfield import DiffScalarField from sage.manifolds.differentiable.vectorframe import CoordFrame + from sage.tensor.modules.comp import Components, CompWithSym if isinstance(frame, CoordFrame): # the Christoffel symbols are symmetric: return CompWithSym(frame._domain.scalar_field_algebra(), frame, 3, diff --git a/src/sage/manifolds/differentiable/manifold.py b/src/sage/manifolds/differentiable/manifold.py index 285a160e7ff..1ad2543827a 100644 --- a/src/sage/manifolds/differentiable/manifold.py +++ b/src/sage/manifolds/differentiable/manifold.py @@ -451,8 +451,8 @@ from sage.rings.real_mpfr import RR if TYPE_CHECKING: - from sage.manifolds.differentiable.diff_map import DiffMap from sage.manifolds.differentiable.diff_form import DiffForm + from sage.manifolds.differentiable.diff_map import DiffMap from sage.manifolds.differentiable.metric import PseudoRiemannianMetric from sage.manifolds.differentiable.vectorfield_module import ( VectorFieldFreeModule, @@ -1097,8 +1097,9 @@ class as the manifold. Differentiable real vector bundle E -> M of rank 2 over the base space 2-dimensional differentiable manifold M """ - from sage.manifolds.differentiable.vector_bundle \ - import DifferentiableVectorBundle + from sage.manifolds.differentiable.vector_bundle import ( + DifferentiableVectorBundle, + ) return DifferentiableVectorBundle(rank, name, self, field=field, latex_name=latex_name) @@ -1366,8 +1367,10 @@ def vector_field_module( sage: M.is_manifestly_parallelizable() True """ - from sage.manifolds.differentiable.vectorfield_module import \ - VectorFieldModule, VectorFieldFreeModule + from sage.manifolds.differentiable.vectorfield_module import ( + VectorFieldFreeModule, + VectorFieldModule, + ) if dest_map is None: dest_map = self.identity_map() codomain = dest_map._codomain @@ -2695,7 +2698,7 @@ def set_orientation(self, orientation): [Coordinate frame (U, (∂/∂x,∂/∂y)), Coordinate frame (V, (∂/∂u,∂/∂v))] """ - from .vectorframe import VectorFrame + from sage.manifolds.differentiable.vectorframe import VectorFrame chart_type = self._structure.chart if isinstance(orientation, chart_type): orientation = [orientation.frame()] @@ -2985,7 +2988,9 @@ def set_change_of_frame(self, frame1, frame2, change_of_frame, [1 2] [0 3] """ - from sage.manifolds.differentiable.automorphismfield import AutomorphismFieldParal + from sage.manifolds.differentiable.automorphismfield import ( + AutomorphismFieldParal, + ) fmodule = frame1._fmodule if frame2._fmodule != fmodule: raise ValueError("the two frames are not defined on the same " + @@ -3394,8 +3399,8 @@ def tangent_space(self, point, base_ring=None): :class:`~sage.manifolds.differentiable.tangent_space.TangentSpace` for more examples. """ - from sage.manifolds.point import ManifoldPoint from sage.manifolds.differentiable.tangent_space import TangentSpace + from sage.manifolds.point import ManifoldPoint if not isinstance(point, ManifoldPoint): raise TypeError("{} is not a manifold point".format(point)) if point not in self: @@ -3725,7 +3730,9 @@ def integrated_autoparallel_curve(self, affine_connection, """ from sage.manifolds.differentiable.examples.real_line import RealLine - from sage.manifolds.differentiable.manifold_homset import IntegratedAutoparallelCurveSet + from sage.manifolds.differentiable.manifold_homset import ( + IntegratedAutoparallelCurveSet, + ) if len(curve_param) != 3: raise ValueError("the argument 'curve_param' must be " + @@ -3893,8 +3900,7 @@ def affine_connection(self, name, latex_name=None): :class:`~sage.manifolds.differentiable.affine_connection.AffineConnection` for more examples. """ - from sage.manifolds.differentiable.affine_connection import \ - AffineConnection + from sage.manifolds.differentiable.affine_connection import AffineConnection return AffineConnection(self, name, latex_name) def metric(self, name: str, signature: Optional[int] = None, diff --git a/src/sage/manifolds/differentiable/manifold_homset.py b/src/sage/manifolds/differentiable/manifold_homset.py index d26e1cfea91..98fdf8998f5 100644 --- a/src/sage/manifolds/differentiable/manifold_homset.py +++ b/src/sage/manifolds/differentiable/manifold_homset.py @@ -42,12 +42,14 @@ # http://www.gnu.org/licenses/ #****************************************************************************** -from sage.manifolds.manifold_homset import TopologicalManifoldHomset -from sage.manifolds.differentiable.diff_map import DiffMap from sage.manifolds.differentiable.curve import DifferentiableCurve -from sage.manifolds.differentiable.integrated_curve import IntegratedCurve -from sage.manifolds.differentiable.integrated_curve import IntegratedAutoparallelCurve -from sage.manifolds.differentiable.integrated_curve import IntegratedGeodesic +from sage.manifolds.differentiable.diff_map import DiffMap +from sage.manifolds.differentiable.integrated_curve import ( + IntegratedAutoparallelCurve, + IntegratedCurve, + IntegratedGeodesic, +) +from sage.manifolds.manifold_homset import TopologicalManifoldHomset class DifferentiableManifoldHomset(TopologicalManifoldHomset): @@ -180,8 +182,7 @@ def __init__(self, domain, codomain, name=None, latex_name=None): manifolds over Real Field with 53 bits of precision sage: TestSuite(E).run() """ - from sage.manifolds.differentiable.manifold import \ - DifferentiableManifold + from sage.manifolds.differentiable.manifold import DifferentiableManifold if not isinstance(domain, DifferentiableManifold): raise TypeError("domain = {} is not an ".format(domain) + "instance of DifferentiableManifold") @@ -1305,11 +1306,11 @@ def _an_element_(self): (1.0565635217644918,) """ + from sage.categories.homset import Hom + from sage.functions.log import exp from sage.rings.infinity import Infinity from sage.rings.rational_field import QQ - from sage.categories.homset import Hom from sage.symbolic.ring import var - from sage.functions.log import exp dom = self.domain() t = dom.canonical_coordinate() @@ -1754,8 +1755,8 @@ def _an_element_(self): """ from sage.categories.homset import Hom - from sage.symbolic.ring import var from sage.functions.log import exp + from sage.symbolic.ring import var dom = self.domain() t = dom.canonical_coordinate() diff --git a/src/sage/manifolds/differentiable/metric.py b/src/sage/manifolds/differentiable/metric.py index 4a783db3478..8512ad2b70d 100644 --- a/src/sage/manifolds/differentiable/metric.py +++ b/src/sage/manifolds/differentiable/metric.py @@ -784,8 +784,9 @@ def connection(self, name=None, latex_name=None, init_coef=True): sage: Dig == 0 True """ - from sage.manifolds.differentiable.levi_civita_connection import \ - LeviCivitaConnection + from sage.manifolds.differentiable.levi_civita_connection import ( + LeviCivitaConnection, + ) if self._connection is None: if latex_name is None: if name is None: diff --git a/src/sage/manifolds/differentiable/mixed_form.py b/src/sage/manifolds/differentiable/mixed_form.py index 65e2a25891e..c9b04bd2a12 100644 --- a/src/sage/manifolds/differentiable/mixed_form.py +++ b/src/sage/manifolds/differentiable/mixed_form.py @@ -23,8 +23,8 @@ # ***************************************************************************** from sage.misc.cachefunc import cached_method -from sage.structure.element import AlgebraElement, ModuleElementWithMutability from sage.rings.integer import Integer +from sage.structure.element import AlgebraElement, ModuleElementWithMutability class MixedForm(AlgebraElement, ModuleElementWithMutability): @@ -413,9 +413,8 @@ def display_expansion(self, frame=None, chart=None, from_chart=None): F = x dx + (2*x^2 - 2*y^2) dx∧dy """ from sage.misc.latex import latex + from sage.tensor.modules.format_utilities import FormattedExpansion, is_atomic from sage.typeset.unicode_characters import unicode_wedge - from sage.tensor.modules.format_utilities import (is_atomic, - FormattedExpansion) # In case, no frame is given: if frame is None: frame = self._domain._def_frame @@ -711,7 +710,7 @@ def _richcmp_(self, other, op): sage: F.parent().zero() == 0 True """ - from sage.structure.richcmp import op_NE, op_EQ + from sage.structure.richcmp import op_EQ, op_NE if op == op_NE: return not self == other elif op == op_EQ: @@ -979,9 +978,11 @@ def wedge(self, other): resu._comp = [sum(self[k].wedge(other[j - k]) for k in range(j + 1)) for j in self.irange()] # Compose name: + from sage.tensor.modules.format_utilities import ( + format_mul_latex, + format_mul_txt, + ) from sage.typeset.unicode_characters import unicode_wedge - from sage.tensor.modules.format_utilities import (format_mul_txt, - format_mul_latex) resu._name = format_mul_txt(self._name, unicode_wedge, other._name) resu._latex_name = format_mul_latex(self._latex_name, r'\wedge ', other._latex_name) @@ -1032,9 +1033,11 @@ def _lmul_(self, other): resu._comp = [other * form for form in self] # Compose name: from sage.misc.latex import latex + from sage.tensor.modules.format_utilities import ( + format_mul_latex, + format_mul_txt, + ) from sage.typeset.unicode_characters import unicode_wedge - from sage.tensor.modules.format_utilities import (format_mul_txt, - format_mul_latex) resu._name = format_mul_txt(repr(other), unicode_wedge, self._name) resu._latex_name = format_mul_latex(latex(other), r'\wedge ', self._latex_name) @@ -1100,8 +1103,10 @@ def exterior_derivative(self): resu[1:] = [self[j].exterior_derivative() for j in range(self._max_deg)] # Compose name: - from sage.tensor.modules.format_utilities import (format_unop_txt, - format_unop_latex) + from sage.tensor.modules.format_utilities import ( + format_unop_latex, + format_unop_txt, + ) resu._name = format_unop_txt('d', self._name) resu._latex_name = format_unop_latex(r'\mathrm{d}', self._latex_name) return resu diff --git a/src/sage/manifolds/differentiable/mixed_form_algebra.py b/src/sage/manifolds/differentiable/mixed_form_algebra.py index 26339c0d6ad..c6af6f4164d 100644 --- a/src/sage/manifolds/differentiable/mixed_form_algebra.py +++ b/src/sage/manifolds/differentiable/mixed_form_algebra.py @@ -28,14 +28,14 @@ # https://www.gnu.org/licenses/ #****************************************************************************** -from sage.misc.cachefunc import cached_method -from sage.structure.parent import Parent -from sage.categories.graded_algebras import GradedAlgebras from sage.categories.chain_complexes import ChainComplexes +from sage.categories.graded_algebras import GradedAlgebras from sage.categories.morphism import SetMorphism +from sage.manifolds.differentiable.mixed_form import MixedForm +from sage.misc.cachefunc import cached_method +from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation from sage.symbolic.ring import SR -from sage.manifolds.differentiable.mixed_form import MixedForm class MixedFormAlgebra(Parent, UniqueRepresentation): @@ -494,7 +494,9 @@ def cohomology(self, *args, **kwargs): De Rham cohomology ring on the 3-dimensional differentiable manifold M """ - from .de_rham_cohomology import DeRhamCohomologyRing + from sage.manifolds.differentiable.de_rham_cohomology import ( + DeRhamCohomologyRing, + ) return DeRhamCohomologyRing(self) homology = cohomology diff --git a/src/sage/manifolds/differentiable/multivector_module.py b/src/sage/manifolds/differentiable/multivector_module.py index fa2d5fce099..35f56f2935e 100644 --- a/src/sage/manifolds/differentiable/multivector_module.py +++ b/src/sage/manifolds/differentiable/multivector_module.py @@ -32,13 +32,15 @@ # http://www.gnu.org/licenses/ #****************************************************************************** +from sage.categories.modules import Modules +from sage.manifolds.differentiable.multivectorfield import ( + MultivectorField, + MultivectorFieldParal, +) from sage.misc.cachefunc import cached_method -from sage.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent -from sage.categories.modules import Modules +from sage.structure.unique_representation import UniqueRepresentation from sage.tensor.modules.ext_pow_free_module import ExtPowerFreeModule -from sage.manifolds.differentiable.multivectorfield import ( - MultivectorField, MultivectorFieldParal) class MultivectorModule(UniqueRepresentation, Parent): diff --git a/src/sage/manifolds/differentiable/multivectorfield.py b/src/sage/manifolds/differentiable/multivectorfield.py index 1e739dfdd17..2efe5c133f2 100644 --- a/src/sage/manifolds/differentiable/multivectorfield.py +++ b/src/sage/manifolds/differentiable/multivectorfield.py @@ -36,9 +36,9 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.tensor.modules.alternating_contr_tensor import AlternatingContrTensor from sage.manifolds.differentiable.tensorfield import TensorField from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal +from sage.tensor.modules.alternating_contr_tensor import AlternatingContrTensor class MultivectorField(TensorField): @@ -300,8 +300,8 @@ def wedge(self, other): sage: c.display(e_uv) a∧b = (-v^2 + u) ∂/∂u∧∂/∂v """ - from sage.typeset.unicode_characters import unicode_wedge from sage.tensor.modules.format_utilities import is_atomic + from sage.typeset.unicode_characters import unicode_wedge if self._domain.is_subset(other._domain): if not self._ambient_domain.is_subset(other._ambient_domain): raise ValueError("incompatible ambient domains for exterior " + @@ -1401,10 +1401,10 @@ def bracket(self, other): True """ from itertools import combinations + from sage.combinat.permutation import Permutation - from sage.tensor.modules.comp import (Components, CompWithSym, - CompFullyAntiSym) from sage.manifolds.differentiable.scalarfield import DiffScalarField + from sage.tensor.modules.comp import CompFullyAntiSym, Components, CompWithSym pp = self._tensor_rank mp1 = (-1)**(pp+1) if isinstance(other, DiffScalarField): diff --git a/src/sage/manifolds/differentiable/poisson_tensor.py b/src/sage/manifolds/differentiable/poisson_tensor.py index 51da2de5f90..63fcab8d588 100644 --- a/src/sage/manifolds/differentiable/poisson_tensor.py +++ b/src/sage/manifolds/differentiable/poisson_tensor.py @@ -16,16 +16,17 @@ # ***************************************************************************** +from typing import Optional, Union + +from sage.manifolds.differentiable.diff_form import DiffForm +from sage.manifolds.differentiable.manifold import DifferentiableManifold from sage.manifolds.differentiable.multivectorfield import ( MultivectorField, MultivectorFieldParal, ) -from sage.manifolds.differentiable.diff_form import DiffForm -from sage.manifolds.differentiable.vectorfield import VectorField from sage.manifolds.differentiable.scalarfield import DiffScalarField +from sage.manifolds.differentiable.vectorfield import VectorField from sage.manifolds.differentiable.vectorfield_module import VectorFieldModule -from sage.manifolds.differentiable.manifold import DifferentiableManifold -from typing import Optional, Union class PoissonTensorField(MultivectorField): diff --git a/src/sage/manifolds/differentiable/pseudo_riemannian.py b/src/sage/manifolds/differentiable/pseudo_riemannian.py index 505900ad0df..c44d063bdc3 100644 --- a/src/sage/manifolds/differentiable/pseudo_riemannian.py +++ b/src/sage/manifolds/differentiable/pseudo_riemannian.py @@ -267,10 +267,13 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.infinity import infinity -from sage.manifolds.structure import (PseudoRiemannianStructure, - RiemannianStructure, LorentzianStructure) from sage.manifolds.differentiable.manifold import DifferentiableManifold +from sage.manifolds.structure import ( + LorentzianStructure, + PseudoRiemannianStructure, + RiemannianStructure, +) +from sage.rings.infinity import infinity ############################################################################### diff --git a/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py b/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py index e791cef6781..57dc1c99862 100644 --- a/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +++ b/src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py @@ -190,19 +190,19 @@ # http://www.gnu.org/licenses/ # ***************************************************************************** -from sage.manifolds.differentiable.pseudo_riemannian import \ - PseudoRiemannianManifold -from sage.manifolds.differentiable.degenerate import \ - DegenerateManifold -from sage.manifolds.differentiable.differentiable_submanifold import \ - DifferentiableSubmanifold -from sage.rings.infinity import infinity -from sage.matrix.constructor import matrix +from queue import Queue + from sage.functions.other import factorial -from sage.symbolic.ring import SR +from sage.manifolds.differentiable.degenerate import DegenerateManifold +from sage.manifolds.differentiable.differentiable_submanifold import ( + DifferentiableSubmanifold, +) +from sage.manifolds.differentiable.pseudo_riemannian import PseudoRiemannianManifold +from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method +from sage.rings.infinity import infinity from sage.rings.integer import Integer -from queue import Queue +from sage.symbolic.ring import SR class PseudoRiemannianSubmanifold(PseudoRiemannianManifold, diff --git a/src/sage/manifolds/differentiable/scalarfield.py b/src/sage/manifolds/differentiable/scalarfield.py index be1d6d3b97e..72d04db04f0 100644 --- a/src/sage/manifolds/differentiable/scalarfield.py +++ b/src/sage/manifolds/differentiable/scalarfield.py @@ -789,8 +789,10 @@ def differential(self) -> DiffForm: sage: ddg == 0 True """ - from sage.tensor.modules.format_utilities import (format_unop_txt, - format_unop_latex) + from sage.tensor.modules.format_utilities import ( + format_unop_latex, + format_unop_txt, + ) if self._differential is None: # A new computation is necessary: rname = format_unop_txt('d', self._name) @@ -936,8 +938,8 @@ def hodge_dual( True """ from sage.tensor.modules.format_utilities import ( - format_unop_txt, format_unop_latex, + format_unop_txt, ) result = self * nondegenerate_tensor.volume_form() diff --git a/src/sage/manifolds/differentiable/scalarfield_algebra.py b/src/sage/manifolds/differentiable/scalarfield_algebra.py index fc716f5fcc4..6a6091fe659 100644 --- a/src/sage/manifolds/differentiable/scalarfield_algebra.py +++ b/src/sage/manifolds/differentiable/scalarfield_algebra.py @@ -30,10 +30,10 @@ class `C^k` over a topological field `K` (in # http://www.gnu.org/licenses/ #****************************************************************************** +from sage.manifolds.differentiable.scalarfield import DiffScalarField +from sage.manifolds.scalarfield_algebra import ScalarFieldAlgebra from sage.rings.infinity import infinity from sage.symbolic.ring import SymbolicRing -from sage.manifolds.scalarfield_algebra import ScalarFieldAlgebra -from sage.manifolds.differentiable.scalarfield import DiffScalarField class DiffScalarFieldAlgebra(ScalarFieldAlgebra): diff --git a/src/sage/manifolds/differentiable/symplectic_form.py b/src/sage/manifolds/differentiable/symplectic_form.py index 52a076bfbe8..2c393d59cd7 100644 --- a/src/sage/manifolds/differentiable/symplectic_form.py +++ b/src/sage/manifolds/differentiable/symplectic_form.py @@ -22,18 +22,19 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** from __future__ import annotations -from typing import Union, Optional -from sage.symbolic.expression import Expression +from typing import Optional, Union + from sage.manifolds.differentiable.diff_form import DiffForm, DiffFormParal from sage.manifolds.differentiable.diff_map import DiffMap -from sage.manifolds.differentiable.vectorfield_module import VectorFieldModule -from sage.manifolds.differentiable.tensorfield import TensorField -from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal from sage.manifolds.differentiable.manifold import DifferentiableManifold +from sage.manifolds.differentiable.poisson_tensor import PoissonTensorField from sage.manifolds.differentiable.scalarfield import DiffScalarField +from sage.manifolds.differentiable.tensorfield import TensorField +from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal from sage.manifolds.differentiable.vectorfield import VectorField -from sage.manifolds.differentiable.poisson_tensor import PoissonTensorField +from sage.manifolds.differentiable.vectorfield_module import VectorFieldModule +from sage.symbolic.expression import Expression class SymplecticForm(DiffForm): diff --git a/src/sage/manifolds/differentiable/symplectic_form_test.py b/src/sage/manifolds/differentiable/symplectic_form_test.py index 804c8956b6e..cb5133595fb 100644 --- a/src/sage/manifolds/differentiable/symplectic_form_test.py +++ b/src/sage/manifolds/differentiable/symplectic_form_test.py @@ -1,16 +1,16 @@ # pylint: disable=missing-function-docstring -from _pytest.fixtures import FixtureRequest import pytest +from _pytest.fixtures import FixtureRequest -from sage.manifolds.manifold import Manifold -from sage.manifolds.differentiable.manifold import DifferentiableManifold from sage.manifolds.differentiable.examples.sphere import Sphere -from sage.manifolds.differentiable.symplectic_form import SymplecticForm from sage.manifolds.differentiable.examples.symplectic_space import ( StandardSymplecticSpace, ) -from sage.symbolic.function_factory import function +from sage.manifolds.differentiable.manifold import DifferentiableManifold from sage.manifolds.differentiable.scalarfield import DiffScalarField +from sage.manifolds.differentiable.symplectic_form import SymplecticForm +from sage.manifolds.manifold import Manifold +from sage.symbolic.function_factory import function class TestGenericSymplecticForm: diff --git a/src/sage/manifolds/differentiable/tangent_vector.py b/src/sage/manifolds/differentiable/tangent_vector.py index 1bd1dd5c647..81b89e29646 100644 --- a/src/sage/manifolds/differentiable/tangent_vector.py +++ b/src/sage/manifolds/differentiable/tangent_vector.py @@ -24,10 +24,10 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.tensor.modules.free_module_element import FiniteRankFreeModuleElement -from sage.tensor.modules.free_module_alt_form import FreeModuleAltForm -from .scalarfield import DiffScalarField +from sage.manifolds.differentiable.scalarfield import DiffScalarField from sage.misc.decorators import options +from sage.tensor.modules.free_module_alt_form import FreeModuleAltForm +from sage.tensor.modules.free_module_element import FiniteRankFreeModuleElement class TangentVector(FiniteRankFreeModuleElement): @@ -448,13 +448,13 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, graph_S2 = XS.plot(chart=X3, mapping=F, number_values=9) sphinx_plot(graph_v + graph_S2) """ + from sage.manifolds.differentiable.chart import DiffChart + from sage.misc.functional import numerical_approx from sage.plot.arrow import arrow2d - from sage.plot.text import text from sage.plot.graphics import Graphics from sage.plot.plot3d.shapes import arrow3d from sage.plot.plot3d.shapes2 import text3d - from sage.misc.functional import numerical_approx - from sage.manifolds.differentiable.chart import DiffChart + from sage.plot.text import text scale = extra_options.pop("scale") diff --git a/src/sage/manifolds/differentiable/tensorfield.py b/src/sage/manifolds/differentiable/tensorfield.py index 562c62cefc8..50ed9fe7a80 100644 --- a/src/sage/manifolds/differentiable/tensorfield.py +++ b/src/sage/manifolds/differentiable/tensorfield.py @@ -2228,7 +2228,7 @@ def __eq__(self, other): sage: t.parent().zero() == 0 True """ - from .mixed_form import MixedForm + from sage.manifolds.differentiable.mixed_form import MixedForm if other is self: return True @@ -2341,8 +2341,10 @@ def __pos__(self): for dom, rst in self._restrictions.items(): resu._restrictions[dom] = + rst # Compose names: - from sage.tensor.modules.format_utilities import (format_unop_txt, - format_unop_latex) + from sage.tensor.modules.format_utilities import ( + format_unop_latex, + format_unop_txt, + ) resu._name = format_unop_txt('+', self._name) resu._latex_name = format_unop_latex(r'+', self._latex_name) return resu @@ -2385,8 +2387,10 @@ def __neg__(self): for dom, rst in self._restrictions.items(): resu._restrictions[dom] = - rst # Compose names: - from sage.tensor.modules.format_utilities import (format_unop_txt, - format_unop_latex) + from sage.tensor.modules.format_utilities import ( + format_unop_latex, + format_unop_txt, + ) resu._name = format_unop_txt('-', self._name) resu._latex = format_unop_latex(r'-', self._latex_name) return resu @@ -2597,8 +2601,10 @@ def _rmul_(self, scalar): for dom, rst in self._restrictions.items(): resu._restrictions[dom] = scalar.restrict(dom) * rst # Compose names: - from sage.tensor.modules.format_utilities import (format_mul_txt, - format_mul_latex) + from sage.tensor.modules.format_utilities import ( + format_mul_latex, + format_mul_txt, + ) resu_name = format_mul_txt(scalar._name, '*', self._name) resu_latex = format_mul_latex(scalar._latex_name, r' \cdot ', self._latex_name) @@ -3826,8 +3832,8 @@ def up( raise ValueError("position out of range") from sage.manifolds.differentiable.metric import PseudoRiemannianMetric - from sage.manifolds.differentiable.symplectic_form import SymplecticForm from sage.manifolds.differentiable.poisson_tensor import PoissonTensorField + from sage.manifolds.differentiable.symplectic_form import SymplecticForm if isinstance(non_degenerate_form, PseudoRiemannianMetric): return self.contract(pos, non_degenerate_form.inverse(), 1) diff --git a/src/sage/manifolds/differentiable/tensorfield_module.py b/src/sage/manifolds/differentiable/tensorfield_module.py index 22d42050b89..089d4d178d8 100644 --- a/src/sage/manifolds/differentiable/tensorfield_module.py +++ b/src/sage/manifolds/differentiable/tensorfield_module.py @@ -38,20 +38,23 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** +from sage.categories.modules import Modules +from sage.manifolds.differentiable.automorphismfield import ( + AutomorphismField, + AutomorphismFieldParal, +) +from sage.manifolds.differentiable.diff_form import DiffForm, DiffFormParal +from sage.manifolds.differentiable.multivectorfield import ( + MultivectorField, + MultivectorFieldParal, +) +from sage.manifolds.differentiable.tensorfield import TensorField +from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal from sage.misc.cachefunc import cached_method -from sage.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent -from sage.categories.modules import Modules +from sage.structure.unique_representation import UniqueRepresentation from sage.tensor.modules.reflexive_module import ReflexiveModule_tensor from sage.tensor.modules.tensor_free_module import TensorFreeModule -from sage.manifolds.differentiable.tensorfield import TensorField -from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal -from sage.manifolds.differentiable.diff_form import (DiffForm, - DiffFormParal) -from sage.manifolds.differentiable.multivectorfield import (MultivectorField, - MultivectorFieldParal) -from sage.manifolds.differentiable.automorphismfield import (AutomorphismField, - AutomorphismFieldParal) class TensorFieldModule(UniqueRepresentation, ReflexiveModule_tensor): @@ -442,12 +445,11 @@ def _coerce_map_from_(self, other): sage: T11._coerce_map_from_(M.automorphism_field_group()) True """ - from sage.manifolds.differentiable.diff_form_module import \ - DiffFormModule - from sage.manifolds.differentiable.multivector_module import \ - MultivectorModule - from sage.manifolds.differentiable.automorphismfield_group \ - import AutomorphismFieldGroup + from sage.manifolds.differentiable.automorphismfield_group import ( + AutomorphismFieldGroup, + ) + from sage.manifolds.differentiable.diff_form_module import DiffFormModule + from sage.manifolds.differentiable.multivector_module import MultivectorModule if isinstance(other, (TensorFieldModule, TensorFieldFreeModule)): # coercion by domain restriction return (self._tensor_type == other._tensor_type @@ -901,12 +903,13 @@ def _coerce_map_from_(self, other): sage: T11._coerce_map_from_(M.automorphism_field_group()) True """ - from sage.manifolds.differentiable.diff_form_module import \ - DiffFormFreeModule - from sage.manifolds.differentiable.multivector_module import \ - MultivectorFreeModule - from sage.manifolds.differentiable.automorphismfield_group \ - import AutomorphismFieldParalGroup + from sage.manifolds.differentiable.automorphismfield_group import ( + AutomorphismFieldParalGroup, + ) + from sage.manifolds.differentiable.diff_form_module import DiffFormFreeModule + from sage.manifolds.differentiable.multivector_module import ( + MultivectorFreeModule, + ) if isinstance(other, (TensorFieldModule, TensorFieldFreeModule)): # coercion by domain restriction return (self._tensor_type == other._tensor_type diff --git a/src/sage/manifolds/differentiable/tensorfield_paral.py b/src/sage/manifolds/differentiable/tensorfield_paral.py index cb0e1db14cd..3fa7166234c 100644 --- a/src/sage/manifolds/differentiable/tensorfield_paral.py +++ b/src/sage/manifolds/differentiable/tensorfield_paral.py @@ -1975,8 +1975,8 @@ def display_comp(self, frame=None, chart=None, coordinate_labels=True, t^10_0 = (u^2 - v^2)/(u^2 + 2*u*v + v^2 + 8) t^11_1 = -12/(u^2 + 2*u*v + v^2 + 8) """ - from sage.misc.latex import latex from sage.manifolds.differentiable.vectorframe import CoordFrame + from sage.misc.latex import latex if frame is None: if chart is not None: frame = chart.frame() diff --git a/src/sage/manifolds/differentiable/vector_bundle.py b/src/sage/manifolds/differentiable/vector_bundle.py index 79e940a19e6..a6307cf274d 100644 --- a/src/sage/manifolds/differentiable/vector_bundle.py +++ b/src/sage/manifolds/differentiable/vector_bundle.py @@ -30,12 +30,12 @@ #****************************************************************************** from sage.categories.vector_bundles import VectorBundles -from sage.rings.cc import CC -from sage.rings.real_mpfr import RR from sage.manifolds.vector_bundle import TopologicalVectorBundle -from sage.rings.infinity import infinity from sage.misc.superseded import deprecated_function_alias +from sage.rings.cc import CC +from sage.rings.infinity import infinity from sage.rings.rational_field import QQ +from sage.rings.real_mpfr import RR class DifferentiableVectorBundle(TopologicalVectorBundle): @@ -158,7 +158,7 @@ def bundle_connection(self, name, latex_name=None): Further examples can be found in :class:`~sage.manifolds.differentiable.bundle_connection.BundleConnection`. """ - from .bundle_connection import BundleConnection + from sage.manifolds.differentiable.bundle_connection import BundleConnection return BundleConnection(self, name, latex_name) def characteristic_cohomology_class_ring(self, base=QQ): @@ -186,7 +186,9 @@ def characteristic_cohomology_class_ring(self, base=QQ): Characteristic cohomology class (1 + p_1)(TM) of the Tangent bundle TM over the 4-dimensional differentiable manifold M """ - from .characteristic_cohomology_class import CharacteristicCohomologyClassRing + from sage.manifolds.differentiable.characteristic_cohomology_class import ( + CharacteristicCohomologyClassRing, + ) return CharacteristicCohomologyClassRing(base, self) diff --git a/src/sage/manifolds/differentiable/vectorfield.py b/src/sage/manifolds/differentiable/vectorfield.py index 44ae84089de..c038e8afab2 100644 --- a/src/sage/manifolds/differentiable/vectorfield.py +++ b/src/sage/manifolds/differentiable/vectorfield.py @@ -59,10 +59,12 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.tensor.modules.free_module_element import FiniteRankFreeModuleElement from sage.manifolds.differentiable.multivectorfield import ( - MultivectorField, MultivectorFieldParal) + MultivectorField, + MultivectorFieldParal, +) from sage.misc.decorators import options +from sage.tensor.modules.free_module_element import FiniteRankFreeModuleElement class VectorField(MultivectorField): @@ -663,14 +665,14 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, sage: v.plot.reset() """ - from sage.rings.infinity import Infinity - from sage.misc.functional import numerical_approx - from sage.misc.latex import latex - from sage.plot.graphics import Graphics from sage.manifolds.chart import RealChart from sage.manifolds.utilities import set_axes_labels + from sage.misc.functional import numerical_approx + from sage.misc.latex import latex from sage.parallel.decorate import parallel from sage.parallel.parallelism import Parallelism + from sage.plot.graphics import Graphics + from sage.rings.infinity import Infinity # # 1/ Treatment of input parameters diff --git a/src/sage/manifolds/differentiable/vectorfield_module.py b/src/sage/manifolds/differentiable/vectorfield_module.py index 67cd1abd614..edea1756278 100644 --- a/src/sage/manifolds/differentiable/vectorfield_module.py +++ b/src/sage/manifolds/differentiable/vectorfield_module.py @@ -57,9 +57,9 @@ if TYPE_CHECKING: from sage.manifolds.differentiable.diff_form import DiffForm - from sage.manifolds.scalarfield import ScalarField from sage.manifolds.differentiable.diff_map import DiffMap from sage.manifolds.differentiable.manifold import DifferentiableManifold + from sage.manifolds.scalarfield import ScalarField class VectorFieldModule(UniqueRepresentation, ReflexiveModule_base): @@ -548,8 +548,9 @@ def tensor_module(self, k, l, *, sym=None, antisym=None): try: return self._tensor_modules[(k,l)] except KeyError: - from sage.manifolds.differentiable.tensorfield_module import \ - TensorFieldModule + from sage.manifolds.differentiable.tensorfield_module import ( + TensorFieldModule, + ) T = TensorFieldModule(self, (k,l)) self._tensor_modules[(k,l)] = T return T @@ -606,8 +607,9 @@ def exterior_power(self, p): if p == 0: L = self._ring else: - from sage.manifolds.differentiable.multivector_module import \ - MultivectorModule + from sage.manifolds.differentiable.multivector_module import ( + MultivectorModule, + ) L = MultivectorModule(self, p) self._exterior_powers[p] = L return L @@ -663,8 +665,9 @@ def dual_exterior_power(self, p): if p == 0: L = self._ring else: - from sage.manifolds.differentiable.diff_form_module import \ - DiffFormModule + from sage.manifolds.differentiable.diff_form_module import ( + DiffFormModule, + ) L = DiffFormModule(self, p) self._dual_exterior_powers[p] = L return L @@ -713,8 +716,9 @@ def general_linear_group(self): for more examples and documentation. """ if self._general_linear_group is None: - from sage.manifolds.differentiable.automorphismfield_group import \ - AutomorphismFieldGroup + from sage.manifolds.differentiable.automorphismfield_group import ( + AutomorphismFieldGroup, + ) self._general_linear_group = AutomorphismFieldGroup(self) return self._general_linear_group @@ -769,10 +773,11 @@ def _tensor(self, tensor_type, name=None, latex_name=None, sym=None, :class:`~sage.manifolds.differentiable.tensorfield.TensorField` for more examples and documentation. """ - from sage.manifolds.differentiable.automorphismfield import \ - AutomorphismField - from sage.manifolds.differentiable.metric import (PseudoRiemannianMetric, - DegenerateMetric) + from sage.manifolds.differentiable.automorphismfield import AutomorphismField + from sage.manifolds.differentiable.metric import ( + DegenerateMetric, + PseudoRiemannianMetric, + ) from sage.tensor.modules.comp import CompWithSym sym, antisym = CompWithSym._canonicalize_sym_antisym( tensor_type[0] + tensor_type[1], sym, antisym) @@ -1839,8 +1844,9 @@ def tensor_module(self, k, l, *, sym=None, antisym=None): elif (k, l) == (0, 1): T = self.dual() else: - from sage.manifolds.differentiable.tensorfield_module import \ - TensorFieldFreeModule + from sage.manifolds.differentiable.tensorfield_module import ( + TensorFieldFreeModule, + ) T = TensorFieldFreeModule(self, (k,l)) self._tensor_modules[(k,l)] = T return T @@ -1900,8 +1906,9 @@ def exterior_power(self, p): elif p == 1: L = self else: - from sage.manifolds.differentiable.multivector_module import \ - MultivectorFreeModule + from sage.manifolds.differentiable.multivector_module import ( + MultivectorFreeModule, + ) L = MultivectorFreeModule(self, p) self._exterior_powers[p] = L return L @@ -1956,12 +1963,14 @@ def dual_exterior_power(self, p): if p == 0: L = self._ring elif p == 1: - from sage.manifolds.differentiable.diff_form_module import \ - VectorFieldDualFreeModule + from sage.manifolds.differentiable.diff_form_module import ( + VectorFieldDualFreeModule, + ) L = VectorFieldDualFreeModule(self) else: - from sage.manifolds.differentiable.diff_form_module import \ - DiffFormFreeModule + from sage.manifolds.differentiable.diff_form_module import ( + DiffFormFreeModule, + ) L = DiffFormFreeModule(self, p) self._dual_exterior_powers[p] = L return L @@ -1996,8 +2005,9 @@ def general_linear_group(self): :class:`~sage.manifolds.differentiable.automorphismfield_group.AutomorphismFieldParalGroup` for more examples and documentation. """ - from sage.manifolds.differentiable.automorphismfield_group import \ - AutomorphismFieldParalGroup + from sage.manifolds.differentiable.automorphismfield_group import ( + AutomorphismFieldParalGroup, + ) return AutomorphismFieldParalGroup(self) def basis(self, symbol=None, latex_symbol=None, from_frame=None, @@ -2138,9 +2148,13 @@ def _tensor(self, tensor_type, name=None, latex_name=None, sym=None, for more examples and documentation. """ from sage.manifolds.differentiable.automorphismfield import ( - AutomorphismField, AutomorphismFieldParal) - from sage.manifolds.differentiable.metric import (PseudoRiemannianMetric, - DegenerateMetric) + AutomorphismField, + AutomorphismFieldParal, + ) + from sage.manifolds.differentiable.metric import ( + DegenerateMetric, + PseudoRiemannianMetric, + ) from sage.tensor.modules.comp import CompWithSym sym, antisym = CompWithSym._canonicalize_sym_antisym( tensor_type[0] + tensor_type[1], sym, antisym) @@ -2227,7 +2241,7 @@ def tensor_from_comp(self, tensor_type, comp, name=None, sage: t.display() t = (x + 1) dx⊗dx - y dx⊗dy + x*y dy⊗dx + (-y^2 + 2) dy⊗dy """ - from sage.tensor.modules.comp import (CompWithSym, CompFullyAntiSym) + from sage.tensor.modules.comp import CompFullyAntiSym, CompWithSym # 0/ Compatibility checks: if comp._ring is not self._ring: diff --git a/src/sage/manifolds/differentiable/vectorframe.py b/src/sage/manifolds/differentiable/vectorframe.py index 594d2e9a729..8cc75ab0f2d 100644 --- a/src/sage/manifolds/differentiable/vectorframe.py +++ b/src/sage/manifolds/differentiable/vectorframe.py @@ -216,10 +216,9 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.tensor.modules.free_module_basis import (FreeModuleBasis, - FreeModuleCoBasis) -from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule from sage.misc.cachefunc import cached_method +from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule +from sage.tensor.modules.free_module_basis import FreeModuleBasis, FreeModuleCoBasis class CoFrame(FreeModuleCoBasis): @@ -1715,9 +1714,9 @@ def __init__(self, chart): Coordinate frame (M, (∂/∂x,∂/∂y)) sage: TestSuite(e).run() """ + from sage.manifolds.differentiable.chart import DiffChart from sage.misc.latex import latex from sage.typeset.unicode_characters import unicode_partial - from sage.manifolds.differentiable.chart import DiffChart if not isinstance(chart, DiffChart): raise TypeError("the first argument must be a chart") dom = chart.domain() diff --git a/src/sage/manifolds/family.py b/src/sage/manifolds/family.py index 565fa2401cc..e58faf0e885 100644 --- a/src/sage/manifolds/family.py +++ b/src/sage/manifolds/family.py @@ -26,6 +26,7 @@ #***************************************************************************** from functools import total_ordering + from sage.sets.family import FiniteFamily diff --git a/src/sage/manifolds/local_frame.py b/src/sage/manifolds/local_frame.py index 42e1579640d..3d13c977f9a 100644 --- a/src/sage/manifolds/local_frame.py +++ b/src/sage/manifolds/local_frame.py @@ -171,9 +171,8 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.tensor.modules.free_module_basis import (FreeModuleBasis, - FreeModuleCoBasis) from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule +from sage.tensor.modules.free_module_basis import FreeModuleBasis, FreeModuleCoBasis class LocalCoFrame(FreeModuleCoBasis): @@ -1414,8 +1413,8 @@ def __init__(self, trivialization): sage: e = phi.frame() sage: TestSuite(e).run() """ + from sage.manifolds.trivialization import Trivialization from sage.misc.latex import latex - from .trivialization import Trivialization if not isinstance(trivialization, Trivialization): raise TypeError("the first argument must be a trivialization") ### diff --git a/src/sage/manifolds/manifold.py b/src/sage/manifolds/manifold.py index c27cd0b6434..754e0dda5a4 100644 --- a/src/sage/manifolds/manifold.py +++ b/src/sage/manifolds/manifold.py @@ -1321,7 +1321,7 @@ def set_default_chart(self, chart): sage: M.default_chart() Chart (M, (u, v)) """ - from .chart import Chart + from sage.manifolds.chart import Chart if not isinstance(chart, Chart): raise TypeError("{} is not a chart".format(chart)) if chart not in self._atlas: @@ -2950,14 +2950,20 @@ def Manifold( sage: isinstance(M, sage.misc.fast_methods.WithEqualityById) True """ - from sage.rings.infinity import infinity + from sage.manifolds.differentiable.degenerate import DegenerateManifold + from sage.manifolds.differentiable.degenerate_submanifold import ( + DegenerateSubmanifold, + ) + from sage.manifolds.differentiable.differentiable_submanifold import ( + DifferentiableSubmanifold, + ) from sage.manifolds.differentiable.manifold import DifferentiableManifold from sage.manifolds.differentiable.pseudo_riemannian import PseudoRiemannianManifold - from sage.manifolds.differentiable.degenerate import DegenerateManifold + from sage.manifolds.differentiable.pseudo_riemannian_submanifold import ( + PseudoRiemannianSubmanifold, + ) from sage.manifolds.topological_submanifold import TopologicalSubmanifold - from sage.manifolds.differentiable.differentiable_submanifold import DifferentiableSubmanifold - from sage.manifolds.differentiable.pseudo_riemannian_submanifold import PseudoRiemannianSubmanifold - from sage.manifolds.differentiable.degenerate_submanifold import DegenerateSubmanifold + from sage.rings.infinity import infinity global _manifold_id diff --git a/src/sage/manifolds/manifold_homset.py b/src/sage/manifolds/manifold_homset.py index c390233ca55..2b3c8564622 100644 --- a/src/sage/manifolds/manifold_homset.py +++ b/src/sage/manifolds/manifold_homset.py @@ -28,10 +28,10 @@ #***************************************************************************** from sage.categories.homset import Homset -from sage.structure.parent import Parent -from sage.structure.unique_representation import UniqueRepresentation from sage.manifolds.continuous_map import ContinuousMap from sage.misc.cachefunc import cached_method +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation class TopologicalManifoldHomset(UniqueRepresentation, Homset): diff --git a/src/sage/manifolds/point.py b/src/sage/manifolds/point.py index b3647cc1447..ca10cb5c767 100644 --- a/src/sage/manifolds/point.py +++ b/src/sage/manifolds/point.py @@ -87,10 +87,10 @@ # https://www.gnu.org/licenses/ #***************************************************************************** -from sage.structure.element import Element from sage.misc.decorators import options -from sage.symbolic.expression import Expression from sage.rings.integer_ring import ZZ +from sage.structure.element import Element +from sage.symbolic.expression import Expression class ManifoldPoint(Element): @@ -935,11 +935,11 @@ def plot(self, chart=None, ambient_coords=None, mapping=None, gX = X.plot(X, ambient_coords=(y,z)) sphinx_plot(g+gX) """ - from sage.plot.point import point2d - from sage.plot.text import text + from sage.manifolds.chart import Chart from sage.plot.graphics import Graphics from sage.plot.plot3d.shapes2 import point3d, text3d - from sage.manifolds.chart import Chart + from sage.plot.point import point2d + from sage.plot.text import text if self._manifold.base_field_type() != 'real': raise NotImplementedError('plot of points on manifolds over fields different' ' from the real field is not implemented') diff --git a/src/sage/manifolds/scalarfield.py b/src/sage/manifolds/scalarfield.py index 62c728ff5bb..7b850a4b1a4 100644 --- a/src/sage/manifolds/scalarfield.py +++ b/src/sage/manifolds/scalarfield.py @@ -40,16 +40,20 @@ # ***************************************************************************** from __future__ import annotations -from typing import Optional, TYPE_CHECKING -from sage.structure.element import (CommutativeAlgebraElement, - ModuleElementWithMutability) -from sage.symbolic.expression import Expression + +from typing import TYPE_CHECKING, Optional + from sage.manifolds.chart_func import ChartFunction from sage.misc.cachefunc import cached_method +from sage.structure.element import ( + CommutativeAlgebraElement, + ModuleElementWithMutability, +) +from sage.symbolic.expression import Expression if TYPE_CHECKING: - from sage.tensor.modules.format_utilities import FormattedExpansion from sage.manifolds.chart import Chart + from sage.tensor.modules.format_utilities import FormattedExpansion class ScalarField(CommutativeAlgebraElement, ModuleElementWithMutability): @@ -2135,11 +2139,13 @@ def display(self, chart: Optional[Chart] = None) -> FormattedExpansion: \begin{array}{llcl} f:& M & \longrightarrow & \mathbb{R} \\ \text{on}\ U : & \left(x, y\right) & \longmapsto & y^{2} \end{array} """ from sage.misc.latex import latex - from sage.typeset.unicode_characters import (unicode_to, - unicode_mapsto, - unicode_mathbbR, - unicode_mathbbC) from sage.tensor.modules.format_utilities import FormattedExpansion + from sage.typeset.unicode_characters import ( + unicode_mapsto, + unicode_mathbbC, + unicode_mathbbR, + unicode_to, + ) def _display_expression(self, chart, result): r""" @@ -2764,8 +2770,10 @@ def _mul_(self, other): if other.is_trivial_one(): return self # Generic case: - from sage.tensor.modules.format_utilities import (format_mul_txt, - format_mul_latex) + from sage.tensor.modules.format_utilities import ( + format_mul_latex, + format_mul_txt, + ) com_charts = self.common_charts(other) if com_charts is None: raise ValueError("no common chart for the multiplication") @@ -2809,8 +2817,10 @@ def _div_(self, other): ... ZeroDivisionError: division of a scalar field by zero """ - from sage.tensor.modules.format_utilities import format_mul_txt, \ - format_mul_latex + from sage.tensor.modules.format_utilities import ( + format_mul_latex, + format_mul_txt, + ) # Trivial cases: if other.is_trivial_zero(): raise ZeroDivisionError("division of a scalar field by zero") diff --git a/src/sage/manifolds/scalarfield_algebra.py b/src/sage/manifolds/scalarfield_algebra.py index 960b4514387..d4a01098eaf 100644 --- a/src/sage/manifolds/scalarfield_algebra.py +++ b/src/sage/manifolds/scalarfield_algebra.py @@ -30,13 +30,13 @@ # http://www.gnu.org/licenses/ #****************************************************************************** -from sage.structure.parent import Parent -from sage.structure.unique_representation import UniqueRepresentation -from sage.misc.cachefunc import cached_method from sage.categories.commutative_algebras import CommutativeAlgebras from sage.categories.topological_spaces import TopologicalSpaces -from sage.symbolic.ring import SymbolicRing, SR from sage.manifolds.scalarfield import ScalarField +from sage.misc.cachefunc import cached_method +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation +from sage.symbolic.ring import SR, SymbolicRing class ScalarFieldAlgebra(UniqueRepresentation, Parent): @@ -518,7 +518,7 @@ def _coerce_map_from_(self, other): sage: CU._coerce_map_from_(CM) True """ - from .chart_func import ChartFunctionRing + from sage.manifolds.chart_func import ChartFunctionRing if isinstance(other, SymbolicRing): return True # coercion from the base ring (multiplication by the # algebra unit, i.e. self.one()) diff --git a/src/sage/manifolds/section.py b/src/sage/manifolds/section.py index 75af42a57e5..77d8f881ee1 100644 --- a/src/sage/manifolds/section.py +++ b/src/sage/manifolds/section.py @@ -19,11 +19,11 @@ # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #****************************************************************************** +from sage.rings.integer import Integer +from sage.rings.integer_ring import ZZ from sage.structure.element import ModuleElementWithMutability from sage.tensor.modules.free_module_element import FiniteRankFreeModuleElement from sage.tensor.modules.tensor_with_indices import TensorWithIndices -from sage.rings.integer import Integer -from sage.rings.integer_ring import ZZ class Section(ModuleElementWithMutability): @@ -2213,8 +2213,10 @@ def _rmul_(self, scalar): return self.copy() ### # General case: - from sage.tensor.modules.format_utilities import (format_mul_txt, - format_mul_latex) + from sage.tensor.modules.format_utilities import ( + format_mul_latex, + format_mul_txt, + ) resu = self._new_instance() for dom, rst in self._restrictions.items(): resu._restrictions[dom] = scalar.restrict(dom) * rst diff --git a/src/sage/manifolds/section_module.py b/src/sage/manifolds/section_module.py index 6192045f45a..bace0b29866 100644 --- a/src/sage/manifolds/section_module.py +++ b/src/sage/manifolds/section_module.py @@ -26,13 +26,13 @@ # http://www.gnu.org/licenses/ #****************************************************************************** +from sage.categories.modules import Modules +from sage.manifolds.section import Section, TrivialSection +from sage.misc.cachefunc import cached_method from sage.rings.infinity import infinity -from sage.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent -from sage.misc.cachefunc import cached_method -from sage.categories.modules import Modules +from sage.structure.unique_representation import UniqueRepresentation from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule -from sage.manifolds.section import Section, TrivialSection class SectionModule(UniqueRepresentation, Parent): @@ -467,7 +467,7 @@ def set_default_frame(self, basis): sage: C0.default_frame().domain() Open subset U of the 3-dimensional topological manifold M """ - from .local_frame import LocalFrame + from sage.manifolds.local_frame import LocalFrame if not isinstance(basis, LocalFrame): raise ValueError("the argument is not a local frame") elif not basis._domain.is_subset(self._domain): @@ -587,7 +587,7 @@ def __init__(self, vbundle, domain): True sage: TestSuite(C0).run() """ - from .scalarfield import ScalarField + from sage.manifolds.scalarfield import ScalarField self._domain = domain name = "C^0({};{})".format(domain._name, vbundle._name) latex_name = r'C^0({};{})'.format(domain._latex_name, diff --git a/src/sage/manifolds/structure.py b/src/sage/manifolds/structure.py index ed166b6438a..6d0797c062d 100644 --- a/src/sage/manifolds/structure.py +++ b/src/sage/manifolds/structure.py @@ -23,15 +23,13 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.misc.fast_methods import Singleton from sage.manifolds.chart import Chart, RealChart -from sage.manifolds.scalarfield_algebra import ScalarFieldAlgebra -from sage.manifolds.manifold_homset import TopologicalManifoldHomset from sage.manifolds.differentiable.chart import DiffChart, RealDiffChart -from sage.manifolds.differentiable.scalarfield_algebra import \ - DiffScalarFieldAlgebra -from sage.manifolds.differentiable.manifold_homset import \ - DifferentiableManifoldHomset +from sage.manifolds.differentiable.manifold_homset import DifferentiableManifoldHomset +from sage.manifolds.differentiable.scalarfield_algebra import DiffScalarFieldAlgebra +from sage.manifolds.manifold_homset import TopologicalManifoldHomset +from sage.manifolds.scalarfield_algebra import ScalarFieldAlgebra +from sage.misc.fast_methods import Singleton # This is a slight abuse by making this a Singleton, but there is no # need to have different copies of this object. diff --git a/src/sage/manifolds/subset.py b/src/sage/manifolds/subset.py index 453fa02de2f..b0552238afa 100644 --- a/src/sage/manifolds/subset.py +++ b/src/sage/manifolds/subset.py @@ -65,15 +65,17 @@ # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import annotations -from typing import Optional -from collections import defaultdict + import itertools -from sage.structure.parent import Parent -from sage.structure.unique_representation import UniqueRepresentation -from sage.misc.superseded import deprecation +from collections import defaultdict +from typing import Optional + from sage.categories.sets_cat import Sets from sage.manifolds.family import ManifoldObjectFiniteFamily, ManifoldSubsetFiniteFamily from sage.manifolds.point import ManifoldPoint +from sage.misc.superseded import deprecation +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation class ManifoldSubset(UniqueRepresentation, Parent): @@ -1891,7 +1893,7 @@ def declare_closed(self): if self.is_closed(): return self.complement(is_open=True) - from .subsets.closure import ManifoldSubsetClosure + from sage.manifolds.subsets.closure import ManifoldSubsetClosure for closure in self.manifold().subsets(): if isinstance(closure, ManifoldSubsetClosure): if closure._subset.is_subset(self): @@ -2755,7 +2757,7 @@ def closure(self, name=None, latex_name=None): """ if self.is_closed(): return self - from .subsets.closure import ManifoldSubsetClosure + from sage.manifolds.subsets.closure import ManifoldSubsetClosure return ManifoldSubsetClosure(self, name=name, latex_name=latex_name) #### End of construction of new sets from self diff --git a/src/sage/manifolds/subsets/pullback.py b/src/sage/manifolds/subsets/pullback.py index d62f9936368..2d499892e35 100644 --- a/src/sage/manifolds/subsets/pullback.py +++ b/src/sage/manifolds/subsets/pullback.py @@ -13,23 +13,23 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.categories.sets_cat import Sets, EmptySetError +import sage.geometry.abc from sage.categories.metric_spaces import MetricSpaces +from sage.categories.sets_cat import EmptySetError, Sets +from sage.manifolds.chart import Chart +from sage.manifolds.scalarfield import ScalarField +from sage.manifolds.subset import ManifoldSubset from sage.misc.lazy_import import lazy_import from sage.modules.free_module import FreeModule_generic +from sage.modules.free_module_element import vector +from sage.rings.complex_double import CDF from sage.rings.infinity import infinity, minus_infinity from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ -from sage.rings.complex_double import CDF from sage.rings.real_double import RDF from sage.rings.real_lazy import CLF, RLF -from sage.symbolic.ring import SR -from sage.modules.free_module_element import vector -from sage.manifolds.subset import ManifoldSubset -from sage.manifolds.chart import Chart -from sage.manifolds.scalarfield import ScalarField from sage.sets.real_set import RealSet -import sage.geometry.abc +from sage.symbolic.ring import SR lazy_import('sage.geometry.relative_interior', 'RelativeInterior') @@ -307,7 +307,7 @@ def _is_open(codomain_subset): if hasattr(codomain_subset, 'minimized_constraints'): try: - from ppl import NNC_Polyhedron, C_Polyhedron + from ppl import C_Polyhedron, NNC_Polyhedron except ImportError: pass else: @@ -837,7 +837,7 @@ def is_closed(self): else: if hasattr(self._codomain_subset, 'is_topologically_closed'): try: - from ppl import NNC_Polyhedron, C_Polyhedron + from ppl import C_Polyhedron, NNC_Polyhedron except ImportError: pass else: diff --git a/src/sage/manifolds/topological_submanifold.py b/src/sage/manifolds/topological_submanifold.py index a99e6d1fca1..9ea40b0f621 100644 --- a/src/sage/manifolds/topological_submanifold.py +++ b/src/sage/manifolds/topological_submanifold.py @@ -45,11 +45,12 @@ # http://www.gnu.org/licenses/ # ***************************************************************************** -from sage.manifolds.manifold import TopologicalManifold from sage.manifolds.continuous_map import ContinuousMap -from sage.symbolic.expression import Expression -from sage.symbolic.assumptions import assumptions, assume +from sage.manifolds.manifold import TopologicalManifold from sage.misc.lazy_import import lazy_import +from sage.symbolic.assumptions import assume, assumptions +from sage.symbolic.expression import Expression + lazy_import("sage.plot.plot3d.parametric_surface", "ParametricSurface") ############################################################################# diff --git a/src/sage/manifolds/trivialization.py b/src/sage/manifolds/trivialization.py index 4c718db8ffe..5898d38a089 100644 --- a/src/sage/manifolds/trivialization.py +++ b/src/sage/manifolds/trivialization.py @@ -20,9 +20,9 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +from sage.manifolds.local_frame import TrivializationFrame from sage.structure.sage_object import SageObject from sage.structure.unique_representation import UniqueRepresentation -from sage.manifolds.local_frame import TrivializationFrame class Trivialization(UniqueRepresentation, SageObject): diff --git a/src/sage/manifolds/utilities.py b/src/sage/manifolds/utilities.py index 190213eeb41..e2a01a1416a 100644 --- a/src/sage/manifolds/utilities.py +++ b/src/sage/manifolds/utilities.py @@ -27,14 +27,15 @@ # **************************************************************************** from operator import pow as _pow -from sage.symbolic.expression import Expression -from sage.symbolic.expression_conversions import ExpressionTreeWalker -from sage.symbolic.ring import SR -from sage.symbolic.constants import pi + from sage.functions.other import abs_symbolic -from sage.misc.functional import sqrt from sage.functions.trig import cos, sin +from sage.misc.functional import sqrt from sage.rings.rational import Rational +from sage.symbolic.constants import pi +from sage.symbolic.expression import Expression +from sage.symbolic.expression_conversions import ExpressionTreeWalker +from sage.symbolic.ring import SR class SimplifySqrtReal(ExpressionTreeWalker): @@ -991,6 +992,7 @@ def _repr_(self): d = d.replace(o, res) import re + from sage.manifolds.manifold import TopologicalManifold if TopologicalManifold.options.omit_function_arguments: list_f = [] @@ -1144,6 +1146,7 @@ def _list_derivatives(ex, list_d, exponent=0): operands = ex.operands() import operator + from sage.misc.latex import latex, latex_variable_name from sage.symbolic.operators import FDerivativeOperator diff --git a/src/sage/manifolds/vector_bundle.py b/src/sage/manifolds/vector_bundle.py index ad830d68469..ebc5e652e14 100644 --- a/src/sage/manifolds/vector_bundle.py +++ b/src/sage/manifolds/vector_bundle.py @@ -32,14 +32,14 @@ # https://www.gnu.org/licenses/ #****************************************************************************** -from sage.structure.category_object import CategoryObject -from sage.categories.vector_bundles import VectorBundles -from sage.structure.unique_representation import UniqueRepresentation import sage.rings.abc +from sage.categories.vector_bundles import VectorBundles +from sage.manifolds.vector_bundle_fiber import VectorBundleFiber from sage.rings.cc import CC -from sage.rings.real_mpfr import RR from sage.rings.integer import Integer -from sage.manifolds.vector_bundle_fiber import VectorBundleFiber +from sage.rings.real_mpfr import RR +from sage.structure.category_object import CategoryObject +from sage.structure.unique_representation import UniqueRepresentation class TopologicalVectorBundle(CategoryObject, UniqueRepresentation): @@ -437,7 +437,7 @@ def trivialization(self, name, domain=None, latex_name=None): """ if domain is None: domain = self._base_space - from .trivialization import Trivialization + from sage.manifolds.trivialization import Trivialization return Trivialization(self, name, domain=domain, latex_name=latex_name) def transitions(self): @@ -638,8 +638,7 @@ def section_module(self, domain=None, force_free=False): """ if domain is None: domain = self._base_space - from sage.manifolds.section_module import (SectionModule, - SectionFreeModule) + from sage.manifolds.section_module import SectionFreeModule, SectionModule if domain not in self._section_modules: if force_free or domain in self._trivial_parts: self._section_modules[domain] = SectionFreeModule(self, domain) @@ -928,8 +927,7 @@ def set_change_of_frame(self, frame1, frame2, change_of_frame, [1 2] [0 3] """ - from sage.tensor.modules.free_module_automorphism import \ - FreeModuleAutomorphism + from sage.tensor.modules.free_module_automorphism import FreeModuleAutomorphism sec_module = frame1._fmodule if frame2._fmodule != sec_module: raise ValueError("the two frames are not defined on the same " + @@ -1154,7 +1152,7 @@ def set_orientation(self, orientation): [Local frame (E|_U, (e_0,e_1)), Local frame (E|_V, (f_0,f_1))] """ - from .local_frame import LocalFrame + from sage.manifolds.local_frame import LocalFrame if isinstance(orientation, LocalFrame): orientation = [orientation] elif isinstance(orientation, (tuple, list)): diff --git a/src/sage/manifolds/vector_bundle_fiber.py b/src/sage/manifolds/vector_bundle_fiber.py index 325ac1582b2..a7cebfba9f8 100644 --- a/src/sage/manifolds/vector_bundle_fiber.py +++ b/src/sage/manifolds/vector_bundle_fiber.py @@ -17,9 +17,9 @@ # http://www.gnu.org/licenses/ #****************************************************************************** +from sage.manifolds.vector_bundle_fiber_element import VectorBundleFiberElement from sage.symbolic.ring import SR from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule -from sage.manifolds.vector_bundle_fiber_element import VectorBundleFiberElement class VectorBundleFiber(FiniteRankFreeModule): From b812c79162c9a6d259db569676e68e387a84a59e Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 1 Dec 2024 19:52:55 +0700 Subject: [PATCH 180/210] Use coercion instead of conversion --- .../rings/polynomial/multi_polynomial_ideal.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 544ef1f4655..ed16c012f53 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -248,6 +248,7 @@ from sage.rings.integer_ring import ZZ from sage.rings.noncommutative_ideals import Ideal_nc from sage.rings.qqbar_decorators import handle_AA_and_QQbar +from sage.structure.element import parent from sage.structure.richcmp import (op_EQ, op_GE, op_GT, op_LE, op_LT, op_NE, rich_to_bool, richcmp_method) from sage.structure.sequence import Sequence @@ -4972,8 +4973,12 @@ def reduce(self, f): sage: I.reduce(1) 1 - sage: I.reduce(pi.n()) # unfortunate side effect - 245850922/78256779 + sage: I.reduce(1r) + 1 + sage: I.reduce(pi.n()) + Traceback (most recent call last): + ... + TypeError: element belong to Real Field with 53 bits of precision, cannot coerce to Multivariate Polynomial Ring in x, y over Rational Field """ try: strat = self._groebner_strategy() @@ -4982,7 +4987,10 @@ def reduce(self, f): pass gb = self.groebner_basis() - return self.ring()(f).reduce(gb) + R = self.ring() + if not R.has_coerce_map_from(parent(f)): + raise TypeError(f"element belong to {parent(f)}, cannot coerce to {R}") + return R(f).reduce(gb) def _contains_(self, f): r""" From b5e7fbb124a1cdf3274741f3d2306e6623dbc307 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 2 Dec 2024 06:26:24 +0700 Subject: [PATCH 181/210] Apply suggested changes Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/multi_polynomial_ideal.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index ed16c012f53..b0b962d3c00 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -4987,10 +4987,8 @@ def reduce(self, f): pass gb = self.groebner_basis() - R = self.ring() - if not R.has_coerce_map_from(parent(f)): - raise TypeError(f"element belong to {parent(f)}, cannot coerce to {R}") - return R(f).reduce(gb) + f = self.ring().coerce(f) + return f.reduce(gb) def _contains_(self, f): r""" From 624d42835b4a1f5f701e83399794df617378b241 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 2 Dec 2024 07:08:30 +0700 Subject: [PATCH 182/210] Fix tests --- src/sage/rings/polynomial/multi_polynomial_ideal.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index b0b962d3c00..2bf05dd0fd7 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -4978,7 +4978,9 @@ def reduce(self, f): sage: I.reduce(pi.n()) Traceback (most recent call last): ... - TypeError: element belong to Real Field with 53 bits of precision, cannot coerce to Multivariate Polynomial Ring in x, y over Rational Field + TypeError: no canonical coercion from Real Field with 53 bits of precision to Multivariate Polynomial Ring in x, y over Rational Field + sage: I.reduce(float(pi.n())) + TypeError: no canonical coercion from to Multivariate Polynomial Ring in x, y over Rational Field """ try: strat = self._groebner_strategy() From b64393117ffec9ef16291b4e8f1c140cde9fedba Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:40:43 +0700 Subject: [PATCH 183/210] Actually fix tests Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/multi_polynomial_ideal.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 2bf05dd0fd7..8db6eb03ea6 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -4980,6 +4980,8 @@ def reduce(self, f): ... TypeError: no canonical coercion from Real Field with 53 bits of precision to Multivariate Polynomial Ring in x, y over Rational Field sage: I.reduce(float(pi.n())) + Traceback (most recent call last): + ... TypeError: no canonical coercion from to Multivariate Polynomial Ring in x, y over Rational Field """ try: From fc99d677e4d6cc2ab6d4c328b70c228f2cbf2fd6 Mon Sep 17 00:00:00 2001 From: Soham Rane Date: Mon, 2 Dec 2024 18:41:00 +0530 Subject: [PATCH 184/210] Improved naming in changelog_trigger.yml --- .github/workflows/changelog_trigger.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/changelog_trigger.yml b/.github/workflows/changelog_trigger.yml index a2192e62230..a639c0e2341 100644 --- a/.github/workflows/changelog_trigger.yml +++ b/.github/workflows/changelog_trigger.yml @@ -8,15 +8,15 @@ jobs: trigger-website-repo-workflow: runs-on: ubuntu-latest steps: - - name: Trigger Workflow in website repo + - name: Trigger Generate Changelog Workflow in website repo env: - GH_TOKEN: ${{ secrets.WEBSITE_ACCESS_TOKEN }} + GITHUB_PAT: ${{ secrets.WEBSITE_ACCESS_TOKEN }} RELEASE_TAG: ${{ github.event.release.tag_name }} run: | curl -L \ -X POST \ -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer $GH_TOKEN" \ + -H "Authorization: Bearer $GITHUB_PAT" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/repos/sagemath/website/actions/workflows/generate_changelog.yml/dispatches \ -d '{"ref":"master","inputs":{"release_tag":"'"$RELEASE_TAG"'"}}' From 2e7e215c30051b964280240006404a4e34fd7f14 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Tue, 3 Dec 2024 14:03:02 +0900 Subject: [PATCH 185/210] It is Issue #12345 --- src/doc/en/developer/coding_in_python.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/en/developer/coding_in_python.rst b/src/doc/en/developer/coding_in_python.rst index bb08408777b..1ea6eebb317 100644 --- a/src/doc/en/developer/coding_in_python.rst +++ b/src/doc/en/developer/coding_in_python.rst @@ -786,13 +786,13 @@ the procedure below: class NewClass: ... - OldClass = NewClass # OldClass is deprecated. See Issue 12345. + OldClass = NewClass # OldClass is deprecated. See Issue #12345. * **Removing a class:** add a comment: .. CODE-BLOCK:: python - # OldClass is deprecated. See Issue 12345. + # OldClass is deprecated. See Issue #12345. class OldClass: From 72d1e6d041eb5ae86edb32668cf8a98afc786a6e Mon Sep 17 00:00:00 2001 From: Soham Rane Date: Tue, 3 Dec 2024 16:51:39 +0530 Subject: [PATCH 186/210] Now changelog generation won't be triggered on pre-release --- .github/workflows/changelog_trigger.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/changelog_trigger.yml b/.github/workflows/changelog_trigger.yml index a639c0e2341..f3456d9b196 100644 --- a/.github/workflows/changelog_trigger.yml +++ b/.github/workflows/changelog_trigger.yml @@ -9,6 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Trigger Generate Changelog Workflow in website repo + if: "!github.event.release.prerelease" env: GITHUB_PAT: ${{ secrets.WEBSITE_ACCESS_TOKEN }} RELEASE_TAG: ${{ github.event.release.tag_name }} From 8a972c4d39ebd61b39885dde30e6b02db9015a89 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Wed, 4 Dec 2024 01:08:45 +0100 Subject: [PATCH 187/210] Updated SageMath version to 10.5 --- CITATION.cff | 4 ++-- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 4 ++-- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/version_requirements.txt | 2 +- build/pkgs/sage_docbuild/version_requirements.txt | 2 +- build/pkgs/sage_setup/version_requirements.txt | 2 +- build/pkgs/sage_sws2rst/version_requirements.txt | 2 +- build/pkgs/sagelib/version_requirements.txt | 2 +- build/pkgs/sagemath_bliss/version_requirements.txt | 2 +- build/pkgs/sagemath_categories/version_requirements.txt | 2 +- build/pkgs/sagemath_coxeter3/version_requirements.txt | 2 +- build/pkgs/sagemath_environment/version_requirements.txt | 2 +- build/pkgs/sagemath_mcqd/version_requirements.txt | 2 +- build/pkgs/sagemath_meataxe/version_requirements.txt | 2 +- build/pkgs/sagemath_objects/version_requirements.txt | 2 +- build/pkgs/sagemath_repl/version_requirements.txt | 2 +- build/pkgs/sagemath_sirocco/version_requirements.txt | 2 +- build/pkgs/sagemath_tdlib/version_requirements.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/doc/en/website/versions.txt | 1 + src/sage/version.py | 6 +++--- 39 files changed, 45 insertions(+), 44 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index c0dbf3d6a37..16ab592bb9a 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.5.rc2 +version: 10.5 doi: 10.5281/zenodo.8042260 -date-released: 2024-11-30 +date-released: 2024-12-04 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 219cada0e3f..e057a4fa381 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.5.rc2, Release Date: 2024-11-30 +SageMath version 10.5, Release Date: 2024-12-04 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 6de96c8fe48..2002501ddee 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,3 +1,3 @@ tarball=configure-VERSION.tar.gz -sha1=7d0d584233b0a52b62dba5eaeaac13d8c38652eb -sha256=02d5e5ee0fad7ccbc99ae92ecb7cfc92260962cb1c8714c6fcd2f561c3d718e6 +sha1=62eedaff4c03b55fdd6f8e1242026226adbf3a16 +sha256=54036d6435218ce1daa7d5d512e1bfd74d3713ed5745d5c49ee1f5e6122a25de diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index cde04b63e0e..c2d9070ce76 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -a60f0455273de4b2b07878d92e8357d8d9a839c8 +f6ad0ecf1f4a269f5954d5487336b13f70624594 diff --git a/build/pkgs/sage_conf/version_requirements.txt b/build/pkgs/sage_conf/version_requirements.txt index 11ae1c5d2a5..a979e585a50 100644 --- a/build/pkgs/sage_conf/version_requirements.txt +++ b/build/pkgs/sage_conf/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.5rc2 +sage-conf ~= 10.5 diff --git a/build/pkgs/sage_docbuild/version_requirements.txt b/build/pkgs/sage_docbuild/version_requirements.txt index b2dd3fbec85..e1fac619a47 100644 --- a/build/pkgs/sage_docbuild/version_requirements.txt +++ b/build/pkgs/sage_docbuild/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.5rc2 +sage-docbuild ~= 10.5 diff --git a/build/pkgs/sage_setup/version_requirements.txt b/build/pkgs/sage_setup/version_requirements.txt index c9bffddf1dc..7eac3993c51 100644 --- a/build/pkgs/sage_setup/version_requirements.txt +++ b/build/pkgs/sage_setup/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.5rc2 +sage-setup ~= 10.5 diff --git a/build/pkgs/sage_sws2rst/version_requirements.txt b/build/pkgs/sage_sws2rst/version_requirements.txt index 44d72b63d93..3116bf7335f 100644 --- a/build/pkgs/sage_sws2rst/version_requirements.txt +++ b/build/pkgs/sage_sws2rst/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.5rc2 +sage-sws2rst ~= 10.5 diff --git a/build/pkgs/sagelib/version_requirements.txt b/build/pkgs/sagelib/version_requirements.txt index 49cf1f431c8..d3ff4cfaa4e 100644 --- a/build/pkgs/sagelib/version_requirements.txt +++ b/build/pkgs/sagelib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-standard ~= 10.5rc2 +sagemath-standard ~= 10.5 diff --git a/build/pkgs/sagemath_bliss/version_requirements.txt b/build/pkgs/sagemath_bliss/version_requirements.txt index 97488091046..168679d2732 100644 --- a/build/pkgs/sagemath_bliss/version_requirements.txt +++ b/build/pkgs/sagemath_bliss/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.5rc2 +sagemath-bliss ~= 10.5 diff --git a/build/pkgs/sagemath_categories/version_requirements.txt b/build/pkgs/sagemath_categories/version_requirements.txt index 38d0f576482..ce0889bf57b 100644 --- a/build/pkgs/sagemath_categories/version_requirements.txt +++ b/build/pkgs/sagemath_categories/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.5rc2 +sagemath-categories ~= 10.5 diff --git a/build/pkgs/sagemath_coxeter3/version_requirements.txt b/build/pkgs/sagemath_coxeter3/version_requirements.txt index 74fcc5180f1..3cb8ea71df9 100644 --- a/build/pkgs/sagemath_coxeter3/version_requirements.txt +++ b/build/pkgs/sagemath_coxeter3/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.5rc2 +sagemath-coxeter3 ~= 10.5 diff --git a/build/pkgs/sagemath_environment/version_requirements.txt b/build/pkgs/sagemath_environment/version_requirements.txt index 17b0f996c23..7dda12e45a9 100644 --- a/build/pkgs/sagemath_environment/version_requirements.txt +++ b/build/pkgs/sagemath_environment/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.5rc2 +sagemath-environment ~= 10.5 diff --git a/build/pkgs/sagemath_mcqd/version_requirements.txt b/build/pkgs/sagemath_mcqd/version_requirements.txt index e25bbd7cbf5..9e1ef4f46bb 100644 --- a/build/pkgs/sagemath_mcqd/version_requirements.txt +++ b/build/pkgs/sagemath_mcqd/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.5rc2 +sagemath-mcqd ~= 10.5 diff --git a/build/pkgs/sagemath_meataxe/version_requirements.txt b/build/pkgs/sagemath_meataxe/version_requirements.txt index 839d6691290..f877d05503f 100644 --- a/build/pkgs/sagemath_meataxe/version_requirements.txt +++ b/build/pkgs/sagemath_meataxe/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.5rc2 +sagemath-meataxe ~= 10.5 diff --git a/build/pkgs/sagemath_objects/version_requirements.txt b/build/pkgs/sagemath_objects/version_requirements.txt index 2087671be40..55b2a515688 100644 --- a/build/pkgs/sagemath_objects/version_requirements.txt +++ b/build/pkgs/sagemath_objects/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.5rc2 +sagemath-objects ~= 10.5 diff --git a/build/pkgs/sagemath_repl/version_requirements.txt b/build/pkgs/sagemath_repl/version_requirements.txt index cf19972eb63..3b19e791c62 100644 --- a/build/pkgs/sagemath_repl/version_requirements.txt +++ b/build/pkgs/sagemath_repl/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.5rc2 +sagemath-repl ~= 10.5 diff --git a/build/pkgs/sagemath_sirocco/version_requirements.txt b/build/pkgs/sagemath_sirocco/version_requirements.txt index eb2af632ca7..fb52db7e2e5 100644 --- a/build/pkgs/sagemath_sirocco/version_requirements.txt +++ b/build/pkgs/sagemath_sirocco/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.5rc2 +sagemath-sirocco ~= 10.5 diff --git a/build/pkgs/sagemath_tdlib/version_requirements.txt b/build/pkgs/sagemath_tdlib/version_requirements.txt index ebd9f2961a9..61cefc36c54 100644 --- a/build/pkgs/sagemath_tdlib/version_requirements.txt +++ b/build/pkgs/sagemath_tdlib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.5rc2 +sagemath-tdlib ~= 10.5 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/src/VERSION.txt b/src/VERSION.txt index 861a196a402..9a62de225f0 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.5.rc2 +10.5 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 0386f6ef5aa..b6288bff917 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.5.rc2' -SAGE_RELEASE_DATE='2024-11-30' -SAGE_VERSION_BANNER='SageMath version 10.5.rc2, Release Date: 2024-11-30' +SAGE_VERSION='10.5' +SAGE_RELEASE_DATE='2024-12-04' +SAGE_VERSION_BANNER='SageMath version 10.5, Release Date: 2024-12-04' diff --git a/src/doc/en/website/versions.txt b/src/doc/en/website/versions.txt index 12aed2b8cfe..6d1a9aa05ea 100644 --- a/src/doc/en/website/versions.txt +++ b/src/doc/en/website/versions.txt @@ -7,6 +7,7 @@ # The sage-update-version script adds a new line for a new stable release # when run by the Sage release manager to prepare a new release # +10.5 doc-10-5--sagemath.netlify.app 10.4 doc-10-4--sagemath.netlify.app 10.3 doc-10-3--sagemath.netlify.app 10.2 doc-10-2--sagemath.netlify.app diff --git a/src/sage/version.py b/src/sage/version.py index 8e15dcf37c7..cc61dd0ca38 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '10.5.rc2' -date = '2024-11-30' -banner = 'SageMath version 10.5.rc2, Release Date: 2024-11-30' +version = '10.5' +date = '2024-12-04' +banner = 'SageMath version 10.5, Release Date: 2024-12-04' From 283a86ef8e81de65f009c4677c0d479b0d86a759 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sun, 1 Dec 2024 22:08:25 +0900 Subject: [PATCH 188/210] Check effective divisor degree depending on the model --- src/sage/rings/function_field/jacobian_base.py | 2 +- src/sage/rings/function_field/jacobian_hess.py | 8 ++++++-- src/sage/rings/function_field/jacobian_khuri_makdisi.py | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/function_field/jacobian_base.py b/src/sage/rings/function_field/jacobian_base.py index 405d90bfc3f..7010b49e6aa 100644 --- a/src/sage/rings/function_field/jacobian_base.py +++ b/src/sage/rings/function_field/jacobian_base.py @@ -668,7 +668,7 @@ def __call__(self, x): if x in F.divisor_group(): G = self.group() return G.point(x) - raise ValueError(f"Cannot create a point of the Jacobian from {x}") + raise ValueError(f"cannot create a point of the Jacobian from {x}") def curve(self): """ diff --git a/src/sage/rings/function_field/jacobian_hess.py b/src/sage/rings/function_field/jacobian_hess.py index a85bc10e256..681a703da00 100644 --- a/src/sage/rings/function_field/jacobian_hess.py +++ b/src/sage/rings/function_field/jacobian_hess.py @@ -606,7 +606,7 @@ def _element_constructor_(self, x): """ Construct an element of ``self`` from ``x``. - If ``x`` is an effective divisor, then it is assumed to of + If ``x`` is an effective divisor, then it is assumed to be of degree `g`, the genus of the function field. EXAMPLES:: @@ -634,9 +634,11 @@ def _element_constructor_(self, x): if x.degree() == 0: return self.point(x) if x.is_effective(): + if x.degree() != self._genus: + raise ValueError(f"effective divisor is not of degree {self._genus}") return self.element_class(self, *self._get_dS_ds(x)) - raise ValueError(f"Cannot construct a point from {x}") + raise ValueError(f"cannot construct a point from {x}") def _get_dS_ds(self, divisor): """ @@ -805,6 +807,8 @@ def point(self, divisor): sage: G.point(p - b) [Place (y + 2, z + 1)] """ + if divisor.degree() != 0: + raise ValueError('divisor not of degree zero') c = divisor + self._base_div f = c.basis_function_space()[0] d = f.divisor() + c diff --git a/src/sage/rings/function_field/jacobian_khuri_makdisi.py b/src/sage/rings/function_field/jacobian_khuri_makdisi.py index 2c9a2e5da97..b303a45a5ea 100644 --- a/src/sage/rings/function_field/jacobian_khuri_makdisi.py +++ b/src/sage/rings/function_field/jacobian_khuri_makdisi.py @@ -619,6 +619,7 @@ def __init__(self, parent, function_field, base_div): D0 = base_div + self._base_div_degree = base_div.degree() self._V_cache = 10*[None] V_cache = self._V_cache @@ -760,10 +761,12 @@ def _element_constructor_(self, x): if x.degree() == 0: return self.point(x) if x.is_effective(): + if x.degree() != self._base_div_degree: + raise ValueError(f"effective divisor is not of degree {self._base_div_degree}") wd = self._wd_from_divisor(x) return self.element_class(self, wd) - raise ValueError(f"Cannot construct a point from {x}") + raise ValueError(f"cannot construct a point from {x}") def point(self, divisor): """ From 2e45de7f8ac622cd70081a3400713854462485f4 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Mon, 2 Dec 2024 19:58:10 +0900 Subject: [PATCH 189/210] Allow effective divisor input for Jacobian --- src/sage/rings/function_field/jacobian_base.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/jacobian_base.py b/src/sage/rings/function_field/jacobian_base.py index 7010b49e6aa..d2840371f41 100644 --- a/src/sage/rings/function_field/jacobian_base.py +++ b/src/sage/rings/function_field/jacobian_base.py @@ -666,8 +666,7 @@ def __call__(self, x): if x == 0: return self.group().zero() if x in F.divisor_group(): - G = self.group() - return G.point(x) + return self.group()(x) raise ValueError(f"cannot create a point of the Jacobian from {x}") def curve(self): From adf63a0fcec71d5274d1a056058a8f7ef0198413 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Mon, 2 Dec 2024 20:39:16 +0900 Subject: [PATCH 190/210] Add long time to doctests taking long --- .../rings/function_field/jacobian_base.py | 3 ++ .../function_field/jacobian_khuri_makdisi.py | 29 +++++++++++++++++++ .../rings/function_field/khuri_makdisi.pyx | 21 ++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/src/sage/rings/function_field/jacobian_base.py b/src/sage/rings/function_field/jacobian_base.py index d2840371f41..8e6065e6e04 100644 --- a/src/sage/rings/function_field/jacobian_base.py +++ b/src/sage/rings/function_field/jacobian_base.py @@ -52,6 +52,7 @@ We can get the corresponding point in the Jacobian in a different model. :: + sage: # long time sage: p1km = J_km(p1) sage: p1km.order() 5 @@ -111,6 +112,7 @@ def order(self): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(29), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: F = C.function_field() @@ -640,6 +642,7 @@ def __call__(self, x): TESTS:: + sage: # long time sage: K. = FunctionField(GF(2)); _. = K[] sage: F. = K.extension(Y^2 + Y + x + 1/x) sage: J_hess = F.jacobian(model='hess') diff --git a/src/sage/rings/function_field/jacobian_khuri_makdisi.py b/src/sage/rings/function_field/jacobian_khuri_makdisi.py index b303a45a5ea..4a86a2d4a08 100644 --- a/src/sage/rings/function_field/jacobian_khuri_makdisi.py +++ b/src/sage/rings/function_field/jacobian_khuri_makdisi.py @@ -68,6 +68,7 @@ EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: F = C.function_field() @@ -154,6 +155,7 @@ class JacobianPoint(JacobianPoint_base): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: b = C([0,1,0]).place() @@ -176,6 +178,7 @@ def __init__(self, parent, w): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: b = C([0,1,0]).place() @@ -196,6 +199,7 @@ def _repr_(self): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -218,6 +222,7 @@ def __hash__(self): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: F = C.function_field() @@ -242,6 +247,7 @@ def _richcmp_(self, other, op): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -275,6 +281,7 @@ def _add_(self, other): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -306,6 +313,7 @@ def _neg_(self): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: F = C.function_field() @@ -340,6 +348,7 @@ def _rmul_(self, n): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -363,6 +372,7 @@ def multiple(self, n): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -394,6 +404,7 @@ def addflip(self, other): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -426,6 +437,7 @@ def defining_matrix(self): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -450,6 +462,7 @@ def divisor(self): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: F = C.function_field() @@ -493,6 +506,7 @@ class JacobianGroupEmbedding(Map): EXAMPLES:: + sage: # long time sage: k = GF(5) sage: P2. = ProjectiveSpace(k, 2) sage: C = Curve(x^3 + z^3 - y^2*z, P2) @@ -514,6 +528,7 @@ def __init__(self, base_group, extension_group): TESTS:: + sage: # long time sage: k = GF(5) sage: P2. = ProjectiveSpace(k, 2) sage: C = Curve(x^3 + z^3 - y^2*z, P2) @@ -538,6 +553,7 @@ def _repr_type(self): TESTS:: + sage: # long time sage: k = GF(5) sage: P2. = ProjectiveSpace(k, 2) sage: C = Curve(x^3 + z^3 - y^2*z, P2) @@ -561,6 +577,7 @@ def _call_(self, x): TESTS:: + sage: # long time sage: k = GF(5) sage: P2. = ProjectiveSpace(k, 2) sage: C = Curve(x^3 + z^3 - y^2*z, P2) @@ -592,6 +609,7 @@ class JacobianGroup(UniqueRepresentation, JacobianGroup_base): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -609,6 +627,7 @@ def __init__(self, parent, function_field, base_div): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -673,6 +692,7 @@ def _repr_(self): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -694,6 +714,7 @@ def _wd_from_divisor(self, x): TESTS: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -720,6 +741,7 @@ def _element_constructor_(self, x): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -778,6 +800,7 @@ def point(self, divisor): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -811,6 +834,7 @@ def zero(self): EXAMPLES:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -842,6 +866,7 @@ class JacobianGroup_finite_field(JacobianGroup, JacobianGroup_finite_field_base) EXAMPLES:: + sage: # long time sage: k = GF(7) sage: P2. = ProjectiveSpace(k, 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) @@ -865,6 +890,7 @@ def __init__(self, parent, function_field, base_div): TESTS:: + sage: # long time sage: k = GF(7) sage: P2. = ProjectiveSpace(k, 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) @@ -955,6 +981,7 @@ def _frobenius_on(self, pt): TESTS:: + sage: # long time sage: k = GF(7) sage: A. = AffineSpace(k,2) sage: C = Curve(y^2 + x^3 + 2*x + 1).projective_closure() @@ -989,6 +1016,7 @@ def __init__(self, function_field, base_div, model, **kwds): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: J = C.jacobian(model='km_large') @@ -996,6 +1024,7 @@ def __init__(self, function_field, base_div, model, **kwds): :: + sage: # long time sage: J = C.jacobian(model='km_unknown') Traceback (most recent call last): ... diff --git a/src/sage/rings/function_field/khuri_makdisi.pyx b/src/sage/rings/function_field/khuri_makdisi.pyx index 5933abcd1ce..aa64322b0ed 100644 --- a/src/sage/rings/function_field/khuri_makdisi.pyx +++ b/src/sage/rings/function_field/khuri_makdisi.pyx @@ -86,6 +86,7 @@ cdef class KhuriMakdisi_base(object): TESTS:: + sage: # long time sage: k = GF(7) sage: A. = AffineSpace(k,2) sage: C = Curve(y^2 + x^3 + 2*x + 1).projective_closure() @@ -180,6 +181,7 @@ cdef class KhuriMakdisi_base(object): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -205,6 +207,7 @@ cdef class KhuriMakdisi_base(object): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -230,6 +233,7 @@ cdef class KhuriMakdisi_base(object): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -255,6 +259,7 @@ cdef class KhuriMakdisi_base(object): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -324,6 +329,7 @@ cdef class KhuriMakdisi_base(object): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -357,6 +363,7 @@ cdef class KhuriMakdisi_large(KhuriMakdisi_base): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -414,6 +421,7 @@ cdef class KhuriMakdisi_large(KhuriMakdisi_base): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: J = C.jacobian(model='km_large') @@ -476,6 +484,7 @@ cdef class KhuriMakdisi_large(KhuriMakdisi_base): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: F = C.function_field() @@ -507,6 +516,7 @@ cdef class KhuriMakdisi_large(KhuriMakdisi_base): TESTS:: + sage: # long time sage: k = GF(7) sage: A. = AffineSpace(k,2) sage: C = Curve(y^2 + x^3 + 2*x + 1).projective_closure() @@ -537,6 +547,7 @@ cdef class KhuriMakdisi_medium(KhuriMakdisi_base): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -588,6 +599,7 @@ cdef class KhuriMakdisi_medium(KhuriMakdisi_base): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -623,6 +635,7 @@ cdef class KhuriMakdisi_medium(KhuriMakdisi_base): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: h = C.function(y/x).divisor_of_poles() @@ -642,6 +655,7 @@ cdef class KhuriMakdisi_medium(KhuriMakdisi_base): We check the computation in other model:: + sage: # long time sage: J = C.jacobian(model='km_large', base_div=h) sage: G = J.group() sage: p1 = G.point(pl1 - b) @@ -671,6 +685,7 @@ cdef class KhuriMakdisi_medium(KhuriMakdisi_base): TESTS:: + sage: # long time sage: k = GF(7) sage: A. = AffineSpace(k,2) sage: C = Curve(y^2 + x^3 + 2*x + 1).projective_closure() @@ -702,6 +717,7 @@ cdef class KhuriMakdisi_small(KhuriMakdisi_base): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: b = C([0,1,0]).place() @@ -759,6 +775,7 @@ cdef class KhuriMakdisi_small(KhuriMakdisi_base): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: b = C([0,1,0]).place() @@ -793,6 +810,7 @@ cdef class KhuriMakdisi_small(KhuriMakdisi_base): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(17), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: b = C([0,1,0]).place() @@ -812,6 +830,7 @@ cdef class KhuriMakdisi_small(KhuriMakdisi_base): We check the computation in other model:: + sage: # long time sage: h = C.function(y/x).divisor_of_poles() sage: Jl = C.jacobian(model='km_large', base_div=h) sage: G = J.group() @@ -840,6 +859,7 @@ cdef class KhuriMakdisi_small(KhuriMakdisi_base): TESTS:: + sage: # long time sage: P2. = ProjectiveSpace(GF(7), 2) sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2) sage: b = C([0,1,0]).place() @@ -874,6 +894,7 @@ cdef class KhuriMakdisi_small(KhuriMakdisi_base): TESTS:: + sage: # long time sage: k = GF(7) sage: A. = AffineSpace(k,2) sage: C = Curve(y^2 + x^3 + 2*x + 1).projective_closure() From ef5b89a1878c8a0972ed8fcdec7b1a2d3949021a Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Tue, 3 Dec 2024 12:44:30 +0900 Subject: [PATCH 191/210] Add a test --- .../rings/function_field/jacobian_base.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/sage/rings/function_field/jacobian_base.py b/src/sage/rings/function_field/jacobian_base.py index 8e6065e6e04..a6b1e328ad3 100644 --- a/src/sage/rings/function_field/jacobian_base.py +++ b/src/sage/rings/function_field/jacobian_base.py @@ -654,6 +654,27 @@ def __call__(self, x): True sage: J_hess(q) == p True + + If ``x`` is an effective divisor, it is checked that the degree + is equal to the degree of the base divisor. See :issue:38623. + + sage: K. = FunctionField(GF(7)) + sage: _. = K[] + sage: F. = K.extension(t^2 - x^6 - 3) + sage: O = F.maximal_order() + sage: D1 = (O.ideal(x + 1, y + 2)*O.ideal(x + 2, y + 2)).divisor() + sage: I = O.ideal(x + 3, y+5)*O.ideal(x + 4, y + 5)*O.ideal(x + 5, y + 5) + sage: D2 = I.divisor() + sage: J = F.jacobian(model='hess') + sage: J(D1) + [Place (x + 1, y + 2) + + Place (x + 2, y + 2)] + sage: J(D2) + Traceback (most recent call last): + ... + ValueError: effective divisor is not of degree 2 + sage: J.base_divisor().degree() + 2 """ F = self._function_field if isinstance(x, JacobianPoint_base): From cadec3965d9fb6c5dfaf514d4bd6590ac1271a62 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Tue, 3 Dec 2024 13:13:32 +0900 Subject: [PATCH 192/210] Satisfy lint --- src/sage/rings/function_field/jacobian_base.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/jacobian_base.py b/src/sage/rings/function_field/jacobian_base.py index a6b1e328ad3..03d12212ae6 100644 --- a/src/sage/rings/function_field/jacobian_base.py +++ b/src/sage/rings/function_field/jacobian_base.py @@ -667,8 +667,7 @@ def __call__(self, x): sage: D2 = I.divisor() sage: J = F.jacobian(model='hess') sage: J(D1) - [Place (x + 1, y + 2) - + Place (x + 2, y + 2)] + [Place (x + 1, y + 2) + Place (x + 2, y + 2)] sage: J(D2) Traceback (most recent call last): ... From 60e7a5cd9a3076b624e93b432ce684d54d775e40 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 4 Dec 2024 11:55:19 +0900 Subject: [PATCH 193/210] Do reviewer suggestions again --- src/sage/rings/function_field/jacobian_base.py | 6 +++--- src/sage/rings/function_field/jacobian_hess.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/function_field/jacobian_base.py b/src/sage/rings/function_field/jacobian_base.py index 03d12212ae6..177ea6058ab 100644 --- a/src/sage/rings/function_field/jacobian_base.py +++ b/src/sage/rings/function_field/jacobian_base.py @@ -656,14 +656,14 @@ def __call__(self, x): True If ``x`` is an effective divisor, it is checked that the degree - is equal to the degree of the base divisor. See :issue:38623. + is equal to the degree of the base divisor. See :issue:`38623`. sage: K. = FunctionField(GF(7)) sage: _. = K[] sage: F. = K.extension(t^2 - x^6 - 3) sage: O = F.maximal_order() - sage: D1 = (O.ideal(x + 1, y + 2)*O.ideal(x + 2, y + 2)).divisor() - sage: I = O.ideal(x + 3, y+5)*O.ideal(x + 4, y + 5)*O.ideal(x + 5, y + 5) + sage: D1 = (O.ideal(x + 1, y + 2) * O.ideal(x + 2, y + 2)).divisor() + sage: I = O.ideal(x + 3, y+5) * O.ideal(x + 4, y + 5) * O.ideal(x + 5, y + 5) sage: D2 = I.divisor() sage: J = F.jacobian(model='hess') sage: J(D1) diff --git a/src/sage/rings/function_field/jacobian_hess.py b/src/sage/rings/function_field/jacobian_hess.py index 681a703da00..882b2eb917d 100644 --- a/src/sage/rings/function_field/jacobian_hess.py +++ b/src/sage/rings/function_field/jacobian_hess.py @@ -606,7 +606,7 @@ def _element_constructor_(self, x): """ Construct an element of ``self`` from ``x``. - If ``x`` is an effective divisor, then it is assumed to be of + If ``x`` is an effective divisor, then it must be of degree `g`, the genus of the function field. EXAMPLES:: From b488cff3ee3f009e315342a05e6f2a82a01d5236 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sun, 1 Dec 2024 21:16:56 +0000 Subject: [PATCH 194/210] unbreak "--disable-sage_conf" --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 067b10c99d8..29812af6e97 100644 --- a/configure.ac +++ b/configure.ac @@ -431,7 +431,7 @@ AS_IF([test "x$enable_download_from_upstream_url" = "xyes"], [ ]) AC_SUBST([SAGE_SPKG_OPTIONS]) -AC_ARG_ENABLE([sagelib], +AC_ARG_ENABLE([sage_conf], AS_HELP_STRING([--disable-sage_conf], [disable build of the sage_conf package]), [ for pkg in sage_conf; do From cb8dfaf8a5a2b22b4223b077aa30e769f4cacf45 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 5 Dec 2024 00:26:34 +0900 Subject: [PATCH 195/210] Remove jupyter_execute directories after doc build --- .github/workflows/doc-build.yml | 8 ++++++-- src/doc/Makefile | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 5eb5e932da9..8ab585606d1 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -202,6 +202,10 @@ jobs: if: steps.docbuild.outcome == 'success' run: | set -ex + # Remove any existing html directory before copying a new one + if [ -d "doc/html" ]; then + rm -rf doc/html + fi # Simpler "docker cp --follow-link ... doc" does not work mkdir -p doc mkdir -p temp @@ -217,7 +221,7 @@ jobs: fi # If so, then create CHANGES.html if [[ -n "$PR_NUMBER" ]]; then - (cd doc && git commit -a -m 'new') + (cd doc && git add -A && git commit --quiet -m 'new') # Wipe out chronic diffs of new doc against old doc before creating CHANGES.html (cd doc && \ find . -name "*.html" | xargs sed -i -e '/This is documentation/ s/ built with GitHub PR .* for development/ for development/' \ @@ -229,7 +233,7 @@ jobs: # Since HEAD is at commit 'wipe-out', HEAD~1 is commit 'new' (new doc), HEAD~2 is commit 'old' (old doc) (cd doc && git diff $(git rev-parse HEAD~2) -- "*.html") > diff.txt # Restore the new doc dropping changes by "wipe out" - (cd doc && git checkout -q -f HEAD~1) + (cd doc && git checkout --quiet -f HEAD~1) .ci/create-changes-html.sh diff.txt doc # Sometimes rm -rf .git errors out because of some diehard hidden files # So we simply move it out of the doc directory diff --git a/src/doc/Makefile b/src/doc/Makefile index 98a3d138baf..9c03292b070 100644 --- a/src/doc/Makefile +++ b/src/doc/Makefile @@ -66,6 +66,8 @@ doc-html-other: doc-html-reference $(MAKE) $(foreach doc, $(wordlist 2, 100, $(DOCS)), doc-html--$(subst /,-,$(doc))) doc-html: doc-html-reference doc-html-other + SAGE_DOC=$$(sage --python -c "from sage.env import SAGE_DOC; print(SAGE_DOC)") + find $${SAGE_DOC}/html -type d -path "*/jupyter_execute" -exec rm -rf {} + # Matches doc-pdf--developer, doc-pdf--reference-manifolds etc. doc-pdf--%: @@ -88,7 +90,8 @@ doc-pdf-other: doc-pdf-reference $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" $(foreach doc, $(wordlist 2, 100, $(DOCS)), doc-pdf--$(subst /,-,$(doc))) doc-pdf: doc-pdf-reference doc-pdf-other - + SAGE_DOC=$$(sage --python -c "from sage.env import SAGE_DOC; print(SAGE_DOC)") + find $${SAGE_DOC}/latex -type d -path "*/jupyter_execute" -exec rm -rf {} + .PHONY: all clean \ doc-src \ From 0969afc63c7c79d772b1428d1d8f4ba9a7e76c0a Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 12 Nov 2024 20:51:34 -0500 Subject: [PATCH 196/210] src/sage/libs/giac/giac.pyx: fix signed infinity handling Before this commit, signed Sage infinities would be converted to unsigned Giac infinities: sage: libgiac(+Infinity) Infinity This can mess up your integrals, if nothing else. To fix it, we add an additional case to the Pygen constructor. Sage's AnInfinity class already knows how to convert itself to a Giac-friendly string, and Pygen already knows what to do with those strings -- we just need to put the pieces together. A new test case is added as well. --- src/sage/libs/giac/giac.pyx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/libs/giac/giac.pyx b/src/sage/libs/giac/giac.pyx index 91c42f3132c..65279b16504 100644 --- a/src/sage/libs/giac/giac.pyx +++ b/src/sage/libs/giac/giac.pyx @@ -102,6 +102,13 @@ TESTS:: sage: libgiac(-11^1000) -2469932918005826334124088385085221477709733385238396234869182951830739390375433175367866116456946191973803561189036523363533798726571008961243792655536655282201820357872673322901148243453211756020067624545609411212063417307681204817377763465511222635167942816318177424600927358163388910854695041070577642045540560963004207926938348086979035423732739933235077042750354729095729602516751896320598857608367865475244863114521391548985943858154775884418927768284663678512441565517194156946312753546771163991252528017732162399536497445066348868438762510366191040118080751580689254476068034620047646422315123643119627205531371694188794408120267120500325775293645416335230014278578281272863450085145349124727476223298887655183167465713337723258182649072572861625150703747030550736347589416285606367521524529665763903537989935510874657420361426804068643262800901916285076966174176854351055183740078763891951775452021781225066361670593917001215032839838911476044840388663443684517735022039957481918726697789827894303408292584258328090724141496484460001 +Ensure that signed infinities get converted correctly:: + + sage: libgiac(+Infinity) + +infinity + sage: libgiac(-Infinity) + -infinity + .. SEEALSO:: ``libgiac``, ``giacsettings``, ``Pygen``,``loadgiacgen`` @@ -159,6 +166,7 @@ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing from sage.rings.integer cimport Integer +from sage.rings.infinity import AnInfinity from sage.rings.rational cimport Rational from sage.structure.element cimport Matrix @@ -860,6 +868,8 @@ cdef class Pygen(GiacMethods_base): s = s._giac_init_() except AttributeError: s = SRexpressiontoGiac(s) + elif isinstance(s, AnInfinity): + s = s._giac_init_() if not isinstance(s, str): s = s.__str__() sig_on() From 4321354c61addc756259d77a454d04740a044fc3 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 13 Sep 2024 17:47:42 -0400 Subject: [PATCH 197/210] src/sage/symbolic/integration/integral.py: use libgiac for "giac" integration The library interface to libgiac is much more efficient than the pexpect one, but the name algorithm="giac" is more attractive (especially to newcomers) than algorithm="libgiac". We should just Do The Right Thing and use libgiac when "giac" is requested. --- src/sage/symbolic/integration/integral.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/symbolic/integration/integral.py b/src/sage/symbolic/integration/integral.py index 0877d132030..f569ef46c54 100644 --- a/src/sage/symbolic/integration/integral.py +++ b/src/sage/symbolic/integration/integral.py @@ -28,7 +28,7 @@ available_integrators['sympy'] = external.sympy_integrator available_integrators['mathematica_free'] = external.mma_free_integrator available_integrators['fricas'] = external.fricas_integrator -available_integrators['giac'] = external.giac_integrator +available_integrators['giac'] = external.libgiac_integrator available_integrators['libgiac'] = external.libgiac_integrator ###################################################### @@ -474,9 +474,9 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): - ``'fricas'`` -- use FriCAS (the optional fricas spkg has to be installed) - - ``'giac'`` -- use Giac + - ``'giac'`` -- use libgiac - - ``'libgiac'`` -- use libgiac + - ``'libgiac'`` -- use libgiac (alias for ``'giac'``) To prevent automatic evaluation, use the ``hold`` argument. From ce4add225c0c608e2542516d8c63884c446c6836 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 13 Sep 2024 17:45:29 -0400 Subject: [PATCH 198/210] src/sage/symbolic/integration/external.py: drop pexpect giac integrator The pexpect integrator is unused now that the "giac" integrator uses libgiac. We also add a few "# needs sage.libs.giac" tags to the tests that use the libgiac integrator, because they obviously will fail when libgiac is not there. --- src/sage/symbolic/integration/external.py | 44 ++--------------------- 1 file changed, 3 insertions(+), 41 deletions(-) diff --git a/src/sage/symbolic/integration/external.py b/src/sage/symbolic/integration/external.py index 5f647228564..ef05676c727 100644 --- a/src/sage/symbolic/integration/external.py +++ b/src/sage/symbolic/integration/external.py @@ -214,53 +214,13 @@ def fricas_integrator(expression, v, a=None, b=None, noPole=True): return result -def giac_integrator(expression, v, a=None, b=None): - r""" - Integration using Giac. - - EXAMPLES:: - - sage: from sage.symbolic.integration.external import giac_integrator - sage: giac_integrator(sin(x), x) - -cos(x) - sage: giac_integrator(1/(x^2+6), x, -oo, oo) - 1/6*sqrt(6)*pi - - TESTS:: - - sage: giac_integrator(e^(-x^2)*log(x), x) - integrate(e^(-x^2)*log(x), x) - - Check that :issue:`30133` is fixed:: - - sage: ee = SR.var('e') - sage: giac_integrator(ee^x, x) - e^x/log(e) - sage: y = SR.var('π') - sage: giac_integrator(cos(y), y) - sin(π) - - Check that :issue:`29966` is fixed:: - - sage: giac_integrator(sqrt(x + sqrt(x)), x) - 1/12*(2*sqrt(x)*(4*sqrt(x) + 1) - 3)*sqrt(x + sqrt(x))... - """ - ex = expression._giac_() - if a is None: - result = ex.integrate(v._giac_()) - else: - result = ex.integrate(v._giac_(), a._giac_(), b._giac_()) - if 'integrate' in format(result) or 'integration' in format(result): - return expression.integrate(v, a, b, hold=True) - return result._sage_() - - def libgiac_integrator(expression, v, a=None, b=None): r""" Integration using libgiac. EXAMPLES:: + sage: # needs sage.libs.giac sage: import sage.libs.giac ... sage: from sage.symbolic.integration.external import libgiac_integrator @@ -272,12 +232,14 @@ def libgiac_integrator(expression, v, a=None, b=None): TESTS:: + sage: # needs sage.libs.giac sage: libgiac_integrator(e^(-x^2)*log(x), x) integrate(e^(-x^2)*log(x), x) The following integral fails with the Giac Pexpect interface, but works with libgiac (:issue:`31873`):: + sage: # needs sage.libs.giac sage: a, x = var('a,x') sage: f = sec(2*a*x) sage: F = libgiac_integrator(f, x) From a9b2b81cd5e10c60b7b7b47760e415da40707ac7 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 20 Sep 2024 09:37:59 -0400 Subject: [PATCH 199/210] src/sage/calculus/calculus.py: add "needs" for libgiac integration One example in this file integrates with algorithm='giac', which can fail if sage.libs.giac is not available to perform the integration. --- src/sage/calculus/calculus.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py index ef4854db676..64881aba812 100644 --- a/src/sage/calculus/calculus.py +++ b/src/sage/calculus/calculus.py @@ -387,6 +387,7 @@ Ensure that :issue:`25626` is fixed. As the form of the answer is dependent of the giac version, we simplify it (see :issue:`34037`):: + sage: # needs sage.libs.giac sage: t = SR.var('t') sage: integrate(exp(t)/(t + 1)^2, t, algorithm='giac').full_simplify() ((t + 1)*Ei(t + 1) - e^(t + 1))/(t*e + e) From 05c5d4ba1e5951150b73bb26cf86548000336296 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 20 Sep 2024 09:38:16 -0400 Subject: [PATCH 200/210] src/sage/functions/piecewise.py: add "needs" for libgiac integration One example in this file integrates with algorithm='giac', which can fail if sage.libs.giac is not available to perform the integration. --- src/sage/functions/piecewise.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/functions/piecewise.py b/src/sage/functions/piecewise.py index fc69057ef6f..2986e47960d 100644 --- a/src/sage/functions/piecewise.py +++ b/src/sage/functions/piecewise.py @@ -836,6 +836,7 @@ def integral(self, parameters, variable, x=None, a=None, b=None, definite=False, Check that the algorithm keyword can be used:: + sage: # needs sage.libs.giac sage: ex = piecewise([([0, 1], 1), ((1, oo), 1/x**2)]) sage: integral(ex, x, 0, 100, algorithm='sympy') 199/100 From 1287b718074479e423a90a89fd71b5e98a646659 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 20 Sep 2024 09:38:35 -0400 Subject: [PATCH 201/210] src/sage/symbolic/integration/integral.py: add "needs" for libgiac integration A few examples in this file integrate with algorithm='giac', which can fail if sage.libs.giac is not available to perform the integration. --- src/sage/symbolic/integration/integral.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/symbolic/integration/integral.py b/src/sage/symbolic/integration/integral.py index f569ef46c54..98a9266f3a0 100644 --- a/src/sage/symbolic/integration/integral.py +++ b/src/sage/symbolic/integration/integral.py @@ -59,6 +59,7 @@ def __init__(self): Check for :issue:`28913`:: + sage: # needs sage.libs.giac sage: Ex = (1-2*x^(1/3))^(3/4)/x sage: integrate(Ex, x, algorithm='giac') # long time 4*(-2*x^(1/3) + 1)^(3/4) + 6*arctan((-2*x^(1/3) + 1)^(1/4)) - 3*log((-2*x^(1/3) + 1)^(1/4) + 1) + 3*log(abs((-2*x^(1/3) + 1)^(1/4) - 1)) @@ -207,6 +208,7 @@ def __init__(self): Check for :issue:`32354`:: + sage: # needs sage.libs.giac sage: ex = 1/max_symbolic(x, 1)**2 sage: integral(ex, x, 0, 2, algorithm='giac') 3/2 @@ -697,6 +699,7 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): Using Giac to integrate the absolute value of a trigonometric expression:: + sage: # needs sage.libs.giac sage: integrate(abs(cos(x)), x, 0, 2*pi, algorithm='giac') 4 sage: result = integrate(abs(cos(x)), x, 0, 2*pi) From b6d1e71eee8cbadb30d02eedcd3da0c6a7513689 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 5 Oct 2024 19:24:33 -0400 Subject: [PATCH 202/210] src/sage/symbolic/integration/integral.py: fixup a "giac" integral test There's one test in this file for an integral where the "libgiac" algorithm prints a warning, but the old "giac" algorithm did not. Now that algorithm="giac" uses libgiac, we expect the warning in that case too. --- src/sage/symbolic/integration/integral.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sage/symbolic/integration/integral.py b/src/sage/symbolic/integration/integral.py index 98a9266f3a0..5172fa64e90 100644 --- a/src/sage/symbolic/integration/integral.py +++ b/src/sage/symbolic/integration/integral.py @@ -697,10 +697,15 @@ def integrate(expression, v=None, a=None, b=None, algorithm=None, hold=False): sage: integrate(f(x), x, 1, 2, algorithm='sympy') # needs sympy -1/2*pi + arctan(8) + arctan(5) + arctan(2) + arctan(1/2) - Using Giac to integrate the absolute value of a trigonometric expression:: + Using Giac to integrate the absolute value of a trigonometric + expression. If Giac is installed, this will be attempted + automatically in the event that Maxima is unable to integrate the + expression:: sage: # needs sage.libs.giac - sage: integrate(abs(cos(x)), x, 0, 2*pi, algorithm='giac') + sage: result = integrate(abs(cos(x)), x, 0, 2*pi, algorithm='giac') + ... + sage: result 4 sage: result = integrate(abs(cos(x)), x, 0, 2*pi) ... From ff180f2199800f52760bc3e803d895112e9c3bc0 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 5 Oct 2024 19:33:03 -0400 Subject: [PATCH 203/210] src/sage/symbolic/integration/integral.py: update expected giac output One "giac" integral in this file has changed its output slightly now that the "giac" algorithm uses libgiac as opposed to the pexpect interface. The difference between the new and old expected outputs full_simplify() to zero, so this one is nothing to worry about. --- src/sage/symbolic/integration/integral.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/symbolic/integration/integral.py b/src/sage/symbolic/integration/integral.py index 5172fa64e90..aebf84e8e03 100644 --- a/src/sage/symbolic/integration/integral.py +++ b/src/sage/symbolic/integration/integral.py @@ -62,7 +62,7 @@ def __init__(self): sage: # needs sage.libs.giac sage: Ex = (1-2*x^(1/3))^(3/4)/x sage: integrate(Ex, x, algorithm='giac') # long time - 4*(-2*x^(1/3) + 1)^(3/4) + 6*arctan((-2*x^(1/3) + 1)^(1/4)) - 3*log((-2*x^(1/3) + 1)^(1/4) + 1) + 3*log(abs((-2*x^(1/3) + 1)^(1/4) - 1)) + 4*(-2*x^(1/3) + 1)^(3/4) + 6*arctan((-2*x^(1/3) + 1)^(1/4)) - 3*log(abs((-2*x^(1/3) + 1)^(1/4) + 1)) + 3*log(abs((-2*x^(1/3) + 1)^(1/4) - 1)) Check for :issue:`29833`:: From 56d5c3a78bbad9650ae2aaace8ecb8c835563fb2 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 6 Oct 2024 07:37:03 -0400 Subject: [PATCH 204/210] src/sage/symbolic/integration/external.py: update a doctest With the recent improvement to the handling of signed infinities in libgiac, this warning about singular points has vanished. --- src/sage/symbolic/integration/external.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/symbolic/integration/external.py b/src/sage/symbolic/integration/external.py index ef05676c727..083858658d4 100644 --- a/src/sage/symbolic/integration/external.py +++ b/src/sage/symbolic/integration/external.py @@ -227,7 +227,6 @@ def libgiac_integrator(expression, v, a=None, b=None): sage: libgiac_integrator(sin(x), x) -cos(x) sage: libgiac_integrator(1/(x^2+6), x, -oo, oo) - No checks were made for singular points of antiderivative... 1/6*sqrt(6)*pi TESTS:: From f384ef578fa4992f720066faa1315eab42ee9c95 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 12 Nov 2024 21:02:15 -0500 Subject: [PATCH 205/210] src/sage/symbolic/integration/external.py: update a comment A comment in this file about failing doctests is still partially true (the doctests fail if you remove the workaround), but it mentions a "fixme" that does not exist. We delete the nonsense part. --- src/sage/symbolic/integration/external.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/symbolic/integration/external.py b/src/sage/symbolic/integration/external.py index 083858658d4..1390c524300 100644 --- a/src/sage/symbolic/integration/external.py +++ b/src/sage/symbolic/integration/external.py @@ -256,10 +256,9 @@ def libgiac_integrator(expression, v, a=None, b=None): return expression.integrate(v, a, b, hold=True) from sage.libs.giac.giac import Pygen - # We call Pygen on first argument because otherwise some expressions - # involving derivatives result in doctest failures in interfaces/sympy.py - # -- related to the fixme note in sage.libs.giac.giac.GiacFunction.__call__ - # regarding conversion of lists. + # We call Pygen on first argument because otherwise some + # expressions involving derivatives result in doctest failures in + # sage/interfaces/sympy.py if a is None: result = libgiac.integrate(Pygen(expression), v) else: From 09572b108b0216703d7a77055ad629383bd8d37b Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 12 Nov 2024 21:04:31 -0500 Subject: [PATCH 206/210] src/sage/symbolic/integration/integral.py: fix giac integral output Now that libgiac is being used for "giac" integrals, one test is printing out "No checks were made for singular points of antiderivative -1/sageVARx for definite integration in [1,+infinity]" where previously the test was silent. We now "..." the junk away. --- src/sage/symbolic/integration/integral.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/symbolic/integration/integral.py b/src/sage/symbolic/integration/integral.py index aebf84e8e03..4a70d373516 100644 --- a/src/sage/symbolic/integration/integral.py +++ b/src/sage/symbolic/integration/integral.py @@ -212,7 +212,9 @@ def __init__(self): sage: ex = 1/max_symbolic(x, 1)**2 sage: integral(ex, x, 0, 2, algorithm='giac') 3/2 - sage: integral(1/max_symbolic(x, 1)**2, x, 0, oo, algorithm='giac') + sage: result = integral(1/max_symbolic(x, 1)**2, x, 0, oo, algorithm='giac') + ... + sage: result 2 """ # The automatic evaluation routine will try these integrators From cfb2b15c0b8d8e52e89f01071132612adea5d4cb Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 5 Dec 2024 17:11:41 +0900 Subject: [PATCH 207/210] Remove doc.zip --- .github/workflows/doc-build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 8ab585606d1..f46317ecda7 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -154,6 +154,7 @@ jobs: git config --global user.email "ci-sage@example.com" git config --global user.name "Build documentation workflow" unzip doc.zip + rm doc.zip PR_NUMBER="" if [[ "$GITHUB_REF" =~ refs/pull/([0-9]+)/merge ]]; then PR_NUMBER="${BASH_REMATCH[1]}" From 5875eaf16f042b843564b104459e27ac0437bc3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 6 Dec 2024 21:14:17 +0100 Subject: [PATCH 208/210] linting : some fixes for pyx files in modular --- src/sage/modular/arithgroup/congroup.pyx | 16 +++--- src/sage/modular/arithgroup/farey_symbol.pyx | 32 +++++------ src/sage/modular/modsym/heilbronn.pyx | 44 +++++++-------- src/sage/modular/modsym/manin_symbol.pyx | 5 +- src/sage/modular/modsym/p1list.pxd | 8 +-- src/sage/modular/modsym/p1list.pyx | 57 ++++++++++---------- src/sage/modular/pollack_stevens/dist.pyx | 28 +++++----- 7 files changed, 95 insertions(+), 95 deletions(-) diff --git a/src/sage/modular/arithgroup/congroup.pyx b/src/sage/modular/arithgroup/congroup.pyx index d55c0c0ce7c..4972b39f435 100644 --- a/src/sage/modular/arithgroup/congroup.pyx +++ b/src/sage/modular/arithgroup/congroup.pyx @@ -31,7 +31,7 @@ from sage.rings.integer_ring import ZZ Mat2Z = MatrixSpace(ZZ, 2) cdef Matrix_integer_dense genS, genT, genI -genS = Matrix_integer_dense(Mat2Z, [0,-1, 1, 0], True, True) +genS = Matrix_integer_dense(Mat2Z, [0, -1, 1, 0], True, True) genT = Matrix_integer_dense(Mat2Z, [1, 1, 0, 1], True, True) genI = Matrix_integer_dense(Mat2Z, [1, 0, 0, 1], True, True) @@ -123,7 +123,7 @@ def degeneracy_coset_representatives_gamma0(int N, int M, int t): # try to find another coset representative. cc = M*random.randrange(-halfmax, halfmax+1) dd = random.randrange(-halfmax, halfmax+1) - g = arith_int.c_xgcd_int(-cc,dd,&bb,&aa) + g = arith_int.c_xgcd_int(-cc, dd, &bb, &aa) if g == 0: continue cc = cc // g @@ -297,22 +297,24 @@ def generators_helper(coset_reps, level): [21 5], [ 7 -1], [-7 1] ] """ - cdef Matrix_integer_dense x,y,z,v,vSmod,vTmod + cdef Matrix_integer_dense x, y, z, v, vSmod, vTmod crs = coset_reps.list() try: - reps = [Matrix_integer_dense(Mat2Z,lift_to_sl2z(c, d, level),False,True) for c,d in crs] + reps = [Matrix_integer_dense(Mat2Z, lift_to_sl2z(c, d, level), + False, True) for c, d in crs] except Exception: raise ArithmeticError("Error lifting to SL2Z: level=%s crs=%s" % (level, crs)) ans = [] cdef Py_ssize_t i for i in range(len(crs)): x = reps[i] - v = Matrix_integer_dense(Mat2Z,[crs[i][0],crs[i][1],0,0],False,True) + v = Matrix_integer_dense(Mat2Z, [crs[i][0], crs[i][1], 0, 0], + False, True) vSmod = (v*genS) vTmod = (v*genT) - y_index = coset_reps.normalize(vSmod[0,0],vSmod[0,1]) - z_index = coset_reps.normalize(vTmod[0,0],vTmod[0,1]) + y_index = coset_reps.normalize(vSmod[0, 0], vSmod[0, 1]) + z_index = coset_reps.normalize(vTmod[0, 0], vTmod[0, 1]) y_index = crs.index(y_index) z_index = crs.index(z_index) y = reps[y_index] diff --git a/src/sage/modular/arithgroup/farey_symbol.pyx b/src/sage/modular/arithgroup/farey_symbol.pyx index c965015b41d..af81a0f61fc 100644 --- a/src/sage/modular/arithgroup/farey_symbol.pyx +++ b/src/sage/modular/arithgroup/farey_symbol.pyx @@ -13,15 +13,15 @@ based on the *KFarey* package by Chris Kurth. Implemented as C++ module for speed. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011 Hartmut Monien # # 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 cpython.object cimport PyObject_RichCompare from itertools import groupby @@ -206,11 +206,11 @@ cdef class Farey: self.this_ptr = new cpp_farey(data) sig_off() return - ## to accelerate the calculation of the FareySymbol - ## we implement the tests for the standard congruence groups - ## in the c++ module. For a general group the test if an element - ## of SL2Z is in the group the python __contains__ attribute - ## of the group is called + # to accelerate the calculation of the FareySymbol + # we implement the tests for the standard congruence groups + # in the c++ module. For a general group the test if an element + # of SL2Z is in the group the python __contains__ attribute + # of the group is called cdef int p if hasattr(group, "level"): p = group.level() @@ -285,19 +285,19 @@ cdef class Farey: a, b, c, d = pm.matrix().list() newval = gens_dict.get(SL2Z([a, b, c, d])) if newval is not None: - ans.append((newval,1)) + ans.append((newval, 1)) continue newval = gens_dict.get(SL2Z([-a, -b, -c, -d])) if newval is not None: - ans.append((newval,-1)) + ans.append((newval, -1)) continue newval = gens_dict.get(SL2Z([d, -b, -c, a])) if newval is not None: - ans.append((-newval,1)) + ans.append((-newval, 1)) continue newval = gens_dict.get(SL2Z([-d, b, c, -a])) if newval is not None: - ans.append((-newval,-1)) + ans.append((-newval, -1)) continue raise RuntimeError("This should have not happened") return ans @@ -453,7 +453,7 @@ cdef class Farey: result = self.this_ptr.word_problem(a.value, b.value, c.value, d.value, cpp_beta) sig_off() beta = convert_to_SL2Z(cpp_beta[0])**-1 - mbeta = SL2Z([-beta.a(),-beta.b(),-beta.c(),-beta.d()]) + mbeta = SL2Z([-beta.a(), -beta.b(), -beta.c(), -beta.d()]) V = self.pairing_matrices_to_tietze_index() sgn = 1 tietze = [] @@ -500,7 +500,7 @@ cdef class Farey: tietze.reverse() gens = self.generators() if check: - tmp = SL2Z([1,0,0,1]) + tmp = SL2Z([1, 0, 0, 1]) for i in range(len(tietze)): t = tietze[i] tmp = tmp * gens[t-1] if t > 0 else tmp * gens[-t-1]**-1 @@ -1009,7 +1009,7 @@ cdef class Farey: fill=options['fill'], linestyle=options['linestyle'], thickness=options['thickness']) - ## show pairings + # show pairings p = self.pairings() x = self.fractions() if options['show_pairing']: @@ -1033,7 +1033,7 @@ cdef class Farey: return g -#--- conversions ------------------------------------------------------------ +# ----- conversions --------------------------------- cdef public long convert_to_long(n) noexcept: cdef long m = n diff --git a/src/sage/modular/modsym/heilbronn.pyx b/src/sage/modular/modsym/heilbronn.pyx index 82adf9efa20..598e8ccfff9 100644 --- a/src/sage/modular/modsym/heilbronn.pyx +++ b/src/sage/modular/modsym/heilbronn.pyx @@ -202,8 +202,8 @@ cdef class Heilbronn: b[i] = (u * self.list.v[4*i+1]) % N + (v * self.list.v[4*i+3]) % N else: for i in range(self.length): - a[i] = llong_prod_mod(u,self.list.v[4*i],N) + llong_prod_mod(v,self.list.v[4*i+2], N) - b[i] = llong_prod_mod(u,self.list.v[4*i+1],N) + llong_prod_mod(v,self.list.v[4*i+3], N) + a[i] = llong_prod_mod(u, self.list.v[4*i], N) + llong_prod_mod(v, self.list.v[4*i+2], N) + b[i] = llong_prod_mod(u, self.list.v[4*i+1], N) + llong_prod_mod(v, self.list.v[4*i+3], N) sig_off() cdef apply_to_polypart(self, fmpz_poly_t* ans, int i, int k): @@ -283,8 +283,8 @@ cdef class Heilbronn: else: for i in range(self.length): sig_check() - a = llong_prod_mod(u,self.list.v[4*i],N) + llong_prod_mod(v,self.list.v[4*i+2], N) - b = llong_prod_mod(u,self.list.v[4*i+1],N) + llong_prod_mod(v,self.list.v[4*i+3], N) + a = llong_prod_mod(u, self.list.v[4*i], N) + llong_prod_mod(v, self.list.v[4*i+2], N) + b = llong_prod_mod(u, self.list.v[4*i+1], N) + llong_prod_mod(v, self.list.v[4*i+3], N) export.c_p1_normalize_llong(N, a, b, &c, &d, &s, 0) X = (c, d) if X in M: @@ -368,15 +368,15 @@ cdef class HeilbronnCremona(Heilbronn): L = &self.list p = self.p - list_append4(L, 1,0,0,p) + list_append4(L, 1, 0, 0, p) # When p==2, then Heilbronn matrices are # [[1,0,0,2], [2,0,0,1], [2,1,0,1], [1,0,1,2]] # which are not given by the algorithm below. if p == 2: - list_append4(L, 2,0,0,1) - list_append4(L, 2,1,0,1) - list_append4(L, 1,0,1,2) + list_append4(L, 2, 0, 0, 1) + list_append4(L, 2, 1, 0, 1) + list_append4(L, 1, 0, 1, 2) self.length = 4 return @@ -489,20 +489,20 @@ cdef class HeilbronnMerel(Heilbronn): sig_on() for a in range(1, n+1): - ## We have ad-bc=n so c=0 and ad=n, or b=(ad-n)/c - ## Must have ad - n >= 0, so d must be >= Ceiling(n/a). + # We have ad-bc=n so c=0 and ad=n, or b=(ad-n)/c + # Must have ad - n >= 0, so d must be >= Ceiling(n/a). q = n // a if q*a == n: d = q for b in range(a): - list_append4(L, a,b,0,d) + list_append4(L, a, b, 0, d) for c in range(1, d): - list_append4(L, a,0,c,d) + list_append4(L, a, 0, c, d) for d in range(q+1, n+1): bc = (a) * (d) - (n) - ## Divisor c of bc must satisfy Floor(bc/c) lt a and c lt d. - ## c ge (bc div a + 1) <=> Floor(bc/c) lt a (for integers) - ## c le d - 1 <=> c lt d + # Divisor c of bc must satisfy Floor(bc/c) lt a and c lt d. + # c ge (bc div a + 1) <=> Floor(bc/c) lt a (for integers) + # c le d - 1 <=> c lt d for c in range(bc // a + 1, d): if bc % c == 0: list_append4(L, a, bc // c, c, d) @@ -569,7 +569,7 @@ def hecke_images_gamma0_weight2(int u, int v, int N, indices, R): cdef Heilbronn H t = verbose("computing non-reduced images of symbol under Hecke operators", - level=1, caller_name='hecke_images_gamma0_weight2') + level=1, caller_name='hecke_images_gamma0_weight2') for i, n in enumerate(indices): # List the Heilbronn matrices of determinant n defined by Cremona or Merel H = HeilbronnCremona(n) if is_prime(n) else HeilbronnMerel(n) @@ -601,25 +601,25 @@ def hecke_images_gamma0_weight2(int u, int v, int N, indices, R): sig_free(b) t = verbose("finished computing non-reduced images", - t, level=1, caller_name='hecke_images_gamma0_weight2') + t, level=1, caller_name='hecke_images_gamma0_weight2') t = verbose("Now reducing images of symbol", - level=1, caller_name='hecke_images_gamma0_weight2') + level=1, caller_name='hecke_images_gamma0_weight2') # Return the product T * R, whose rows are the image of (u,v) under # the Hecke operators T_n for n in indices. if max(indices) <= 30: # In this case T tends to be very sparse ans = T.sparse_matrix()._matrix_times_matrix_dense(R) verbose("did reduction using sparse multiplication", - t, level=1, caller_name='hecke_images_gamma0_weight2') + t, level=1, caller_name='hecke_images_gamma0_weight2') elif R.is_sparse(): ans = T * R.dense_matrix() verbose("did reduction using dense multiplication", - t, level=1, caller_name='hecke_images_gamma0_weight2') + t, level=1, caller_name='hecke_images_gamma0_weight2') else: ans = T * R verbose("did reduction using dense multiplication", - t, level=1, caller_name='hecke_images_gamma0_weight2') + t, level=1, caller_name='hecke_images_gamma0_weight2') if original_base_ring != QQ: ans = ans.change_ring(original_base_ring) @@ -700,7 +700,7 @@ def hecke_images_nonquad_character_weight2(int u, int v, int N, indices, chi, R) cdef Heilbronn H t = verbose("computing non-reduced images of symbol under Hecke operators", - level=1, caller_name='hecke_images_character_weight2') + level=1, caller_name='hecke_images_character_weight2') # Make a matrix over the rational numbers each of whose columns # are the values of the character chi. diff --git a/src/sage/modular/modsym/manin_symbol.pyx b/src/sage/modular/modsym/manin_symbol.pyx index 726f78c55a6..0a7feaffb5b 100644 --- a/src/sage/modular/modsym/manin_symbol.pyx +++ b/src/sage/modular/modsym/manin_symbol.pyx @@ -401,7 +401,7 @@ cdef class ManinSymbol(Element): N=int(N) if N < 1: raise ArithmeticError("N must be positive") - a,b,c,d = self.lift_to_sl2z() + a, b, c, d = self.lift_to_sl2z() return Cusp(b, d), Cusp(a, c) def weight(self): @@ -453,8 +453,7 @@ cdef class ManinSymbol(Element): # TODO: It would likely be much better to do this slightly more directly from sage.modular.modsym.modular_symbols import ModularSymbol x = ModularSymbol(self.parent(), self.i, 0, Infinity) - a,b,c,d = self.lift_to_sl2z() - return x.apply([a,b,c,d]) + return x.apply(self.lift_to_sl2z()) def _print_polypart(i, j): diff --git a/src/sage/modular/modsym/p1list.pxd b/src/sage/modular/modsym/p1list.pxd index b66f28b8ad6..b559922411c 100644 --- a/src/sage/modular/modsym/p1list.pxd +++ b/src/sage/modular/modsym/p1list.pxd @@ -6,8 +6,8 @@ cdef class export: int compute_s) except -1 cdef int c_p1_normalize_llong(self, int N, int u, int v, - int* uu, int* vv, int* ss, - int compute_s) except -1 + int* uu, int* vv, int* ss, + int compute_s) except -1 cdef class P1List: @@ -22,7 +22,7 @@ cdef class P1List: # for normalizing an element does not need to be used # every time the user calls the normalize function. cdef int (*_normalize)(int N, int u, int v, - int* uu, int* vv, int* ss, - int compute_s) except -1 + int* uu, int* vv, int* ss, + int compute_s) except -1 cpdef index(self, int u, int v) cdef index_and_scalar(self, int u, int v, int* i, int* s) diff --git a/src/sage/modular/modsym/p1list.pyx b/src/sage/modular/modsym/p1list.pyx index 7ceda12d5c8..f7d5f4b209b 100644 --- a/src/sage/modular/modsym/p1list.pyx +++ b/src/sage/modular/modsym/p1list.pyx @@ -75,7 +75,7 @@ cdef int c_p1_normalize_int(int N, int u, int v, v += N if u == 0: uu[0] = 0 - if arith_int.c_gcd_int(v,N) == 1: + if arith_int.c_gcd_int(v, N) == 1: vv[0] = 1 else: vv[0] = 0 @@ -96,7 +96,7 @@ cdef int c_p1_normalize_int(int N, int u, int v, # Adjust s modulo N/g so it is coprime to N. if g != 1: d = N // g - while arith_int.c_gcd_int(s,N) != 1: + while arith_int.c_gcd_int(s, N) != 1: s = (s+d) % N # Multiply [u,v] by s; then [s*u,s*v] = [g,s*v] (mod N) @@ -112,7 +112,7 @@ cdef int c_p1_normalize_int(int N, int u, int v, for k in range(2, g + 1): v = (v + vNg) % N t = (t + Ng) % N - if v N - #if N<=0 or N >= 2**31: - # raise OverflowError("Modulus is too large (must be < 46340)") - # return -1 + # if N <= 0 or N >= 2**31: + # raise OverflowError("Modulus is too large (must be < 46340)") + # return -1 u = u % N v = v % N @@ -333,14 +333,14 @@ cdef int c_p1_normalize_llong(int N, int u, int v, v += N if u == 0: uu[0] = 0 - if arith_int.c_gcd_int(v,N) == 1: + if arith_int.c_gcd_int(v, N) == 1: vv[0] = 1 else: vv[0] = 0 ss[0] = v return 0 - #g = xgcd_int_llong(u, N, &s, &t) + # g = xgcd_int_llong(u, N, &s, &t) g = arith_llong.c_xgcd_longlong(u, N, &ll_s, &ll_t) s = (ll_s % ll_N) t = (ll_t % ll_N) @@ -357,7 +357,7 @@ cdef int c_p1_normalize_llong(int N, int u, int v, # Adjust s modulo N/g so it is coprime to N. if g != 1: d = N // g - while arith_int.c_gcd_int(s,N) != 1: + while arith_int.c_gcd_int(s, N) != 1: s = (s+d) % N # Multiply [u,v] by s; then [s*u,s*v] = [g,s*v] (mod N) @@ -466,7 +466,7 @@ def p1list_llong(int N): if N == 1: return [(0, 0)] - lst = [(0,1)] + lst = [(0, 1)] c = 1 for d in range(N): lst.append((c, d)) @@ -720,7 +720,7 @@ cdef class P1List(): else: raise OverflowError("p1list not defined for such large N.") self.__list.sort() - self.__end_hash = dict([(x,i) for i, x in enumerate(self.__list[N+1:])]) + self.__end_hash = {x: i for i, x in enumerate(self.__list[N+1:])} # Allocate memory for xgcd table. self.g = NULL @@ -870,7 +870,7 @@ cdef class P1List(): cdef int c, d, N if self.__N == 1: - return [1,0,0,1] + return [1, 0, 0, 1] c, d = self.__list[i] N = self.__N @@ -909,9 +909,9 @@ cdef class P1List(): True """ cdef int u, v, uu, vv, ss - u,v = self.__list[i] + u, v = self.__list[i] self._normalize(self.__N, -u, v, &uu, &vv, &ss, 0) - _, j = search(self.__list, (uu,vv)) + _, j = search(self.__list, (uu, vv)) return j def apply_S(self, int i): @@ -941,9 +941,9 @@ cdef class P1List(): True """ cdef int u, v, uu, vv, ss - u,v = self.__list[i] + u, v = self.__list[i] self._normalize(self.__N, -v, u, &uu, &vv, &ss, 0) - _, j = search(self.__list, (uu,vv)) + _, j = search(self.__list, (uu, vv)) return j def apply_T(self, int i): @@ -973,9 +973,9 @@ cdef class P1List(): True """ cdef int u, v, uu, vv, ss - u,v = self.__list[i] + u, v = self.__list[i] self._normalize(self.__N, v, -u-v, &uu, &vv, &ss, 0) - _, j = search(self.__list, (uu,vv)) + _, j = search(self.__list, (uu, vv)) return j cpdef index(self, int u, int v): @@ -1014,7 +1014,7 @@ cdef class P1List(): return -1 return 0 try: - return self.__end_hash[(uu,vv)] + self.__N + 1 + return self.__end_hash[(uu, vv)] + self.__N + 1 except KeyError: return -1 @@ -1053,7 +1053,7 @@ cdef class P1List(): i[0] = 0 return try: - i[0] = self.__end_hash[(uu,vv)] + self.__N + 1 + i[0] = self.__end_hash[(uu, vv)] + self.__N + 1 return except KeyError: i[0] = -1 @@ -1084,7 +1084,7 @@ cdef class P1List(): sage: all(L.index_of_normalized_pair(L[i][0],L[i][1])==i for i in range(len(L))) True """ - t, i = search(self.__list, (u,v)) + t, i = search(self.__list, (u, v)) if t: return i return -1 @@ -1129,7 +1129,7 @@ cdef class P1List(): """ cdef int uu, vv, ss self._normalize(self.__N, u, v, &uu, &vv, &ss, 0) - return (uu,vv) + return (uu, vv) def normalize_with_scalar(self, int u, int v): r""" @@ -1365,11 +1365,10 @@ def lift_to_sl2z(c, d, N): [1, 0, 0, 1] """ if N <= 46340: - return lift_to_sl2z_int(c,d,N) - elif N <= 2147483647: - return lift_to_sl2z_llong(c,d,N) - else: - raise NotImplementedError("N too large") + return lift_to_sl2z_int(c, d, N) + if N <= 2147483647: + return lift_to_sl2z_llong(c, d, N) + raise NotImplementedError("N too large") def _make_p1list(n): diff --git a/src/sage/modular/pollack_stevens/dist.pyx b/src/sage/modular/pollack_stevens/dist.pyx index 85cccd3bb11..9ed53a955c9 100644 --- a/src/sage/modular/pollack_stevens/dist.pyx +++ b/src/sage/modular/pollack_stevens/dist.pyx @@ -43,7 +43,7 @@ from sage.rings.rational_field import QQ from sage.structure.element cimport Element from sage.structure.richcmp cimport richcmp_not_equal, rich_to_bool -#from sage.libs.flint.ulong_extras cimport * +# from sage.libs.flint.ulong_extras cimport * cdef long overflow = 1 << (4 * sizeof(long) - 1) cdef long underflow = -overflow @@ -360,8 +360,8 @@ cdef class Dist(ModuleElement): raise ValueError("self is zero") v = a.valuation(p) relprec = n - i - v -# verbose("p=%s, n-i=%s\nself.moment=%s, other.moment=%s" % (p, n-i, a, other._unscaled_moment(i)),level=2) -## RP: This code was crashing because other may have too few moments -- so I added this bound with other's relative precision + # verbose("p=%s, n-i=%s\nself.moment=%s, other.moment=%s" % (p, n-i, a, other._unscaled_moment(i)),level=2) + # RP: This code was crashing because other may have too few moments -- so I added this bound with other's relative precision if padic: if i < other_pr: alpha = (other._unscaled_moment(i) / a).add_bigoh(n - i) @@ -373,7 +373,7 @@ cdef class Dist(ModuleElement): else: alpha = 0 verbose("alpha = %s" % alpha, level = 2) -## RP: This code was crashing because other may have too few moments -- so I added this bound with other's relative precision + # RP: This code was crashing because other may have too few moments -- so I added this bound with other's relative precision while i < other_pr - 1: i += 1 verbose("comparing p moment %s" % i, level = 2) @@ -656,11 +656,11 @@ cdef class Dist(ModuleElement): zero = R(0) moments.extend([zero] * (M - k - 1)) mu = V(moments) - #val = mu.valuation() - #if val < 0: - # # This seems unnatural - # print("scaling by ", p, "^", -val, " to keep things integral") - # mu *= p**(-val) + # val = mu.valuation() + # if val < 0: + # # This seems unnatural + # print("scaling by ", p, "^", -val, " to keep things integral") + # mu *= p**(-val) return mu def _is_malformed(self): @@ -1129,7 +1129,7 @@ cdef class Dist_vector(Dist): """ # assert self._moments[0][0]==0, "not total measure zero" # print("result accurate modulo p^",self.moment(0).valuation(self.p) ) - #v=[0 for j in range(0,i)]+[binomial(j,i)*bernoulli(j-i) for j in range(i,M)] + # v=[0 for j in range(0,i)]+[binomial(j,i)*bernoulli(j-i) for j in range(i,M)] M = self.precision_relative() R = self.parent().base_ring() K = R.fraction_field() @@ -1361,7 +1361,7 @@ cdef class WeightKAction_vector(WeightKAction): sage: v * D._act.actor()(g) # indirect doctest (-107, 35, -12, 5) """ - #tim = verbose("Starting") + # tim = verbose("Starting") a, b, c, d = self._adjuster(g) # if g.parent().base_ring().is_exact(): # self._check_mat(a, b, c, d) @@ -1378,17 +1378,17 @@ cdef class WeightKAction_vector(WeightKAction): return B.change_ring(self.codomain().base_ring()) R = PowerSeriesRing(base_ring, 'y', default_prec=M) y = R.gen() - #tim = verbose("Checked, made R",tim) + # tim = verbose("Checked, made R",tim) # special case for small precision, large weight scale = (b + d * y) / (a + c * y) t = (a + c * y) ** k # will already have precision M cdef long row, col - #tim = verbose("Made matrix",tim) + # tim = verbose("Made matrix",tim) for col in range(M): for row in range(M): B.set_unsafe(row, col, t[row]) t *= scale - #verbose("Finished loop",tim) + # verbose("Finished loop",tim) # the changering here is annoying, but otherwise we have to # change ring each time we multiply B = B.change_ring(self.codomain().base_ring()) From 99527be48996df8ba111c109fb5a3d19cba59fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 7 Dec 2024 21:21:22 +0100 Subject: [PATCH 209/210] remove final empty lines in pxd/pxi files --- src/sage/coding/binary_code.pxd | 1 - src/sage/combinat/permutation_cython.pxd | 1 - src/sage/combinat/rigged_configurations/rigged_partition.pxd | 1 - src/sage/data_structures/bitset.pxd | 1 - src/sage/groups/group.pxd | 1 - src/sage/groups/old.pxd | 1 - src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd | 1 - src/sage/groups/perm_gps/partn_ref/refinement_matrices.pxd | 1 - src/sage/libs/gmp/mpq.pxd | 1 - src/sage/libs/m4ri.pxd | 1 - src/sage/libs/ntl/ZZ_pX.pxd | 1 - src/sage/libs/ntl/ntl_GF2E.pxd | 1 - src/sage/matrix/matrix_cyclo_dense.pxd | 1 - src/sage/matrix/matrix_modn_dense_template.pxi | 1 - src/sage/modules/free_module_element.pxd | 1 - src/sage/rings/finite_rings/element_base.pxd | 1 - src/sage/rings/finite_rings/stdint.pxd | 1 - src/sage/rings/laurent_series_ring_element.pxd | 1 - src/sage/rings/number_field/number_field_element_quadratic.pxd | 1 - src/sage/rings/number_field/totallyreal_data.pxd | 1 - src/sage/rings/polynomial/polynomial_element.pxd | 1 - src/sage/rings/polynomial/polynomial_gf2x.pxd | 1 - src/sage/rings/polynomial/polynomial_rational_flint.pxd | 1 - src/sage/rings/polynomial/skew_polynomial_finite_order.pxd | 1 - src/sage/rings/power_series_poly.pxd | 1 - src/sage/rings/real_lazy.pxd | 1 - src/sage/rings/ring_extension_conversion.pxd | 2 -- src/sage/rings/ring_extension_element.pxd | 2 -- src/sage/rings/tate_algebra_element.pxd | 1 - src/sage/stats/hmm/hmm.pxd | 1 - src/sage/stats/hmm/util.pxd | 1 - src/sage/structure/element_wrapper.pxd | 1 - 32 files changed, 34 deletions(-) diff --git a/src/sage/coding/binary_code.pxd b/src/sage/coding/binary_code.pxd index 38be220c731..44a793d15df 100644 --- a/src/sage/coding/binary_code.pxd +++ b/src/sage/coding/binary_code.pxd @@ -115,4 +115,3 @@ cdef class BinaryCodeClassifier: cdef void record_automorphism(self, int *, int) noexcept cdef void aut_gp_and_can_label(self, BinaryCode, int) noexcept - diff --git a/src/sage/combinat/permutation_cython.pxd b/src/sage/combinat/permutation_cython.pxd index 094dafc8ddc..3e5afddf40e 100644 --- a/src/sage/combinat/permutation_cython.pxd +++ b/src/sage/combinat/permutation_cython.pxd @@ -8,4 +8,3 @@ cpdef list left_action_same_n(list l, list r) cpdef list right_action_same_n(list l, list r) cpdef list left_action_product(list l, list r) cpdef list right_action_product(list l, list r) - diff --git a/src/sage/combinat/rigged_configurations/rigged_partition.pxd b/src/sage/combinat/rigged_configurations/rigged_partition.pxd index e99258f33b2..031ab548020 100644 --- a/src/sage/combinat/rigged_configurations/rigged_partition.pxd +++ b/src/sage/combinat/rigged_configurations/rigged_partition.pxd @@ -12,4 +12,3 @@ cdef class RiggedPartition(SageObject): cdef class RiggedPartitionTypeB(RiggedPartition): pass - diff --git a/src/sage/data_structures/bitset.pxd b/src/sage/data_structures/bitset.pxd index db627b294cd..a93e26c2ef9 100644 --- a/src/sage/data_structures/bitset.pxd +++ b/src/sage/data_structures/bitset.pxd @@ -37,4 +37,3 @@ cdef class Bitset(FrozenBitset): cpdef discard(self, unsigned long n) cpdef pop(self) cpdef clear(self) - diff --git a/src/sage/groups/group.pxd b/src/sage/groups/group.pxd index 8a38ba4b583..462099d77fd 100644 --- a/src/sage/groups/group.pxd +++ b/src/sage/groups/group.pxd @@ -11,4 +11,3 @@ cdef class FiniteGroup(Group): cdef class AlgebraicGroup(Group): pass - diff --git a/src/sage/groups/old.pxd b/src/sage/groups/old.pxd index 3409c5b1764..b141cd6d1a3 100644 --- a/src/sage/groups/old.pxd +++ b/src/sage/groups/old.pxd @@ -11,4 +11,3 @@ cdef class FiniteGroup(Group): cdef class AlgebraicGroup(Group): pass - diff --git a/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd b/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd index 8996dcaf509..fde91d1d0f6 100644 --- a/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +++ b/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd @@ -82,4 +82,3 @@ cdef iterator *setup_canonical_generator(int degree, iterator *cangen_prealloc) except NULL cdef iterator *start_canonical_generator(StabilizerChain *, void *, int, iterator *) except NULL - diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pxd b/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pxd index 2cf087e9915..6ef14648081 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +++ b/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pxd @@ -28,4 +28,3 @@ cdef class MatrixStruct: cdef int refine_matrix(PartitionStack *, void *, int *, int) noexcept cdef int compare_matrices(int *, int *, void *, void *, int) noexcept cdef bint all_matrix_children_are_equivalent(PartitionStack *, void *) noexcept - diff --git a/src/sage/libs/gmp/mpq.pxd b/src/sage/libs/gmp/mpq.pxd index 068988ffbc4..19d94b32808 100644 --- a/src/sage/libs/gmp/mpq.pxd +++ b/src/sage/libs/gmp/mpq.pxd @@ -55,4 +55,3 @@ cdef extern from "gmp.h": # Input and Output Functions # size_t mpq_out_str (file *stream, int base, mpq_t op) # size_t mpq_inp_str (mpq_t rop, file *stream, int base) - diff --git a/src/sage/libs/m4ri.pxd b/src/sage/libs/m4ri.pxd index 7fbdd35b856..365369b4687 100644 --- a/src/sage/libs/m4ri.pxd +++ b/src/sage/libs/m4ri.pxd @@ -192,4 +192,3 @@ cdef extern from "m4ri/m4ri.h": ################################## cdef void mzd_clear_bits(mzd_t *m, int x, int y, int n) - diff --git a/src/sage/libs/ntl/ZZ_pX.pxd b/src/sage/libs/ntl/ZZ_pX.pxd index 8c9f609f1cd..4c6895581dd 100644 --- a/src/sage/libs/ntl/ZZ_pX.pxd +++ b/src/sage/libs/ntl/ZZ_pX.pxd @@ -119,4 +119,3 @@ cdef extern from "ntlwrap_impl.h": void ZZ_pX_right_pshift(ZZ_pX_c x, ZZ_pX_c a, ZZ_c pn, ZZ_pContext_c c) void ZZ_pX_InvMod_newton_unram(ZZ_pX_c x, ZZ_pX_c a, ZZ_pX_Modulus_c F, ZZ_pContext_c cpn, ZZ_pContext_c cp) void ZZ_pX_InvMod_newton_ram(ZZ_pX_c x, ZZ_pX_c a, ZZ_pX_Modulus_c F, ZZ_pContext_c cpn) - diff --git a/src/sage/libs/ntl/ntl_GF2E.pxd b/src/sage/libs/ntl/ntl_GF2E.pxd index c36292c8748..f12777b16c9 100644 --- a/src/sage/libs/ntl/ntl_GF2E.pxd +++ b/src/sage/libs/ntl/ntl_GF2E.pxd @@ -5,4 +5,3 @@ cdef class ntl_GF2E(): cdef GF2E_c x cdef ntl_GF2EContext_class c cdef ntl_GF2E _new(self) - diff --git a/src/sage/matrix/matrix_cyclo_dense.pxd b/src/sage/matrix/matrix_cyclo_dense.pxd index 13f72389cf5..1c740082681 100644 --- a/src/sage/matrix/matrix_cyclo_dense.pxd +++ b/src/sage/matrix/matrix_cyclo_dense.pxd @@ -13,4 +13,3 @@ cdef class Matrix_cyclo_dense(Matrix_dense): cdef _randomize_rational_column_unsafe(Matrix_cyclo_dense self, Py_ssize_t col, mpz_t nump1, mpz_t denp1, distribution=?) - diff --git a/src/sage/matrix/matrix_modn_dense_template.pxi b/src/sage/matrix/matrix_modn_dense_template.pxi index 177cebffb38..96ea3b69ad8 100644 --- a/src/sage/matrix/matrix_modn_dense_template.pxi +++ b/src/sage/matrix/matrix_modn_dense_template.pxi @@ -3241,4 +3241,3 @@ cdef class Matrix_modn_dense_template(Matrix_dense): [0 1] """ return self._entries[j+i*self._ncols] == 0 - diff --git a/src/sage/modules/free_module_element.pxd b/src/sage/modules/free_module_element.pxd index 084423a2714..25585564228 100644 --- a/src/sage/modules/free_module_element.pxd +++ b/src/sage/modules/free_module_element.pxd @@ -19,4 +19,3 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): # cdef'd methods cdef _new_c(self, object v) - diff --git a/src/sage/rings/finite_rings/element_base.pxd b/src/sage/rings/finite_rings/element_base.pxd index c214e4745a9..2c509e2d5e3 100644 --- a/src/sage/rings/finite_rings/element_base.pxd +++ b/src/sage/rings/finite_rings/element_base.pxd @@ -9,4 +9,3 @@ cdef class FinitePolyExtElement(FiniteRingElement): cdef class Cache_base(SageObject): cpdef FinitePolyExtElement fetch_int(self, number) - diff --git a/src/sage/rings/finite_rings/stdint.pxd b/src/sage/rings/finite_rings/stdint.pxd index b2b96a90c39..4e4cb6522d3 100644 --- a/src/sage/rings/finite_rings/stdint.pxd +++ b/src/sage/rings/finite_rings/stdint.pxd @@ -16,4 +16,3 @@ from libc.stdint cimport int_fast32_t, int_fast64_t cdef extern from "integer_mod_limits.h": int_fast32_t INTEGER_MOD_INT32_LIMIT int_fast64_t INTEGER_MOD_INT64_LIMIT - diff --git a/src/sage/rings/laurent_series_ring_element.pxd b/src/sage/rings/laurent_series_ring_element.pxd index 8df5a92c9e7..3fc8e5dfffd 100644 --- a/src/sage/rings/laurent_series_ring_element.pxd +++ b/src/sage/rings/laurent_series_ring_element.pxd @@ -7,4 +7,3 @@ cdef class LaurentSeries(AlgebraElement): cdef _normalize(self) cpdef _add_(self, other) cpdef _mul_(self, other) - diff --git a/src/sage/rings/number_field/number_field_element_quadratic.pxd b/src/sage/rings/number_field/number_field_element_quadratic.pxd index 6dce9c04d90..7bb9e57a3a2 100644 --- a/src/sage/rings/number_field/number_field_element_quadratic.pxd +++ b/src/sage/rings/number_field/number_field_element_quadratic.pxd @@ -31,4 +31,3 @@ cdef class OrderElement_quadratic(NumberFieldElement_quadratic): pass cpdef bint is_sqrt_disc(Rational ad, Rational bd) noexcept - diff --git a/src/sage/rings/number_field/totallyreal_data.pxd b/src/sage/rings/number_field/totallyreal_data.pxd index 61973829ddb..006189325f9 100644 --- a/src/sage/rings/number_field/totallyreal_data.pxd +++ b/src/sage/rings/number_field/totallyreal_data.pxd @@ -23,4 +23,3 @@ cdef class tr_data: cdef int *df cdef void incr(self, int *f_out, int verbose, int haltk, int phc) noexcept - diff --git a/src/sage/rings/polynomial/polynomial_element.pxd b/src/sage/rings/polynomial/polynomial_element.pxd index a8f2cf3057b..45e64ce6744 100644 --- a/src/sage/rings/polynomial/polynomial_element.pxd +++ b/src/sage/rings/polynomial/polynomial_element.pxd @@ -61,4 +61,3 @@ cpdef Polynomial generic_power_trunc(Polynomial p, Integer n, long prec) cpdef list _dict_to_list(dict x, zero) cpdef bint polynomial_is_variable(x) noexcept - diff --git a/src/sage/rings/polynomial/polynomial_gf2x.pxd b/src/sage/rings/polynomial/polynomial_gf2x.pxd index 293715c0379..3a27019f77c 100644 --- a/src/sage/rings/polynomial/polynomial_gf2x.pxd +++ b/src/sage/rings/polynomial/polynomial_gf2x.pxd @@ -7,4 +7,3 @@ include "polynomial_template_header.pxi" cdef class Polynomial_GF2X(Polynomial_template): pass - diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pxd b/src/sage/rings/polynomial/polynomial_rational_flint.pxd index f4644f19d04..fab8ac5463c 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pxd +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pxd @@ -17,4 +17,3 @@ cdef class Polynomial_rational_flint(Polynomial): cpdef _mod_(self, right) cpdef _unsafe_mutate(self, unsigned long n, value) cpdef Polynomial truncate(self, long n) - diff --git a/src/sage/rings/polynomial/skew_polynomial_finite_order.pxd b/src/sage/rings/polynomial/skew_polynomial_finite_order.pxd index 438773a39ef..4c6a4b638c9 100644 --- a/src/sage/rings/polynomial/skew_polynomial_finite_order.pxd +++ b/src/sage/rings/polynomial/skew_polynomial_finite_order.pxd @@ -7,4 +7,3 @@ cdef class SkewPolynomial_finite_order_dense (SkewPolynomial_generic_dense): cdef _matphir_c(self) cdef _matmul_c(self) - diff --git a/src/sage/rings/power_series_poly.pxd b/src/sage/rings/power_series_poly.pxd index e37e1fb26cf..82539afef3f 100644 --- a/src/sage/rings/power_series_poly.pxd +++ b/src/sage/rings/power_series_poly.pxd @@ -7,4 +7,3 @@ cdef class PowerSeries_poly(PowerSeries): cdef class BaseRingFloorDivAction(Action): pass - diff --git a/src/sage/rings/real_lazy.pxd b/src/sage/rings/real_lazy.pxd index 60a6580a550..c7aa82cd596 100644 --- a/src/sage/rings/real_lazy.pxd +++ b/src/sage/rings/real_lazy.pxd @@ -27,4 +27,3 @@ cdef class LazyUnop(LazyFieldElement): cdef class LazyNamedUnop(LazyUnop): cdef readonly _extra_args - diff --git a/src/sage/rings/ring_extension_conversion.pxd b/src/sage/rings/ring_extension_conversion.pxd index e3815a411ba..5a7c871841e 100644 --- a/src/sage/rings/ring_extension_conversion.pxd +++ b/src/sage/rings/ring_extension_conversion.pxd @@ -13,5 +13,3 @@ cpdef from_backend_morphism(f, RingExtension_generic E) cpdef to_backend(arg) cpdef from_backend(arg, E) - - diff --git a/src/sage/rings/ring_extension_element.pxd b/src/sage/rings/ring_extension_element.pxd index 9bd662f3d0f..ca83f669643 100644 --- a/src/sage/rings/ring_extension_element.pxd +++ b/src/sage/rings/ring_extension_element.pxd @@ -18,5 +18,3 @@ cdef class RingExtensionWithBasisElement(RingExtensionElement): cdef _trace(self, Parent base) cdef _norm(self, Parent base) cpdef minpoly(self, base=*, var=*) - - diff --git a/src/sage/rings/tate_algebra_element.pxd b/src/sage/rings/tate_algebra_element.pxd index 3cafe330fb0..a1566f0e053 100644 --- a/src/sage/rings/tate_algebra_element.pxd +++ b/src/sage/rings/tate_algebra_element.pxd @@ -46,4 +46,3 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): cdef _quo_rem_c(self, list divisors, bint quo, bint rem, bint integral) cdef _quo_rem_check(self, divisors, bint quo, bint rem) cdef TateAlgebraElement _Spoly_c(self, TateAlgebraElement other) - diff --git a/src/sage/stats/hmm/hmm.pxd b/src/sage/stats/hmm/hmm.pxd index 1abcb95392b..e1a2fa8590e 100644 --- a/src/sage/stats/hmm/hmm.pxd +++ b/src/sage/stats/hmm/hmm.pxd @@ -14,4 +14,3 @@ cdef class HiddenMarkovModel: cdef TimeSeries A, pi cdef TimeSeries _baum_welch_gamma(self, TimeSeries alpha, TimeSeries beta) - diff --git a/src/sage/stats/hmm/util.pxd b/src/sage/stats/hmm/util.pxd index b0d399d9aaf..4be9fbd77d5 100644 --- a/src/sage/stats/hmm/util.pxd +++ b/src/sage/stats/hmm/util.pxd @@ -4,4 +4,3 @@ cdef class HMM_Util: cpdef normalize_probability_TimeSeries(self, TimeSeries T, Py_ssize_t i, Py_ssize_t j) cpdef TimeSeries initial_probs_to_TimeSeries(self, pi, bint normalize) cpdef TimeSeries state_matrix_to_TimeSeries(self, A, int N, bint normalize) - diff --git a/src/sage/structure/element_wrapper.pxd b/src/sage/structure/element_wrapper.pxd index dda6630c84d..158d5687a8a 100644 --- a/src/sage/structure/element_wrapper.pxd +++ b/src/sage/structure/element_wrapper.pxd @@ -10,4 +10,3 @@ cdef class ElementWrapper(Element): cdef class ElementWrapperCheckWrappedClass(ElementWrapper): pass - From f48da11b6dcffbc328d4b0cd2ebc25995c7e86ca Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sun, 8 Dec 2024 23:37:27 +0100 Subject: [PATCH 210/210] Updated SageMath version to 10.6.beta0 --- .upstream.d/20-github.com-sagemath-sage-releases | 2 +- CITATION.cff | 4 ++-- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 4 ++-- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/version_requirements.txt | 2 +- build/pkgs/sage_docbuild/version_requirements.txt | 2 +- build/pkgs/sage_setup/version_requirements.txt | 2 +- build/pkgs/sage_sws2rst/version_requirements.txt | 2 +- build/pkgs/sagelib/version_requirements.txt | 2 +- build/pkgs/sagemath_bliss/version_requirements.txt | 2 +- build/pkgs/sagemath_categories/version_requirements.txt | 2 +- build/pkgs/sagemath_coxeter3/version_requirements.txt | 2 +- build/pkgs/sagemath_environment/version_requirements.txt | 2 +- build/pkgs/sagemath_mcqd/version_requirements.txt | 2 +- build/pkgs/sagemath_meataxe/version_requirements.txt | 2 +- build/pkgs/sagemath_objects/version_requirements.txt | 2 +- build/pkgs/sagemath_repl/version_requirements.txt | 2 +- build/pkgs/sagemath_sirocco/version_requirements.txt | 2 +- build/pkgs/sagemath_tdlib/version_requirements.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 39 files changed, 45 insertions(+), 45 deletions(-) diff --git a/.upstream.d/20-github.com-sagemath-sage-releases b/.upstream.d/20-github.com-sagemath-sage-releases index 399ee84dbd6..ed442b3039e 100644 --- a/.upstream.d/20-github.com-sagemath-sage-releases +++ b/.upstream.d/20-github.com-sagemath-sage-releases @@ -1,5 +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.6/ https://github.com/sagemath/sage/releases/download/10.5/ https://github.com/sagemath/sage/releases/download/10.4/ -https://github.com/sagemath/sage/releases/download/10.3/ diff --git a/CITATION.cff b/CITATION.cff index 16ab592bb9a..b3774971e4a 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.5 +version: 10.6.beta0 doi: 10.5281/zenodo.8042260 -date-released: 2024-12-04 +date-released: 2024-12-08 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index e057a4fa381..75a4802e431 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.5, Release Date: 2024-12-04 +SageMath version 10.6.beta0, Release Date: 2024-12-08 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index b00f9149798..af25b3b9917 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,3 +1,3 @@ tarball=configure-VERSION.tar.gz -sha1=2ddf97fb44945c5e863332a2e9494438fff85b4d -sha256=6c6f918459bb21c82fb015722ed46bd2f43a4fb3ab60f38666e3332a7eebf33b +sha1=ca942ace2e5104f3ae9e57946c8228b0bdb580c5 +sha256=99c0a76943170a85d2eb868d72dd673c6b0df529d99b808458bdb3b285dec8fe diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index eca7b3769be..036f9ad2756 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -d305e8b32fe1977ea75b3a58198aa0d3dd60e2f9 +d129e08e85a0c6530fa140dfc04c86ac0b74e05e diff --git a/build/pkgs/sage_conf/version_requirements.txt b/build/pkgs/sage_conf/version_requirements.txt index a979e585a50..1528604151d 100644 --- a/build/pkgs/sage_conf/version_requirements.txt +++ b/build/pkgs/sage_conf/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.5 +sage-conf ~= 10.6b0 diff --git a/build/pkgs/sage_docbuild/version_requirements.txt b/build/pkgs/sage_docbuild/version_requirements.txt index e1fac619a47..64078134018 100644 --- a/build/pkgs/sage_docbuild/version_requirements.txt +++ b/build/pkgs/sage_docbuild/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.5 +sage-docbuild ~= 10.6b0 diff --git a/build/pkgs/sage_setup/version_requirements.txt b/build/pkgs/sage_setup/version_requirements.txt index 7eac3993c51..e5b0998d572 100644 --- a/build/pkgs/sage_setup/version_requirements.txt +++ b/build/pkgs/sage_setup/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.5 +sage-setup ~= 10.6b0 diff --git a/build/pkgs/sage_sws2rst/version_requirements.txt b/build/pkgs/sage_sws2rst/version_requirements.txt index 3116bf7335f..1aec16d1739 100644 --- a/build/pkgs/sage_sws2rst/version_requirements.txt +++ b/build/pkgs/sage_sws2rst/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.5 +sage-sws2rst ~= 10.6b0 diff --git a/build/pkgs/sagelib/version_requirements.txt b/build/pkgs/sagelib/version_requirements.txt index d3ff4cfaa4e..a01ffdf92ed 100644 --- a/build/pkgs/sagelib/version_requirements.txt +++ b/build/pkgs/sagelib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-standard ~= 10.5 +sagemath-standard ~= 10.6b0 diff --git a/build/pkgs/sagemath_bliss/version_requirements.txt b/build/pkgs/sagemath_bliss/version_requirements.txt index 168679d2732..637c4611451 100644 --- a/build/pkgs/sagemath_bliss/version_requirements.txt +++ b/build/pkgs/sagemath_bliss/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.5 +sagemath-bliss ~= 10.6b0 diff --git a/build/pkgs/sagemath_categories/version_requirements.txt b/build/pkgs/sagemath_categories/version_requirements.txt index ce0889bf57b..8e37771c3f9 100644 --- a/build/pkgs/sagemath_categories/version_requirements.txt +++ b/build/pkgs/sagemath_categories/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.5 +sagemath-categories ~= 10.6b0 diff --git a/build/pkgs/sagemath_coxeter3/version_requirements.txt b/build/pkgs/sagemath_coxeter3/version_requirements.txt index 3cb8ea71df9..06dc600cfd7 100644 --- a/build/pkgs/sagemath_coxeter3/version_requirements.txt +++ b/build/pkgs/sagemath_coxeter3/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.5 +sagemath-coxeter3 ~= 10.6b0 diff --git a/build/pkgs/sagemath_environment/version_requirements.txt b/build/pkgs/sagemath_environment/version_requirements.txt index 7dda12e45a9..7e0f787af06 100644 --- a/build/pkgs/sagemath_environment/version_requirements.txt +++ b/build/pkgs/sagemath_environment/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.5 +sagemath-environment ~= 10.6b0 diff --git a/build/pkgs/sagemath_mcqd/version_requirements.txt b/build/pkgs/sagemath_mcqd/version_requirements.txt index 9e1ef4f46bb..3a2722024c4 100644 --- a/build/pkgs/sagemath_mcqd/version_requirements.txt +++ b/build/pkgs/sagemath_mcqd/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.5 +sagemath-mcqd ~= 10.6b0 diff --git a/build/pkgs/sagemath_meataxe/version_requirements.txt b/build/pkgs/sagemath_meataxe/version_requirements.txt index f877d05503f..3cb0d050fa5 100644 --- a/build/pkgs/sagemath_meataxe/version_requirements.txt +++ b/build/pkgs/sagemath_meataxe/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.5 +sagemath-meataxe ~= 10.6b0 diff --git a/build/pkgs/sagemath_objects/version_requirements.txt b/build/pkgs/sagemath_objects/version_requirements.txt index 55b2a515688..e8c44e2142e 100644 --- a/build/pkgs/sagemath_objects/version_requirements.txt +++ b/build/pkgs/sagemath_objects/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.5 +sagemath-objects ~= 10.6b0 diff --git a/build/pkgs/sagemath_repl/version_requirements.txt b/build/pkgs/sagemath_repl/version_requirements.txt index 3b19e791c62..3df75b7c62a 100644 --- a/build/pkgs/sagemath_repl/version_requirements.txt +++ b/build/pkgs/sagemath_repl/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.5 +sagemath-repl ~= 10.6b0 diff --git a/build/pkgs/sagemath_sirocco/version_requirements.txt b/build/pkgs/sagemath_sirocco/version_requirements.txt index fb52db7e2e5..2c8db8e59f7 100644 --- a/build/pkgs/sagemath_sirocco/version_requirements.txt +++ b/build/pkgs/sagemath_sirocco/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.5 +sagemath-sirocco ~= 10.6b0 diff --git a/build/pkgs/sagemath_tdlib/version_requirements.txt b/build/pkgs/sagemath_tdlib/version_requirements.txt index 61cefc36c54..1732fe39010 100644 --- a/build/pkgs/sagemath_tdlib/version_requirements.txt +++ b/build/pkgs/sagemath_tdlib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.5 +sagemath-tdlib ~= 10.6b0 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/src/VERSION.txt b/src/VERSION.txt index 9a62de225f0..bf89b51e25f 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.5 +10.6.beta0 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index b6288bff917..8f940ae430b 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.5' -SAGE_RELEASE_DATE='2024-12-04' -SAGE_VERSION_BANNER='SageMath version 10.5, Release Date: 2024-12-04' +SAGE_VERSION='10.6.beta0' +SAGE_RELEASE_DATE='2024-12-08' +SAGE_VERSION_BANNER='SageMath version 10.6.beta0, Release Date: 2024-12-08' diff --git a/src/sage/version.py b/src/sage/version.py index cc61dd0ca38..37c771ba0f2 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '10.5' -date = '2024-12-04' -banner = 'SageMath version 10.5, Release Date: 2024-12-04' +version = '10.6.beta0' +date = '2024-12-08' +banner = 'SageMath version 10.6.beta0, Release Date: 2024-12-08'