From 6ab77b7f4d88d261fab9d244fadb409f80551260 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Nov 2024 17:44:58 +0800 Subject: [PATCH 01/69] Correctly print import errors in `sage.all` When there is an error during importing `sage.all`, then it is just hidden but sage's are no longer available. This is very hard to debug and misleading during development. For this reason the fallback to `repl.all` is removed. Furthermore, a ruff exception for "unused imports" is added for all files, since these files always contains many unused imports. --- ruff.toml | 5 +++++ src/sage/repl/ipython_extension.py | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ruff.toml b/ruff.toml index b3070914153..15def717a4e 100644 --- a/ruff.toml +++ b/ruff.toml @@ -12,3 +12,8 @@ lint.select = [ lint.ignore = [ "E501", # Line too long - hard to avoid in doctests, and better handled by black. ] + +[lint.per-file-ignores] +"all.py" = [ + "F401", # Unused import - these files are by definition collections of imports. +] diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index b6fc42bbb37..df4b04d5a31 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -434,10 +434,7 @@ def __init__(self, shell=None): self.init_inspector() self.init_line_transforms() - try: - import sage.all # until sage's import hell is fixed - except ImportError: - import sage.all__sagemath_repl + import sage.all # noqa: F401 self.shell.verbose_quit = True From aa509c6df0589bd19a33b5b63dc101a337be90f0 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 9 Dec 2024 18:38:25 +0800 Subject: [PATCH 02/69] =?UTF-8?q?Fix=20more=20ruff=20issues=20in=20=CC=80?= =?UTF-8?q?=20sage.manifolds`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sage/manifolds/calculus_method.py | 4 +- src/sage/manifolds/catalog.py | 111 ++-- src/sage/manifolds/chart.py | 590 +++++++++++++-------- src/sage/manifolds/chart_func.py | 382 ++++++++----- src/sage/manifolds/continuous_map.py | 324 ++++++----- src/sage/manifolds/continuous_map_image.py | 4 +- src/sage/manifolds/family.py | 23 +- src/sage/manifolds/manifold_homset.py | 47 +- src/sage/manifolds/operators.py | 5 +- 9 files changed, 951 insertions(+), 539 deletions(-) diff --git a/src/sage/manifolds/calculus_method.py b/src/sage/manifolds/calculus_method.py index f7193b12c16..abbc5c8bc5f 100644 --- a/src/sage/manifolds/calculus_method.py +++ b/src/sage/manifolds/calculus_method.py @@ -172,6 +172,7 @@ class CalculusMethod(SageObject): associated with each calculus method and :meth:`set_simplify_function` for introducing a new simplification algorithm. """ + _default = 'SR' # default calculus method _methods = ('SR', 'sympy') # implemented methods _tranf = {'SR': _Sympy_to_SR, 'sympy': _SR_to_Sympy} # translators @@ -337,8 +338,7 @@ def set(self, method): NotImplementedError: method lala not implemented """ if method not in self._methods: - raise NotImplementedError("method {} not ".format(method) + - "implemented") + raise NotImplementedError("method {} not ".format(method) + "implemented") self._current = method def current(self): diff --git a/src/sage/manifolds/catalog.py b/src/sage/manifolds/catalog.py index fb6ba5634f2..aa75ed115b8 100644 --- a/src/sage/manifolds/catalog.py +++ b/src/sage/manifolds/catalog.py @@ -82,6 +82,7 @@ def Minkowski(positive_spacelike=True, names=None): [ 0 0 0 -1] """ from sage.manifolds.manifold import Manifold + M = Manifold(4, 'M', structure='Lorentzian') if names is None: names = ("t", "x", "y", "z") @@ -90,8 +91,8 @@ def Minkowski(positive_spacelike=True, names=None): g = M.metric('g') sgn = 1 if positive_spacelike else -1 - g[0,0] = -sgn - g[1,1], g[2,2], g[3,3] = sgn, sgn, sgn + g[0, 0] = -sgn + g[1, 1], g[2, 2], g[3, 3] = sgn, sgn, sgn return M @@ -176,48 +177,71 @@ def Kerr(m=1, a=0, coordinates='BL', names=None): 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: - names = (r't:(-oo,+oo)', r'r:(0,+oo)', r'th:(0,pi):\theta', - r'ph:(-pi,pi):periodic:\phi') + names = ( + r't:(-oo,+oo)', + r'r:(0,+oo)', + r'th:(0,pi):\theta', + r'ph:(-pi,pi):periodic:\phi', + ) else: - names = (names[0]+r':(-oo,+oo)', names[1]+r':(0,+oo)', - names[2]+r':(0,pi):\theta', - names[3]+r':(-pi,pi):periodic:\phi') + names = ( + names[0] + r':(-oo,+oo)', + names[1] + r':(0,+oo)', + names[2] + r':(0,pi):\theta', + names[3] + r':(-pi,pi):periodic:\phi', + ) C = M.chart(names=names) M._first_ngens = C._first_ngens g = M.metric('g') t, r, th, ph = C[:] - rho = sqrt(r**2+a**2*cos(th)**2) - g[0, 0], g[1, 1], g[2, 2], g[3, 3] = -(1-2*m*r/rho**2), 1+2*m*r/rho**2,\ - rho**2, (r**2+a**2+2*a**2*m*r*sin(th)**2/rho**2)*sin(th)**2 - g[0, 1] = 2*m*r/rho**2 - g[0, 3] = -2*a*m*r/rho**2*sin(th)**2 - g[1, 3] = -a*sin(th)**2*(1+2*m*r/rho**2) + rho = sqrt(r**2 + a**2 * cos(th) ** 2) + g[0, 0], g[1, 1], g[2, 2], g[3, 3] = ( + -(1 - 2 * m * r / rho**2), + 1 + 2 * m * r / rho**2, + rho**2, + (r**2 + a**2 + 2 * a**2 * m * r * sin(th) ** 2 / rho**2) * sin(th) ** 2, + ) + g[0, 1] = 2 * m * r / rho**2 + g[0, 3] = -2 * a * m * r / rho**2 * sin(th) ** 2 + g[1, 3] = -a * sin(th) ** 2 * (1 + 2 * m * r / rho**2) return M if coordinates == "BL": if names is None: - names = (r't:(-oo,+oo)', r'r:(0,+oo)', r'th:(0,pi):\theta', - r'ph:(-pi,pi):periodic:\phi') + names = ( + r't:(-oo,+oo)', + r'r:(0,+oo)', + r'th:(0,pi):\theta', + r'ph:(-pi,pi):periodic:\phi', + ) else: - names = (names[0]+r':(-oo,+oo)', names[1]+r':(0,+oo)', - names[2]+r':(0,pi):\theta', - names[3]+r':(-pi,pi):periodic:\phi') + names = ( + names[0] + r':(-oo,+oo)', + names[1] + r':(0,+oo)', + names[2] + r':(0,pi):\theta', + names[3] + r':(-pi,pi):periodic:\phi', + ) C = M.chart(names=names) M._first_ngens = C._first_ngens g = M.metric('g') t, r, th, ph = C[:] - rho = sqrt(r**2+a**2*cos(th)**2) - g[0, 0], g[1, 1], g[2, 2], g[3, 3] = -(1-2*m*r/rho**2), \ - rho**2/(r**2-2*m*r+a**2), rho**2, \ - (r**2+a**2+2*m*r*a**2/rho**2*sin(th)**2)*sin(th)**2 - g[0, 3] = -2*m*r*a*sin(th)**2/rho**2 + rho = sqrt(r**2 + a**2 * cos(th) ** 2) + g[0, 0], g[1, 1], g[2, 2], g[3, 3] = ( + -(1 - 2 * m * r / rho**2), + rho**2 / (r**2 - 2 * m * r + a**2), + rho**2, + (r**2 + a**2 + 2 * m * r * a**2 / rho**2 * sin(th) ** 2) * sin(th) ** 2, + ) + g[0, 3] = -2 * m * r * a * sin(th) ** 2 / rho**2 return M - raise NotImplementedError("coordinates system not implemented, see help" - " for details") + raise NotImplementedError( + "coordinates system not implemented, see help" " for details" + ) def Torus(R=2, r=1, names=None): @@ -255,6 +279,7 @@ def Torus(R=2, r=1, names=None): from sage.functions.trig import cos, sin 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: @@ -263,7 +288,7 @@ def Torus(R=2, r=1, names=None): C = M.chart(names=names) M._first_ngens = C._first_ngens th, ph = C[:] - coordfunc = [(R+r*cos(th))*cos(ph), (R+r*cos(th))*sin(ph), r*sin(th)] + coordfunc = [(R + r * cos(th)) * cos(ph), (R + r * cos(th)) * sin(ph), r * sin(th)] imm = M.diff_map(E, coordfunc) M.set_embedding(imm) M.induced_metric() @@ -357,9 +382,12 @@ def RealProjectiveSpace(dim=2): from sage.manifolds.manifold import Manifold - P = Manifold(dim, f"RP{dim}", - structure='topological', - latex_name=r"\mathbb{{RP}}^{{{}}}".format(dim)) + P = Manifold( + dim, + f"RP{dim}", + structure='topological', + latex_name=r"\mathbb{{RP}}^{{{}}}".format(dim), + ) # the trailing whitespace in the string is intentional for defining charts names = [f'x_{i} ' for i in range(dim + 1)] @@ -373,13 +401,12 @@ def RealProjectiveSpace(dim=2): U = P.open_subset(name=f'U{j}', latex_name=f'U_{j}') # The chart where we assert that x_i == 1 - Cj = U.chart(''.join(names[:j] + names[j+1:])) + Cj = U.chart(''.join(names[:j] + names[j + 1 :])) gj = Cj[:] charts[j] = Cj for i in range(j): - Ci = charts[i] gi = Ci[:] @@ -387,15 +414,19 @@ def RealProjectiveSpace(dim=2): xj = gi[j - 1] # use index j - 1 because i < j and xi is omitted in gi # the corresponding coordinates in R^{dim+1} - d_plus_one_coords = [g/xj for g in gi[:i]] + [1/xj] + [g/xj for g in gi[i:]] - cj_new_coords = d_plus_one_coords[:j] + d_plus_one_coords[j+1:] - - Ci_to_Cj = Ci.transition_map(Cj, cj_new_coords, - restrictions1=xj != 0, - restrictions2=xi != 0) - - d_plus_one_coords = [g/xi for g in gj[:j]] + [1/xi] + [g/xi for g in gj[j:]] - ci_new_coords = d_plus_one_coords[:i] + d_plus_one_coords[i+1:] + d_plus_one_coords = ( + [g / xj for g in gi[:i]] + [1 / xj] + [g / xj for g in gi[i:]] + ) + cj_new_coords = d_plus_one_coords[:j] + d_plus_one_coords[j + 1 :] + + Ci_to_Cj = Ci.transition_map( + Cj, cj_new_coords, restrictions1=xj != 0, restrictions2=xi != 0 + ) + + d_plus_one_coords = ( + [g / xi for g in gj[:j]] + [1 / xi] + [g / xi for g in gj[j:]] + ) + ci_new_coords = d_plus_one_coords[:i] + d_plus_one_coords[i + 1 :] Cj_to_Ci = Ci_to_Cj.set_inverse(*ci_new_coords, check=False) diff --git a/src/sage/manifolds/chart.py b/src/sage/manifolds/chart.py index f20a0e2bab4..3468ba44426 100644 --- a/src/sage/manifolds/chart.py +++ b/src/sage/manifolds/chart.py @@ -287,9 +287,15 @@ class Chart(UniqueRepresentation, SageObject): """ @staticmethod - def __classcall__(cls, domain, coordinates='', - calc_method=None, names=None, - coord_restrictions=None, **coordinate_options): + def __classcall__( + cls, + domain, + coordinates='', + calc_method=None, + names=None, + coord_restrictions=None, + **coordinate_options, + ): r""" Normalize init args and implement unique representation behavior. @@ -307,8 +313,7 @@ def __classcall__(cls, domain, coordinates='', for x in names: coordinates += x + ' ' coordinates = coordinates[:-1] - coordinates, parsed_options = cls._parse_coordinates(domain, - coordinates) + coordinates, parsed_options = cls._parse_coordinates(domain, coordinates) if not coordinate_options: coordinate_options = parsed_options @@ -318,16 +323,28 @@ def __classcall__(cls, domain, coordinates='', return domain._charts_by_coord[coord_string] except KeyError: # Make coord_restrictions hashable - coord_restrictions = cls._normalize_coord_restrictions(coordinates, - coord_restrictions) - self = super().__classcall__(cls, domain, coordinates, calc_method, - coord_restrictions=coord_restrictions, - **coordinate_options) + coord_restrictions = cls._normalize_coord_restrictions( + coordinates, coord_restrictions + ) + self = super().__classcall__( + cls, + domain, + coordinates, + calc_method, + coord_restrictions=coord_restrictions, + **coordinate_options, + ) domain._charts_by_coord[coord_string] = self return self - def __init__(self, domain, coordinates, calc_method=None, periods=None, - coord_restrictions=None): + def __init__( + self, + domain, + coordinates, + calc_method=None, + periods=None, + coord_restrictions=None, + ): r""" Construct a chart. @@ -354,23 +371,29 @@ def __init__(self, domain, coordinates, calc_method=None, periods=None, [Chart (U, (x, y)), Chart (V, (x, y))] """ from sage.manifolds.manifold import TopologicalManifold + if not isinstance(domain, TopologicalManifold): - raise TypeError("the first argument must be an open subset of " + - "a topological manifold") + raise TypeError( + "the first argument must be an open subset of " + + "a topological manifold" + ) self._manifold = domain.manifold() self._domain = domain self._sindex = self._manifold.start_index() # Handling of calculus methods available on this chart: - self._calc_method = CalculusMethod(current=calc_method, - base_field_type=self.manifold().base_field_type()) + self._calc_method = CalculusMethod( + current=calc_method, base_field_type=self.manifold().base_field_type() + ) self.simplify = self._calc_method.simplify # Treatment of the coordinates: self._periods = periods if len(coordinates) != self._manifold.dim(): - raise ValueError("the list of coordinates must contain " + - "{} elements".format(self._manifold.dim())) + raise ValueError( + "the list of coordinates must contain " + + "{} elements".format(self._manifold.dim()) + ) self._xx = coordinates # # Additional restrictions on the coordinates. @@ -383,8 +406,7 @@ def __init__(self, domain, coordinates, calc_method=None, periods=None, # the chart is added in the top charts iff its coordinates have # not been used on a domain including the chart's domain: for chart in sd._atlas: - if (domain.is_subset(chart._domain) - and self._xx == chart._xx): + if domain.is_subset(chart._domain) and self._xx == chart._xx: break else: sd._top_charts.append(self) @@ -400,9 +422,10 @@ def __init__(self, domain, coordinates, calc_method=None, periods=None, # restriction of: self._supercharts = set([self]) - self._dom_restrict = {} # dict. of the restrictions of self to - # subsets of self._domain, with the - # subsets as keys + # dict. of the restrictions of self to + # subsets of self._domain, with the + # subsets as keys + self._dom_restrict = {} # The null and one functions of the coordinates: # Expression in self of the zero and one scalar fields of open sets # containing the domain of self: @@ -445,13 +468,13 @@ def _parse_coordinates(cls, domain, coordinates): coord_list = coordinates.split() else: coord_list = coordinates - xx_list = [] # will contain the coordinates as Sage symbolic variables + xx_list = [] # will contain the coordinates as Sage symbolic variables period_list = [] for coord_index, coord_field in enumerate(coord_list): coord_properties = coord_field.split(':') - coord_symb = coord_properties[0].strip() # the coordinate symbol - coord_latex = None # possibly redefined below - period = None # possibly redefined below + coord_symb = coord_properties[0].strip() # the coordinate symbol + coord_latex = None # possibly redefined below + period = None # possibly redefined below # scan of the properties other than the symbol: for prop in coord_properties[1:]: prop1 = prop.strip() @@ -489,6 +512,7 @@ def _normalize_coord_restrictions(coordinates, coord_restrictions): sage: Chart._normalize_coord_restrictions(coordinates, [x > y, (x != 0, y != 0), z^2 < x]) frozenset({(x != 0, y != 0), x > y, z^2 < x}) """ + def normalize(r): if isinstance(r, tuple): # or return tuple(normalize(x) for x in r) @@ -500,8 +524,9 @@ def normalize(r): if coord_restrictions is None: return frozenset() - if callable(coord_restrictions) and not isinstance(coord_restrictions, - Expression): + if callable(coord_restrictions) and not isinstance( + coord_restrictions, Expression + ): # lambda-quoted coord_restrictions = coord_restrictions(*coordinates) @@ -542,9 +567,9 @@ def _latex_(self): """ description = r'\left(' + latex(self.domain()).strip() + ',(' n = len(self._xx) - for i in range(n-1): + for i in range(n - 1): description += latex(self._xx[i]).strip() + ', ' - description += latex(self._xx[n-1]).strip() + r')\right)' + description += latex(self._xx[n - 1]).strip() + r')\right)' return description def _first_ngens(self, n): @@ -608,8 +633,8 @@ def __getitem__(self, i): start -= self._sindex if stop is not None: stop -= self._sindex - return self._xx[start:stop:i.step] - return self._xx[i-self._sindex] + return self._xx[start : stop : i.step] + return self._xx[i - self._sindex] def __call__(self, point): r""" @@ -752,8 +777,14 @@ def add_restrictions(self, restrictions): False """ from sage.misc.superseded import deprecation - deprecation(32102, "Chart.add_restrictions is deprecated; provide the restrictions at the time of creating the chart") - self._restrictions.extend(self._normalize_coord_restrictions(self._xx, restrictions)) + + deprecation( + 32102, + "Chart.add_restrictions is deprecated; provide the restrictions at the time of creating the chart", + ) + self._restrictions.extend( + self._normalize_coord_restrictions(self._xx, restrictions) + ) def restrict(self, subset, restrictions=None): r""" @@ -807,20 +838,26 @@ def restrict(self, subset, restrictions=None): return self if subset not in self._dom_restrict: if not subset.is_subset(self.domain()): - raise ValueError("the specified subset is not a subset " + - "of the domain of definition of the chart") + raise ValueError( + "the specified subset is not a subset " + + "of the domain of definition of the chart" + ) coordinates = "" for coord in self._xx: coordinates += repr(coord) + ' ' res_coord_restrictions = set(self._restrictions) - res_coord_restrictions.update(self._normalize_coord_restrictions(self._xx, - restrictions)) - res = type(self)(subset, coordinates, - calc_method=self._calc_method._current, - periods=self._periods, - # The coordinate restrictions are added - # to the result chart - coord_restrictions=res_coord_restrictions) + res_coord_restrictions.update( + self._normalize_coord_restrictions(self._xx, restrictions) + ) + res = type(self)( + subset, + coordinates, + calc_method=self._calc_method._current, + periods=self._periods, + # The coordinate restrictions are added + # to the result chart + coord_restrictions=res_coord_restrictions, + ) # Update of supercharts and subcharts: res._supercharts.update(self._supercharts) for schart in self._supercharts: @@ -926,12 +963,14 @@ def _check_restrictions(self, restrict, substitutions): sage: X._check_restrictions([(x0], {x: 2, y: 1}) False """ - if isinstance(restrict, tuple): # case of 'or' conditions - return any(self._check_restrictions(cond, substitutions) - for cond in restrict) - elif isinstance(restrict, (list, set, frozenset)): # case of 'and' conditions - return all(self._check_restrictions(cond, substitutions) - for cond in restrict) + if isinstance(restrict, tuple): # case of 'or' conditions + return any( + self._check_restrictions(cond, substitutions) for cond in restrict + ) + elif isinstance(restrict, (list, set, frozenset)): # case of 'and' conditions + return all( + self._check_restrictions(cond, substitutions) for cond in restrict + ) # Case of a single condition: return bool(restrict.subs(substitutions)) @@ -947,6 +986,7 @@ def codomain(self): Vector space of dimension 2 over Complex Field with 53 bits of precision """ from sage.modules.free_module import VectorSpace + ambient = VectorSpace(self.manifold().base_field(), self.manifold().dimension()) if self._restrictions: return self._restrict_set(ambient, self._restrictions) @@ -977,24 +1017,35 @@ def _restrict_set(self, universe, coord_restrictions): { (x, y) ∈ Vector space of dimension 2 over Real Field with 53 bits of precision : y < 0 } and { (x, y) ∈ Vector space of dimension 2 over Real Field with 53 bits of precision : x > 0 } """ - if isinstance(coord_restrictions, tuple): # case of 'or' conditions + if isinstance(coord_restrictions, tuple): # case of 'or' conditions A = self._restrict_set(universe, coord_restrictions[0]) if len(coord_restrictions) == 1: return A else: return A.union(self._restrict_set(universe, coord_restrictions[1:])) - elif isinstance(coord_restrictions, (list, set, frozenset)): # case of 'and' conditions + elif isinstance( + coord_restrictions, (list, set, frozenset) + ): # case of 'and' conditions A = self._restrict_set(universe, coord_restrictions[0]) if len(coord_restrictions) == 1: return A else: - return A.intersection(self._restrict_set(universe, coord_restrictions[1:])) + return A.intersection( + self._restrict_set(universe, coord_restrictions[1:]) + ) # Case of a single condition: from sage.sets.condition_set import ConditionSet + return ConditionSet(universe, coord_restrictions, vars=self._xx) - def transition_map(self, other, transformations, intersection_name=None, - restrictions1=None, restrictions2=None): + def transition_map( + self, + other, + transformations, + intersection_name=None, + restrictions1=None, + restrictions2=None, + ): r""" Construct the transition map between the current chart, `(U, \varphi)` say, and another one, `(V, \psi)` say. @@ -1112,7 +1163,7 @@ def transition_map(self, other, transformations, intersection_name=None, else: chart2 = other.restrict(dom, restrictions2) if not isinstance(transformations, (tuple, list)): - transformations = [transformations] + transformations = [transformations] return CoordChange(chart1, chart2, *transformations) def preimage(self, codomain_subset, name=None, latex_name=None): @@ -1217,8 +1268,10 @@ def preimage(self, codomain_subset, name=None, latex_name=None): True """ from sage.manifolds.subsets.pullback import ManifoldSubsetPullback - return ManifoldSubsetPullback(self, codomain_subset, - name=name, latex_name=latex_name) + + return ManifoldSubsetPullback( + self, codomain_subset, name=name, latex_name=latex_name + ) pullback = preimage @@ -1236,8 +1289,7 @@ def function_ring(self): return ChartFunctionRing(self) - def function(self, expression, calc_method=None, expansion_symbol=None, - order=None): + def function(self, expression, calc_method=None, expansion_symbol=None, order=None): r""" Define a coordinate function to the base field. @@ -1318,9 +1370,13 @@ def function(self, expression, calc_method=None, expansion_symbol=None, See :class:`~sage.manifolds.chart_func.ChartFunction` for more examples. """ parent = self.function_ring() - return parent.element_class(parent, expression, calc_method=calc_method, - expansion_symbol=expansion_symbol, - order=order) + return parent.element_class( + parent, + expression, + calc_method=calc_method, + expansion_symbol=expansion_symbol, + order=order, + ) def zero_function(self): r""" @@ -1547,11 +1603,13 @@ def multifunction(self, *expressions): """ from sage.manifolds.chart_func import MultiCoordFunction + return MultiCoordFunction(self, expressions) # ***************************************************************************** + class RealChart(Chart): r""" Chart on a topological manifold over `\RR`. @@ -1831,8 +1889,16 @@ class RealChart(Chart): Chart grids can be drawn in 2D or 3D graphics thanks to the method :meth:`plot`. """ - def __init__(self, domain, coordinates, calc_method=None, bounds=None, - periods=None, coord_restrictions=None): + + def __init__( + self, + domain, + coordinates, + calc_method=None, + bounds=None, + periods=None, + coord_restrictions=None, + ): r""" Construct a chart on a real topological manifold. @@ -1849,8 +1915,13 @@ def __init__(self, domain, coordinates, calc_method=None, bounds=None, [x is real, y is real] sage: TestSuite(X).run() """ - super().__init__(domain, coordinates, calc_method=calc_method, - periods=periods, coord_restrictions=coord_restrictions) + super().__init__( + domain, + coordinates, + calc_method=calc_method, + periods=periods, + coord_restrictions=coord_restrictions, + ) self._bounds = bounds self._tighten_bounds() self._fast_valid_coordinates = None @@ -1896,16 +1967,17 @@ def _parse_coordinates(cls, domain, coordinates): 'periods': (None, None)}) """ from sage.symbolic.assumptions import assume + if isinstance(coordinates, str): coord_list = coordinates.split() else: coord_list = coordinates - xx_list = [] # will contain the coordinates as Sage symbolic variables - bounds_list = [] # will contain the coordinate bounds + xx_list = [] # will contain the coordinates as Sage symbolic variables + bounds_list = [] # will contain the coordinate bounds period_list = [] for coord_index, coord_field in enumerate(coord_list): coord_properties = coord_field.split(':') - coord_symb = coord_properties[0].strip() # the coordinate symbol + coord_symb = coord_properties[0].strip() # the coordinate symbol # default values, possibly redefined below: coord_latex = None xmin = -Infinity @@ -1920,16 +1992,30 @@ def _parse_coordinates(cls, domain, coordinates): delim_min = prop1[0] if delim_min in ['[', ']', '(']: # prop1 is the coordinate's range - xmin_str, xmax_str = prop1[1:len(prop1)-1].split(',') - if xmin_str not in ['-inf', '-Inf', '-infinity', - '-Infinity', '-oo']: + xmin_str, xmax_str = prop1[1 : len(prop1) - 1].split(',') + if xmin_str not in [ + '-inf', + '-Inf', + '-infinity', + '-Infinity', + '-oo', + ]: xmin = SR(xmin_str) - xmin_included = ( delim_min == '[' ) - if xmax_str not in ['inf', '+inf', 'Inf', '+Inf', - 'infinity', '+infinity', 'Infinity', - '+Infinity', 'oo', '+oo']: + xmin_included = delim_min == '[' + if xmax_str not in [ + 'inf', + '+inf', + 'Inf', + '+Inf', + 'infinity', + '+infinity', + 'Infinity', + '+Infinity', + 'oo', + '+oo', + ]: xmax = SR(xmax_str) - xmax_included = ( prop1[-1] == ']' ) + xmax_included = prop1[-1] == ']' elif prop1[0:6] == 'period': # prop1 indicates a periodic coordinate is_periodic = True @@ -1941,8 +2027,7 @@ def _parse_coordinates(cls, domain, coordinates): # prop1 is the coordinate's LaTeX symbol coord_latex = prop1 # Construction of the coordinate as a Sage symbolic variable: - coord_var = SR.var(coord_symb, domain='real', - latex_name=coord_latex) + coord_var = SR.var(coord_symb, domain='real', latex_name=coord_latex) assume(coord_var, 'real') if is_periodic: period = xmax - xmin @@ -1962,8 +2047,9 @@ def _parse_coordinates(cls, domain, coordinates): xx_list.append(coord_var) bounds_list.append(((xmin, xmin_included), (xmax, xmax_included))) period_list.append(period) - return tuple(xx_list), dict(bounds=tuple(bounds_list), - periods=tuple(period_list)) + return tuple(xx_list), dict( + bounds=tuple(bounds_list), periods=tuple(period_list) + ) def coord_bounds(self, i=None): r""" @@ -2025,7 +2111,7 @@ def coord_bounds(self, i=None): if i is None: return self._bounds else: - return self._bounds[i-self._sindex] + return self._bounds[i - self._sindex] def codomain(self): r""" @@ -2056,13 +2142,20 @@ def codomain(self): 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)) - for ((xmin, min_included), (xmax, max_included)) in self._bounds) - if all(interval.is_universe() - for interval in intervals): - ambient = VectorSpace(self.manifold().base_field(), self.manifold().dimension()) + + intervals = tuple( + RealSet.interval( + xmin, + xmax, + lower_closed=(min_included == 'periodic' or min_included), + upper_closed=(max_included != 'periodic' and max_included), + ) + for ((xmin, min_included), (xmax, max_included)) in self._bounds + ) + if all(interval.is_universe() for interval in intervals): + ambient = VectorSpace( + self.manifold().base_field(), self.manifold().dimension() + ) else: ambient = cartesian_product(intervals) if self._restrictions: @@ -2150,11 +2243,11 @@ def _display_coord_range(self, xx, rtxt, rlatex): if resu_txt != "": resu_txt += "; " resu_latex += r";\quad " - resu_txt, resu_latex = _display_coord_range(self, x, resu_txt, - resu_latex) + resu_txt, resu_latex = _display_coord_range( + self, x, resu_txt, resu_latex + ) else: - resu_txt, resu_latex = _display_coord_range(self, xx, resu_txt, - resu_latex) + resu_txt, resu_latex = _display_coord_range(self, xx, resu_txt, resu_latex) return FormattedExpansion(resu_txt, resu_latex) def add_restrictions(self, restrictions): @@ -2239,13 +2332,16 @@ def _tighten_bounds(self): x: (-oo, 0); y: (1/2, +oo) """ import operator - bounds = list(self._bounds) # convert to a list for modifications + + bounds = list(self._bounds) # convert to a list for modifications new_restrictions = [] for restrict in self._restrictions: - restrict_used = False # determines whether restrict is used - # to set some coordinate bound - if not isinstance(restrict, (tuple, list, set, frozenset)): # case of combined - # conditions excluded + restrict_used = False # determines whether restrict is used to set some coordinate bound + if not isinstance( + restrict, (tuple, list, set, frozenset) + ): + # case of combined + # conditions excluded operands = restrict.operands() left = operands[0] right = operands[1] @@ -2253,15 +2349,14 @@ def _tighten_bounds(self): if left in self._xx: # the l.h.s. of the restriction is a single # coordinate - right_coord = [coord for coord in self._xx - if coord in right_var] + right_coord = [coord for coord in self._xx if coord in right_var] if not right_coord: # there is no other coordinate in the r.h.s. ind = self._xx.index(left) left_bounds = list(bounds[ind]) oper = restrict.operator() - oinf = left_bounds[0][0] # old coord inf - osup = left_bounds[1][0] # old coord sup + oinf = left_bounds[0][0] # old coord inf + osup = left_bounds[1][0] # old coord sup if oper == operator.lt: if osup == Infinity or right <= osup: left_bounds[1] = (right, False) @@ -2367,21 +2462,28 @@ def restrict(self, subset, restrictions=None): return self if subset not in self._dom_restrict: if not subset.is_subset(self.domain()): - raise ValueError("the specified subset is not a subset " + - "of the domain of definition of the chart") + raise ValueError( + "the specified subset is not a subset " + + "of the domain of definition of the chart" + ) coordinates = "" for coord in self._xx: coordinates += repr(coord) + ' ' res_coord_restrictions = set(self._restrictions) - res_coord_restrictions.update(self._normalize_coord_restrictions(self._xx, - restrictions)) - res = type(self)(subset, coordinates, - calc_method=self._calc_method._current, - bounds=self._bounds, periods=self._periods, - # The coordinate restrictions are added - # to the result chart and possibly - # transformed into coordinate bounds: - coord_restrictions=res_coord_restrictions) + res_coord_restrictions.update( + self._normalize_coord_restrictions(self._xx, restrictions) + ) + res = type(self)( + subset, + coordinates, + calc_method=self._calc_method._current, + bounds=self._bounds, + periods=self._periods, + # The coordinate restrictions are added + # to the result chart and possibly + # transformed into coordinate bounds: + coord_restrictions=res_coord_restrictions, + ) # Update of supercharts and subcharts: res._supercharts.update(self._supercharts) for schart in self._supercharts: @@ -2617,11 +2719,26 @@ def evaluate_fast_callable(*coordinates): self._fast_valid_coordinates = evaluate_fast_callable return self._fast_valid_coordinates(*coordinates) - @options(max_range=8, color='red', style='-', thickness=1, plot_points=75, - label_axes=True) - def plot(self, chart=None, ambient_coords=None, mapping=None, - fixed_coords=None, ranges=None, number_values=None, - steps=None, parameters=None, **kwds): + @options( + max_range=8, + color='red', + style='-', + thickness=1, + plot_points=75, + label_axes=True, + ) + def plot( + self, + chart=None, + ambient_coords=None, + mapping=None, + fixed_coords=None, + ranges=None, + number_values=None, + steps=None, + parameters=None, + **kwds, + ): r""" Plot ``self`` as a grid in a Cartesian graph based on the coordinates of some ambient chart. @@ -3036,8 +3153,7 @@ def _plot_xx_list(xx_list, rem_coords, ranges, steps, number_values): return resu else: rem_coords.remove(coord) - return _plot_xx_list(resu, rem_coords, ranges, steps, - number_values) + return _plot_xx_list(resu, rem_coords, ranges, steps, number_values) if chart is None: chart = self @@ -3059,12 +3175,14 @@ def _plot_xx_list(xx_list, rem_coords, ranges, steps, number_values): if coord not in ambient_coords: fixed_coords[coord] = 0 else: - transf = None # to be the MultiCoordFunction object relating self - # to the ambient chart + transf = None # to be the MultiCoordFunction object relating self + # to the ambient chart if mapping is None: if not self.domain().is_subset(chart.domain()): - raise ValueError("the domain of {} is not ".format(self) + - "included in that of {}".format(chart)) + raise ValueError( + "the domain of {} is not ".format(self) + + "included in that of {}".format(chart) + ) coord_changes = chart.domain()._coord_changes for chart_pair in coord_changes: if chart_pair == (self, chart): @@ -3078,22 +3196,28 @@ def _plot_xx_list(xx_list, rem_coords, ranges, steps, number_values): transf = coord_changes[chart_pair]._transf else: if not isinstance(mapping, ContinuousMap): - raise TypeError("the argument 'mapping' must be a " - "continuous manifold map") + raise TypeError( + "the argument 'mapping' must be a " "continuous manifold map" + ) if not self.domain().is_subset(mapping.domain()): - raise ValueError("the domain of {} is not ".format(self) + - "included in that of {}".format(mapping)) + raise ValueError( + "the domain of {} is not ".format(self) + + "included in that of {}".format(mapping) + ) if not chart.domain().is_subset(mapping._codomain): - raise ValueError("the domain of {} is not ".format(chart) + - "included in the codomain of {}".format( - mapping)) + raise ValueError( + "the domain of {} is not ".format(chart) + + "included in the codomain of {}".format(mapping) + ) try: transf = mapping.coord_functions(chart1=self, chart2=chart) except ValueError: pass if transf is None: - raise ValueError("no relation has been found between " + - "{} and {}".format(self, chart)) + raise ValueError( + "no relation has been found between " + + "{} and {}".format(self, chart) + ) # # 2/ Treatment of input parameters # ----------------------------- @@ -3118,8 +3242,10 @@ def _plot_xx_list(xx_list, rem_coords, ranges, steps, number_values): ranges0 = {} for coord in coords: if coord in ranges: - ranges0[coord] = (numerical_approx(ranges[coord][0]), - numerical_approx(ranges[coord][1])) + ranges0[coord] = ( + numerical_approx(ranges[coord][0]), + numerical_approx(ranges[coord][1]), + ) else: bounds = self._bounds[self._xx.index(coord)] if bounds[0][0] == -Infinity: @@ -3127,19 +3253,19 @@ def _plot_xx_list(xx_list, rem_coords, ranges, steps, number_values): elif bounds[0][1]: xmin = numerical_approx(bounds[0][0]) else: - xmin = numerical_approx(bounds[0][0] + 1.e-3) + xmin = numerical_approx(bounds[0][0] + 1.0e-3) if bounds[1][0] == Infinity: xmax = numerical_approx(max_range) elif bounds[1][1]: xmax = numerical_approx(bounds[1][0]) else: - xmax = numerical_approx(bounds[1][0] - 1.e-3) + xmax = numerical_approx(bounds[1][0] - 1.0e-3) ranges0[coord] = (xmin, xmax) ranges = ranges0 if number_values is None: - if nca == 2: # 2D plot + if nca == 2: # 2D plot number_values = 9 - else: # 3D plot + else: # 3D plot number_values = 5 if not isinstance(number_values, dict): number_values0 = {} @@ -3150,12 +3276,15 @@ def _plot_xx_list(xx_list, rem_coords, ranges, steps, number_values): steps = {} for coord in coords: if coord not in steps: - steps[coord] = ((ranges[coord][1] - ranges[coord][0]) - / (number_values[coord]-1)) + steps[coord] = (ranges[coord][1] - ranges[coord][0]) / ( + number_values[coord] - 1 + ) else: from sage.functions.other import floor - number_values[coord] = 1 + floor((ranges[coord][1] - ranges[coord][0]) - / steps[coord]) + + number_values[coord] = 1 + floor( + (ranges[coord][1] - ranges[coord][0]) / steps[coord] + ) if not isinstance(color, dict): color0 = {} for coord in coords: @@ -3194,15 +3323,16 @@ def _plot_xx_list(xx_list, rem_coords, ranges, steps, number_values): rem_coords.remove(coord) xx_list = [xx0] if len(rem_coords) >= 1: - xx_list = _plot_xx_list(xx_list, rem_coords, ranges, steps, - number_values) + xx_list = _plot_xx_list( + xx_list, rem_coords, ranges, steps, number_values + ) xmin, xmax = ranges[coord] nbp = plot_points[coord] - dx = (xmax - xmin) / (nbp-1) + dx = (xmax - xmin) / (nbp - 1) ind_coord = self._xx.index(coord) for xx in xx_list: curve = [] - first_invalid = False # initialization + first_invalid = False # initialization xc = xmin xp = list(xx) if parameters is None: @@ -3210,48 +3340,58 @@ def _plot_xx_list(xx_list, rem_coords, ranges, steps, number_values): xp[ind_coord] = xc if self.valid_coordinates(*xp, tolerance=1e-13): yp = transf(*xp, simplify=False) - curve.append( [numerical_approx(yp[j]) - for j in ind_a] ) - first_invalid = True # next invalid point will be - # the first one + curve.append([numerical_approx(yp[j]) for j in ind_a]) + first_invalid = True # next invalid point will be + # the first one else: if first_invalid: # the curve is stopped at previous point and # added to the graph: - resu += line(curve, color=color_c, - linestyle=style_c, - thickness=thickness_c) - curve = [] # a new curve will start at the - # next valid point - first_invalid = False # next invalid point will not - # be the first one + resu += line( + curve, + color=color_c, + linestyle=style_c, + thickness=thickness_c, + ) + curve = [] # a new curve will start at the + # next valid point + first_invalid = False # next invalid point will not + # be the first one xc += dx else: for i in range(nbp): xp[ind_coord] = xc - if self.valid_coordinates(*xp, tolerance=1e-13, - parameters=parameters): + if self.valid_coordinates( + *xp, tolerance=1e-13, parameters=parameters + ): yp = transf(*xp, simplify=False) - curve.append([numerical_approx(yp[j].substitute(parameters)) - for j in ind_a]) - first_invalid = True # next invalid point will be - # the first one + curve.append( + [ + numerical_approx(yp[j].substitute(parameters)) + for j in ind_a + ] + ) + first_invalid = True # next invalid point will be + # the first one else: if first_invalid: # the curve is stopped at previous point and # added to the graph: - resu += line(curve, color=color_c, - linestyle=style_c, - thickness=thickness_c) - curve = [] # a new curve will start at the - # next valid point - first_invalid = False # next invalid point will not - # be the first one + resu += line( + curve, + color=color_c, + linestyle=style_c, + thickness=thickness_c, + ) + curve = [] # a new curve will start at the + # next valid point + first_invalid = False # next invalid point will not + # be the first one xc += dx if curve: - resu += line(curve, color=color_c, - linestyle=style_c, - thickness=thickness_c) + resu += line( + curve, color=color_c, linestyle=style_c, thickness=thickness_c + ) if nca == 2: # 2D graphic resu.set_aspect_ratio(1) if label_axes: @@ -3259,15 +3399,17 @@ def _plot_xx_list(xx_list, rem_coords, ranges, steps, number_values): # to show()), instead of using the method # Graphics.axes_labels() since the latter is not robust w.r.t. # graph addition - resu._extra_kwds['axes_labels'] = [r'$'+latex(ac)+r'$' - for ac in ambient_coords] - else: # 3D graphic + resu._extra_kwds['axes_labels'] = [ + r'$' + latex(ac) + r'$' for ac in ambient_coords + ] + else: # 3D graphic resu.aspect_ratio(1) if label_axes: labels = [str(ac) for ac in ambient_coords] resu = set_axes_labels(resu, *labels) return resu + # ***************************************************************************** @@ -3313,6 +3455,7 @@ class CoordChange(SageObject): u = x + y v = x - y """ + def __init__(self, chart1, chart2, *transformations): r""" Construct a transition map. @@ -3332,8 +3475,9 @@ def __init__(self, chart1, chart2, *transformations): self._n1 = len(chart1._xx) self._n2 = len(chart2._xx) if len(transformations) != self._n2: - raise ValueError("{} coordinate transformations ".format(self._n2) - + "must be provided") + raise ValueError( + "{} coordinate transformations ".format(self._n2) + "must be provided" + ) self._chart1 = chart1 self._chart2 = chart2 # The coordinate transformations are implemented via the class @@ -3364,8 +3508,7 @@ def _repr_(self): sage: X_to_Y # indirect doctest Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v)) """ - return "Change of coordinates from {} to {}".format(self._chart1, - self._chart2) + return "Change of coordinates from {} to {}".format(self._chart1, self._chart2) def _latex_(self): r""" @@ -3411,9 +3554,11 @@ def __eq__(self, other): return True if not isinstance(other, CoordChange): return False - return ((self._chart1 == other._chart1) - and (self._chart2 == other._chart2) - and (self._transf == other._transf)) + return ( + (self._chart1 == other._chart1) + and (self._chart2 == other._chart2) + and (self._transf == other._transf) + ) def __ne__(self, other): r""" @@ -3502,6 +3647,7 @@ def inverse(self): True """ from sage.symbolic.relation import solve + if self._inverse is not None: return self._inverse # The computation is necessary: @@ -3510,9 +3656,11 @@ def inverse(self): n1 = self._n1 n2 = self._n2 if n1 != n2: - raise ValueError("the change of coordinates is not invertible " + - "(different number of coordinates in the two " + - "charts)") + raise ValueError( + "the change of coordinates is not invertible " + + "(different number of coordinates in the two " + + "charts)" + ) # New symbolic variables (different from x2 to allow for a # correct solution even when chart2 = chart1): base_field = self._chart1.domain().base_field_type() @@ -3525,19 +3673,20 @@ def inverse(self): for i in range(n2): if x2[i].is_positive(): coord_domain[i] = 'positive' - xp2 = [ SR.temp_var(domain=coord_domain[i]) for i in range(n2) ] + xp2 = [SR.temp_var(domain=coord_domain[i]) for i in range(n2)] xx2 = self._transf.expr() equations = [xp2[i] == xx2[i] for i in range(n2)] try: solutions = solve(equations, *x1, solution_dict=True) except RuntimeError: - raise RuntimeError("the system could not be solved; use " + - "set_inverse() to set the inverse manually") + raise RuntimeError( + "the system could not be solved; use " + + "set_inverse() to set the inverse manually" + ) substitutions = dict(zip(xp2, x2)) if len(solutions) == 1: - x2_to_x1 = [solutions[0][x1[i]].subs(substitutions) - for i in range(n1)] - x2_to_x1_simpl = [] # to store simplified transformations + x2_to_x1 = [solutions[0][x1[i]].subs(substitutions) for i in range(n1)] + x2_to_x1_simpl = [] # to store simplified transformations for transf in x2_to_x1: try: transf = self._chart2.simplify(transf) @@ -3549,14 +3698,16 @@ def inverse(self): list_x2_to_x1 = [] for sol in solutions: if x2[0] in sol: - raise ValueError("the system could not be solved; use " + - "set_inverse() to set the inverse " + - "manually") + raise ValueError( + "the system could not be solved; use " + + "set_inverse() to set the inverse " + + "manually" + ) try: x2_to_x1 = [sol[x1[i]].subs(substitutions) for i in range(n1)] - except KeyError: # sol is not a valid solution + except KeyError: # sol is not a valid solution continue - x2_to_x1_simpl = [] # to store simplified transformations + x2_to_x1_simpl = [] # to store simplified transformations for transf in x2_to_x1: try: transf = self._chart2.simplify(transf) @@ -3567,15 +3718,18 @@ def inverse(self): if self._chart1.valid_coordinates(*x2_to_x1): list_x2_to_x1.append(x2_to_x1) if len(list_x2_to_x1) == 0: - raise ValueError("no solution found; use set_inverse() to " + - "set the inverse manually") + raise ValueError( + "no solution found; use set_inverse() to " + + "set the inverse manually" + ) if len(list_x2_to_x1) > 1: print("Multiple solutions found: ") print(list_x2_to_x1) raise ValueError( - "non-unique solution to the inverse coordinate " + - "transformation; use set_inverse() to set the inverse " + - "manually") + "non-unique solution to the inverse coordinate " + + "transformation; use set_inverse() to set the inverse " + + "manually" + ) x2_to_x1 = list_x2_to_x1[0] self._inverse = type(self)(self._chart2, self._chart1, *x2_to_x1) self._inverse._inverse = self @@ -3693,10 +3847,8 @@ def set_inverse(self, *transformations, **kwds): check = kwds.pop('check', True) verbose = kwds.pop('verbose', False) for unknown_key in kwds: - raise TypeError("{} is not a valid keyword " - "argument".format(unknown_key)) - self._inverse = type(self)(self._chart2, self._chart1, - *transformations) + raise TypeError("{} is not a valid keyword " "argument".format(unknown_key)) + self._inverse = type(self)(self._chart2, self._chart1, *transformations) self._inverse._inverse = self if check: infos = ["Check of the inverse coordinate transformation:"] @@ -3722,8 +3874,9 @@ def set_inverse(self, *transformations, **kwds): any_failure = True infos.append(" {} {}".format(eq, resu)) if any_failure: - infos.append("NB: a failed report can reflect a mere lack of " - "simplification.") + infos.append( + "NB: a failed report can reflect a mere lack of " "simplification." + ) if verbose or any_failure: for li in infos: print(li) @@ -3759,9 +3912,10 @@ def __mul__(self, other): if not isinstance(other, CoordChange): raise TypeError("{} is not a change of coordinate".format(other)) if other._chart2 != self._chart1: - raise ValueError("composition not possible: " + - "{} is different from {}".format(other._chart2, - other._chart1)) + raise ValueError( + "composition not possible: " + + "{} is different from {}".format(other._chart2, other._chart1) + ) transf = self._transf(*(other._transf.expr())) return type(self)(other._chart1, self._chart2, *transf) @@ -3804,8 +3958,11 @@ def restrict(self, dom1, dom2=None): ch2 = self._chart2.restrict(dom2) if (ch1, ch2) in dom1.coord_changes(): return dom1.coord_changes()[(ch1, ch2)] - return type(self)(self._chart1.restrict(dom1), - self._chart2.restrict(dom2), *(self._transf.expr())) + return type(self)( + self._chart1.restrict(dom1), + self._chart2.restrict(dom2), + *(self._transf.expr()), + ) def display(self): r""" @@ -3838,6 +3995,7 @@ def display(self): """ from sage.misc.latex import latex from sage.tensor.modules.format_utilities import FormattedExpansion + coords2 = self._chart2[:] n2 = len(coords2) expr = self._transf.expr('SR') diff --git a/src/sage/manifolds/chart_func.py b/src/sage/manifolds/chart_func.py index 77006d5459a..30adb1e18c9 100644 --- a/src/sage/manifolds/chart_func.py +++ b/src/sage/manifolds/chart_func.py @@ -23,6 +23,7 @@ - Florentin Jaffredo (2018) : series expansion with respect to a given parameter """ + # **************************************************************************** # Copyright (C) 2017 Marco Mancini # Copyright (C) 2018 Florentin Jaffredo @@ -327,8 +328,14 @@ class ChartFunction(AlgebraElement, ModuleElementWithMutability): .. automethod:: __call__ """ - def __init__(self, parent, expression=None, calc_method=None, - expansion_symbol=None, order=None): + def __init__( + self, + parent, + expression=None, + calc_method=None, + expansion_symbol=None, + order=None, + ): r""" Initialize ``self``. @@ -370,10 +377,11 @@ def __init__(self, parent, expression=None, calc_method=None, if calc_method is None: calc_method = self._calc_method._current self._express[calc_method] = self._calc_method._tranf[calc_method]( - expression) + expression + ) # Derived quantities: self._der = None # list of partial derivatives (to be set by diff() - # and unset by del_derived()) + # and unset by del_derived()) self._expansion_symbol = expansion_symbol self._order = order @@ -399,9 +407,8 @@ def _simplify(self, expr): 2*x """ res = self._calc_method.simplify(expr) - if (self._expansion_symbol is not None and - self._calc_method._current == 'SR'): - res = res.series(self._expansion_symbol, self._order+1).truncate() + if self._expansion_symbol is not None and self._calc_method._current == 'SR': + res = res.series(self._expansion_symbol, self._order + 1).truncate() return res def chart(self): @@ -454,9 +461,9 @@ def scalar_field(self, name=None, latex_name=None): True """ alg = self._chart.domain().scalar_field_algebra() - return alg.element_class(alg, - coord_expression={self._chart: self}, - name=name, latex_name=latex_name) + return alg.element_class( + alg, coord_expression={self._chart: self}, name=name, latex_name=latex_name + ) def expr(self, method=None): r""" @@ -553,8 +560,7 @@ def expr(self, method=None): return self._express[method] except (KeyError, ValueError): pass - raise ValueError("no expression found for converting to {}".format( - method)) + raise ValueError("no expression found for converting to {}".format(method)) def set_expr(self, calc_method, expression): r""" @@ -588,11 +594,14 @@ def set_expr(self, calc_method, expression): ValueError: Expressions are not equal """ if self.is_immutable(): - raise ValueError("the expressions of an immutable element cannot " - "be changed") + raise ValueError( + "the expressions of an immutable element cannot " "be changed" + ) for vv in self._express.values(): - if not bool(self._calc_method._tranf[calc_method](expression) == - self._calc_method._tranf[calc_method](vv)): + if not bool( + self._calc_method._tranf[calc_method](expression) + == self._calc_method._tranf[calc_method](vv) + ): raise ValueError("Expressions are not equal") self._express[calc_method] = expression @@ -613,8 +622,7 @@ def _repr_(self): x*y + 1 """ curr = self._calc_method._current - if (curr == 'SR' and - self._chart.manifold().options.textbook_output): + if curr == 'SR' and self._chart.manifold().options.textbook_output: return str(ExpressionNice(self.expr(curr))) else: return str(self.expr(curr)) @@ -634,8 +642,7 @@ def _latex_(self): \cos\left(\frac{1}{2} \, x y\right) """ curr = self._calc_method._current - if (curr == 'SR' and - self._chart.manifold().options.textbook_output): + if curr == 'SR' and self._chart.manifold().options.textbook_output: out_expr = ExpressionNice(self._express[curr]) else: out_expr = self._express[curr] @@ -673,15 +680,14 @@ def display(self): """ 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 - self._chart.manifold().options.textbook_output): + if curr == 'SR' and self._chart.manifold().options.textbook_output: expr = ExpressionNice(expr) latex_func = self._calc_method._latex_dict[curr] resu_txt = str(self._chart[:]) + ' ' + unicode_mapsto + ' ' + str(expr) - resu_latex = latex_func(self._chart[:]) + r' \mapsto ' \ - + latex_func(expr) + resu_latex = latex_func(self._chart[:]) + r' \mapsto ' + latex_func(expr) return FormattedExpansion(resu_txt, resu_latex) disp = display @@ -1026,20 +1032,28 @@ def derivative(self, coord): """ from sage.calculus.functional import diff from sage.rings.integer import Integer + if self._der is None: # the list of partial derivatives has to be updated curr = self._calc_method._current if curr == 'SR': - self._der = [type(self)(self.parent(), - self._simplify(diff(self.expr(), xx)), - expansion_symbol=self._expansion_symbol, - order=self._order) - for xx in self._chart[:]] + self._der = [ + type(self)( + self.parent(), + self._simplify(diff(self.expr(), xx)), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) + for xx in self._chart[:] + ] elif curr == 'sympy': - self._der = [type(self)(self.parent(), - self._simplify(sympy.diff(self.expr(), - xx._sympy_()))) - for xx in self._chart[:]] + self._der = [ + type(self)( + self.parent(), + self._simplify(sympy.diff(self.expr(), xx._sympy_())), + ) + for xx in self._chart[:] + ] if isinstance(coord, (int, Integer)): # NB: for efficiency, we access directly to the "private" attributes # of other classes. A more conventional OOP writing would be @@ -1106,8 +1120,9 @@ def __eq__(self, other): method = list(self._express)[0] # pick a random method # other.expr(method) if method == 'sympy': - return bool(sympy.simplify(other.expr(method) - - self.expr(method)) == 0) + return bool( + sympy.simplify(other.expr(method) - self.expr(method)) == 0 + ) return bool(other.expr(method) == self.expr(method)) else: return bool(self.expr(self._calc_method._current) == other) @@ -1161,7 +1176,7 @@ def __neg__(self): """ curr = self._calc_method._current resu = type(self)(self.parent()) - resu._express[curr] = self._simplify(- self.expr()) + resu._express[curr] = self._simplify(-self.expr()) resu._order = self._order resu._expansion_symbol = self._expansion_symbol return resu @@ -1209,16 +1224,21 @@ def __invert__(self): """ curr = self._calc_method._current if curr == 'SR': - return type(self)(self.parent(), - calc_method='SR', - expression=self._simplify(SR.one() / self.expr())) + return type(self)( + self.parent(), + calc_method='SR', + expression=self._simplify(SR.one() / self.expr()), + ) # NB: self._express.__invert__() would return 1/self._express # (cf. the code of __invert__ in src/sage/symbolic/expression.pyx) # Here we prefer SR(1)/self._express - return type(self)(self.parent(), - calc_method=curr, - expression=self._simplify(1 / self.expr()), - expansion_symbol=self._expansion_symbol, order=self._order) + return type(self)( + self.parent(), + calc_method=curr, + expression=self._simplify(1 / self.expr()), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def _add_(self, other): r""" @@ -1286,13 +1306,19 @@ def _add_(self, other): # NB: "if res == 0" would be too expensive (cf. #22859) return self.parent().zero() if other._expansion_symbol is not None: - return type(self)(self.parent(), res, - expansion_symbol=other._expansion_symbol, - order=other._order) + return type(self)( + self.parent(), + res, + expansion_symbol=other._expansion_symbol, + order=other._order, + ) else: - return type(self)(self.parent(), res, - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + res, + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def _sub_(self, other): r""" @@ -1351,13 +1377,19 @@ def _sub_(self, other): # NB: "if res == 0" would be too expensive (cf. #22859) return self.parent().zero() if other._expansion_symbol is not None: - return type(self)(self.parent(), res, - expansion_symbol=other._expansion_symbol, - order=other._order) + return type(self)( + self.parent(), + res, + expansion_symbol=other._expansion_symbol, + order=other._order, + ) else: - return type(self)(self.parent(), res, - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + res, + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def _mul_(self, other): r""" @@ -1412,13 +1444,19 @@ def _mul_(self, other): # NB: "if res == 0" would be too expensive (cf. #22859) return self.parent().zero() if other._expansion_symbol is not None: - return type(self)(self.parent(), res, - expansion_symbol=other._expansion_symbol, - order=other._order) + return type(self)( + self.parent(), + res, + expansion_symbol=other._expansion_symbol, + order=other._order, + ) else: - return type(self)(self.parent(), res, - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + res, + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def _rmul_(self, other): """ @@ -1451,9 +1489,12 @@ def _rmul_(self, other): other = self._calc_method._tranf[curr](other) except (TypeError, ValueError): return - return type(self)(self.parent(), other * self.expr(), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + other * self.expr(), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def _lmul_(self, other): """ @@ -1486,9 +1527,12 @@ def _lmul_(self, other): other = self._calc_method._tranf[curr](other) except (TypeError, ValueError): return - return type(self)(self.parent(), self.expr() * other, - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self.expr() * other, + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def _div_(self, other): r""" @@ -1547,9 +1591,12 @@ def _div_(self, other): if curr == 'SR' and res.is_trivial_zero(): # NB: "if res == 0" would be too expensive (cf. #22859) return self.parent().zero() - return type(self)(self.parent(), res, - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + res, + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def exp(self): r""" @@ -1592,9 +1639,12 @@ def exp(self): val = self.expr().exp() elif curr == 'sympy': val = sympy.exp(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def log(self, base=None): r""" @@ -1645,10 +1695,15 @@ def log(self, base=None): if curr == 'SR': val = self.expr().log(base) elif curr == 'sympy': - val = sympy.log(self.expr()) if base is None else sympy.log(self.expr(), base) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + val = ( + sympy.log(self.expr()) if base is None else sympy.log(self.expr(), base) + ) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def __pow__(self, exponent): r""" @@ -1703,9 +1758,12 @@ def __pow__(self, exponent): val = pow(self.expr(), exponent) elif curr == 'sympy': val = self.expr() ** exponent - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def sqrt(self): r""" @@ -1735,9 +1793,12 @@ def sqrt(self): val = self.expr().sqrt() elif curr == 'sympy': val = sympy.sqrt(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def cos(self): r""" @@ -1775,9 +1836,12 @@ def cos(self): val = self.expr().cos() elif curr == 'sympy': val = sympy.cos(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def sin(self): r""" @@ -1820,9 +1884,12 @@ def sin(self): val = self.expr().sin() elif curr == 'sympy': val = sympy.sin(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def tan(self): r""" @@ -1863,9 +1930,12 @@ def tan(self): val = self.expr().tan() elif curr == 'sympy': val = sympy.tan(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def arccos(self): r""" @@ -1910,9 +1980,12 @@ def arccos(self): val = self.expr().arccos() elif curr == 'sympy': val = sympy.acos(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def arcsin(self): r""" @@ -1954,9 +2027,12 @@ def arcsin(self): val = self.expr().arcsin() elif curr == 'sympy': val = sympy.asin(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def arctan(self): r""" @@ -1998,9 +2074,12 @@ def arctan(self): val = self.expr().arctan() elif curr == 'sympy': val = sympy.atan(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def cosh(self): r""" @@ -2038,9 +2117,12 @@ def cosh(self): val = self.expr().cosh() elif curr == 'sympy': val = sympy.cosh(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def sinh(self): r""" @@ -2078,9 +2160,12 @@ def sinh(self): val = self.expr().sinh() elif curr == 'sympy': val = sympy.sinh(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def tanh(self): r""" @@ -2118,9 +2203,12 @@ def tanh(self): val = self.expr().tanh() elif curr == 'sympy': val = sympy.tanh(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def arccosh(self): r""" @@ -2162,9 +2250,12 @@ def arccosh(self): val = self.expr().arccosh() elif curr == 'sympy': val = sympy.acosh(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def arcsinh(self): r""" @@ -2206,9 +2297,12 @@ def arcsinh(self): val = self.expr().arcsinh() elif curr == 'sympy': val = sympy.asinh(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def arctanh(self): r""" @@ -2250,9 +2344,12 @@ def arctanh(self): val = self.expr().arctanh() elif curr == 'sympy': val = sympy.atanh(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def __abs__(self): r""" @@ -2290,9 +2387,12 @@ def __abs__(self): val = self.expr().abs() elif curr == 'sympy': val = abs(self.expr()) - return type(self)(self.parent(), self._simplify(val), - expansion_symbol=self._expansion_symbol, - order=self._order) + return type(self)( + self.parent(), + self._simplify(val), + expansion_symbol=self._expansion_symbol, + order=self._order, + ) def _del_derived(self): r""" @@ -2652,6 +2752,7 @@ class ChartFunctionRing(Parent, UniqueRepresentation): sage: FR_Y.has_coerce_map_from(FR_X) False """ + Element = ChartFunction def __init__(self, chart): @@ -2895,6 +2996,7 @@ class MultiCoordFunction(SageObject, Mutability): sage: g(1,2) (4,) """ + def __init__(self, chart, expressions): r""" Initialize ``self``. @@ -2910,10 +3012,9 @@ def __init__(self, chart, expressions): sage: TestSuite(f).run() """ self._chart = chart - self._nc = len(self._chart._xx) # number of coordinates - self._nf = len(expressions) # number of functions - self._functions = tuple(chart.function(express) - for express in expressions) + self._nc = len(self._chart._xx) # number of coordinates + self._nf = len(expressions) # number of functions + self._functions = tuple(chart.function(express) for express in expressions) Mutability.__init__(self) def _repr_(self): @@ -2930,8 +3031,7 @@ def _repr_(self): sage: f Coordinate functions (x - y, x*y, cos(x)*e^y) on the Chart (M, (x, y)) """ - return "Coordinate functions {} on the {}".format(self._functions, - self._chart) + return "Coordinate functions {} on the {}".format(self._functions, self._chart) def _latex_(self): r""" @@ -2948,6 +3048,7 @@ def _latex_(self): \left(x - y, x y, \cos\left(x\right) e^{y}\right) """ from sage.misc.latex import latex + return latex(self._functions) def expr(self, method=None): @@ -3048,8 +3149,7 @@ def __eq__(self, other): return False if other._nf != self._nf: return False - return all(other._functions[i] == self._functions[i] - for i in range(self._nf)) + return all(other._functions[i] == self._functions[i] for i in range(self._nf)) def __ne__(self, other): r""" @@ -3191,8 +3291,10 @@ def jacobian(self): [[True, True], [True, True], [True, True]] """ from sage.matrix.constructor import matrix - mat = matrix([[func.diff(coord) for coord in self._chart[:]] - for func in self._functions]) + + mat = matrix( + [[func.diff(coord) for coord in self._chart[:]] for func in self._functions] + ) mat.set_immutable() return mat @@ -3262,16 +3364,24 @@ def jacobian_det(self): True """ from sage.matrix.constructor import matrix + if self._nf != self._nc: raise ValueError("the Jacobian matrix is not a square matrix") mat = self.jacobian() # TODO: do the computation without the 'SR' enforcement - mat_expr = matrix([[mat[i,j].expr(method='SR') for i in range(self._nc)] - for j in range(self._nc)]) + mat_expr = matrix( + [ + [mat[i, j].expr(method='SR') for i in range(self._nc)] + for j in range(self._nc) + ] + ) det = mat_expr.det() # the unsimplified determinant func = self._functions[0] - return type(func)(func.parent(), func._calc_method.simplify(det, method='SR'), - calc_method=self._chart._calc_method._current) + return type(func)( + func.parent(), + func._calc_method.simplify(det, method='SR'), + calc_method=self._chart._calc_method._current, + ) def set_immutable(self): r""" diff --git a/src/sage/manifolds/continuous_map.py b/src/sage/manifolds/continuous_map.py index d8158deb1ce..22f44b5d430 100644 --- a/src/sage/manifolds/continuous_map.py +++ b/src/sage/manifolds/continuous_map.py @@ -343,8 +343,16 @@ class ContinuousMap(Morphism): sage: ~id is id True """ - def __init__(self, parent, coord_functions=None, name=None, latex_name=None, - is_isomorphism=False, is_identity=False): + + def __init__( + self, + parent, + coord_functions=None, + name=None, + latex_name=None, + is_isomorphism=False, + is_identity=False, + ): r""" Initialize ``self``. @@ -376,10 +384,11 @@ def __init__(self, parent, coord_functions=None, name=None, latex_name=None, codomain = parent.codomain() self._domain = domain self._codomain = codomain - self._coord_expression = {} # dict. of coordinate expressions of the - # map: - # - key: pair of charts - # - value: instance of MultiCoordFunction + # dict. of coordinate expressions of the + # map: + # - key: pair of charts + # - value: instance of MultiCoordFunction + self._coord_expression = {} self._is_isomorphism = False # default value; may be redefined below self._is_identity = False # default value; may be redefined below if is_identity: @@ -387,8 +396,9 @@ def __init__(self, parent, coord_functions=None, name=None, latex_name=None, self._is_identity = True self._is_isomorphism = True if domain != codomain: - raise ValueError("the domain and codomain must coincide" - " for the identity map") + raise ValueError( + "the domain and codomain must coincide" " for the identity map" + ) if name is None: name = 'Id_' + domain._name if latex_name is None: @@ -398,35 +408,42 @@ def __init__(self, parent, coord_functions=None, name=None, latex_name=None, for chart in domain.atlas(): coord_funct = chart[:] self._coord_expression[(chart, chart)] = chart.multifunction( - *coord_funct) + *coord_funct + ) else: # Construction of a generic continuous map if is_isomorphism: self._is_isomorphism = True if domain.dim() != codomain.dim(): - raise ValueError("for an isomorphism, the source" - " manifold and target manifold must" - " have the same dimension") + raise ValueError( + "for an isomorphism, the source" + " manifold and target manifold must" + " have the same dimension" + ) if coord_functions is not None: n2 = self._codomain.dim() for chart_pair, expression in coord_functions.items(): if chart_pair[0] not in self._domain.atlas(): - raise ValueError("{} is not a chart ".format( - chart_pair[0]) + - "defined on the {}".format(self._domain)) + raise ValueError( + "{} is not a chart ".format(chart_pair[0]) + + "defined on the {}".format(self._domain) + ) if chart_pair[1] not in self._codomain.atlas(): - raise ValueError("{} is not a chart ".format( - chart_pair[1]) + - "defined on the {}".format(self._codomain)) + raise ValueError( + "{} is not a chart ".format(chart_pair[1]) + + "defined on the {}".format(self._codomain) + ) if n2 == 1: # a single expression entry is allowed if not isinstance(expression, (tuple, list)): expression = (expression,) if len(expression) != n2: - raise ValueError("{} coordinate ".format(n2) + - "functions must be provided") - self._coord_expression[chart_pair] = \ - chart_pair[0].multifunction(*expression) + raise ValueError( + "{} coordinate ".format(n2) + "functions must be provided" + ) + self._coord_expression[chart_pair] = chart_pair[0].multifunction( + *expression + ) self._name = name if latex_name is None: self._latex_name = self._name @@ -481,8 +498,7 @@ def _repr_(self): else: description += " from the {} to itself".format(self._domain) else: - description += " from the {} to the {}".format(self._domain, - self._codomain) + description += " from the {} to the {}".format(self._domain, self._codomain) return description def _latex_(self): @@ -675,8 +691,10 @@ def _call_(self, point): if chart1 is not None: break else: - raise ValueError("no pair of charts has been found to " + - "compute the action of the {} on the {}".format(self, point)) + raise ValueError( + "no pair of charts has been found to " + + "compute the action of the {} on the {}".format(self, point) + ) coord_map = self._coord_expression[(chart1, chart2)] y = coord_map(*(point._coordinates[chart1])) if point._name is None or self._name is None: @@ -686,13 +704,20 @@ def _call_(self, point): if point._latex_name is None or self._latex_name is None: res_latex_name = None else: - res_latex_name = (self._latex_name + r'\left(' + - point._latex_name + r'\right)') + res_latex_name = ( + self._latex_name + r'\left(' + point._latex_name + r'\right)' + ) # The image point is created as an element of the domain of chart2: dom2 = chart2.domain() - return dom2.element_class(dom2, coords=y, chart=chart2, - name=res_name, latex_name=res_latex_name, - check_coords=False) + return dom2.element_class( + dom2, + coords=y, + chart=chart2, + name=res_name, + latex_name=res_latex_name, + check_coords=False, + ) + # # Morphism methods # @@ -799,8 +824,9 @@ def _composition_(self, other, homset): for chart3 in self._codomain._top_charts: try: self23 = self.coord_functions(chart2, chart3) - resu_funct[(chart1, chart3)] = self23(*other.expr(chart1, chart2), - simplify=True) + resu_funct[(chart1, chart3)] = self23( + *other.expr(chart1, chart2), simplify=True + ) except ValueError: pass return homset(resu_funct) @@ -844,6 +870,7 @@ def image(self, subset=None, inverse=None): True """ from sage.manifolds.continuous_map_image import ImageManifoldSubset + if self._is_identity: if subset is None: return self.domain() @@ -917,8 +944,10 @@ def preimage(self, codomain_subset, name=None, latex_name=None): if self._codomain.is_subset(codomain_subset): return self._domain from sage.manifolds.subsets.pullback import ManifoldSubsetPullback - return ManifoldSubsetPullback(self, codomain_subset, - name=name, latex_name=latex_name) + + return ManifoldSubsetPullback( + self, codomain_subset, name=name, latex_name=latex_name + ) pullback = preimage @@ -1002,8 +1031,8 @@ def _init_derived(self): [ 1 0] [ 0 1/2] """ - self._restrictions = {} # dict. of restrictions to subdomains of - # self._domain + # dict. of restrictions to subdomains of self._domain + self._restrictions = {} self._restrictions_graph = {(self._domain, self._codomain): self} # dict. of known extensions of self on bigger domains, # including self, with pairs of domain codomain as keys. @@ -1194,33 +1223,43 @@ def _display_expression(self, chart1, chart2, result): result._latex += ' & ' else: result._txt += 'on ' + chart1._domain._name + ': ' - result._latex += r'\text{on}\ ' + latex(chart1._domain) + \ - r': & ' + result._latex += r'\text{on}\ ' + latex(chart1._domain) + r': & ' result._txt += repr(coords1) + ' ' + unicode_mapsto + ' ' result._latex += latex(coords1) + r'& \longmapsto & ' if chart2 == chart1: result._txt += repr(expression) + '\n' result._latex += latex(coord_func) + r'\\' else: - result._txt += repr(coords2) + ' = ' + \ - repr(expression) + '\n' - result._latex += latex(coords2) + ' = ' + \ - latex(coord_func) + r'\\' + result._txt += repr(coords2) + ' = ' + repr(expression) + '\n' + result._latex += latex(coords2) + ' = ' + latex(coord_func) + r'\\' result = FormattedExpansion() if self._name is None: symbol = '' else: symbol = self._name + ': ' - result._txt = symbol + self._domain._name + ' ' + unicode_to + ' ' \ - + self._codomain._name + '\n' + result._txt = ( + symbol + + self._domain._name + + ' ' + + unicode_to + + ' ' + + self._codomain._name + + '\n' + ) if self._latex_name is None: symbol = '' else: symbol = self._latex_name + ':' - result._latex = r'\begin{array}{llcl} ' + symbol + r'&' + \ - latex(self._domain) + r'& \longrightarrow & ' + \ - latex(self._codomain) + r'\\' + result._latex = ( + r'\begin{array}{llcl} ' + + symbol + + r'&' + + latex(self._domain) + + r'& \longrightarrow & ' + + latex(self._codomain) + + r'\\' + ) if chart1 is None: if chart2 is None: for ch1 in self._domain._top_charts: @@ -1357,31 +1396,35 @@ def coord_functions(self, chart1=None, chart2=None): if (chart1, chart2) not in self._coord_expression: # Check whether (chart1, chart2) are (subchart, superchart) of # a pair of charts where the expression of self is known: - for (ochart1, ochart2) in self._coord_expression: + for ochart1, ochart2 in self._coord_expression: if chart1 in ochart1._subcharts and ochart2 in chart2._subcharts: coord_functions = self._coord_expression[(ochart1, ochart2)].expr() - self._coord_expression[(chart1, chart2)] = \ - chart1.multifunction(*coord_functions) + self._coord_expression[(chart1, chart2)] = chart1.multifunction( + *coord_functions + ) return self._coord_expression[(chart1, chart2)] # Special case of the identity in a single chart: if self._is_identity and chart1 == chart2: coord_functions = chart1[:] - self._coord_expression[(chart1, chart1)] = \ - chart1.multifunction(*coord_functions) + self._coord_expression[(chart1, chart1)] = chart1.multifunction( + *coord_functions + ) return self._coord_expression[(chart1, chart2)] # Some change of coordinates must be performed change_start = [] change_arrival = [] - for (ochart1, ochart2) in self._coord_expression: + for ochart1, ochart2 in self._coord_expression: if chart1 == ochart1: change_arrival.append(ochart2) if chart2 == ochart2: change_start.append(ochart1) # 1/ Trying to make a change of chart only on the codomain: # the codomain's default chart is privileged: - sel_chart2 = None # selected chart2 - if (def_chart2 in change_arrival - and (def_chart2, chart2) in dom2._coord_changes): + sel_chart2 = None # selected chart2 + if ( + def_chart2 in change_arrival + and (def_chart2, chart2) in dom2._coord_changes + ): sel_chart2 = def_chart2 else: for ochart2 in change_arrival: @@ -1391,15 +1434,18 @@ def coord_functions(self, chart1=None, chart2=None): if sel_chart2 is not None: oexpr = self._coord_expression[(chart1, sel_chart2)] chg2 = dom2._coord_changes[(sel_chart2, chart2)] - self._coord_expression[(chart1, chart2)] = \ - chart1.multifunction( *chg2(*oexpr.expr()) ) + self._coord_expression[(chart1, chart2)] = chart1.multifunction( + *chg2(*oexpr.expr()) + ) return self._coord_expression[(chart1, chart2)] # 2/ Trying to make a change of chart only on the start domain: # the domain's default chart is privileged: - sel_chart1 = None # selected chart1 - if (def_chart1 in change_start - and (chart1, def_chart1) in dom1._coord_changes): + sel_chart1 = None # selected chart1 + if ( + def_chart1 in change_start + and (chart1, def_chart1) in dom1._coord_changes + ): sel_chart1 = def_chart1 else: for ochart1 in change_start: @@ -1409,22 +1455,27 @@ def coord_functions(self, chart1=None, chart2=None): if sel_chart1 is not None: oexpr = self._coord_expression[(sel_chart1, chart2)] chg1 = dom1._coord_changes[(chart1, sel_chart1)] - self._coord_expression[(chart1, chart2)] = \ - chart1.multifunction( *oexpr(*chg1._transf.expr()) ) + self._coord_expression[(chart1, chart2)] = chart1.multifunction( + *oexpr(*chg1._transf.expr()) + ) return self._coord_expression[(chart1, chart2)] # 3/ If this point is reached, it is necessary to perform some # coordinate change both on the start domain and the arrival one # the default charts are privileged: - if ((def_chart1, def_chart2) in self._coord_expression - and (chart1, def_chart1) in dom1._coord_changes - and (def_chart2, chart2) in dom2._coord_changes): + if ( + (def_chart1, def_chart2) in self._coord_expression + and (chart1, def_chart1) in dom1._coord_changes + and (def_chart2, chart2) in dom2._coord_changes + ): sel_chart1 = def_chart1 sel_chart2 = def_chart2 else: - for (ochart1, ochart2) in self._coord_expression: - if ((chart1, ochart1) in dom1._coord_changes - and (ochart2, chart2) in dom2._coord_changes): + for ochart1, ochart2 in self._coord_expression: + if (chart1, ochart1) in dom1._coord_changes and ( + ochart2, + chart2, + ) in dom2._coord_changes: sel_chart1 = ochart1 sel_chart2 = ochart2 break @@ -1433,14 +1484,18 @@ def coord_functions(self, chart1=None, chart2=None): chg1 = dom1._coord_changes[(chart1, sel_chart1)] chg2 = dom2._coord_changes[(sel_chart2, chart2)] self._coord_expression[(chart1, chart2)] = chart1.multifunction( - *chg2( *oexpr(*chg1._transf.expr()) ) ) + *chg2(*oexpr(*chg1._transf.expr())) + ) return self._coord_expression[(chart1, chart2)] # 4/ If this point is reached, the demanded value cannot be # computed - raise ValueError("the expression of the map in the pair " + - "({}, {})".format(chart1, chart2) + " cannot " + - "be computed by means of known changes of charts") + raise ValueError( + "the expression of the map in the pair " + + "({}, {})".format(chart1, chart2) + + " cannot " + + "be computed by means of known changes of charts" + ) return self._coord_expression[(chart1, chart2)] @@ -1638,27 +1693,36 @@ def set_expr(self, chart1, chart2, coord_functions): True """ if self._is_identity: - raise NotImplementedError("set_expr() must not be used for the identity map") + raise NotImplementedError( + "set_expr() must not be used for the identity map" + ) if chart1 not in self._domain.atlas(): - raise ValueError("the {}".format(chart1) + - " has not been defined on the {}".format(self._domain)) + raise ValueError( + "the {}".format(chart1) + + " has not been defined on the {}".format(self._domain) + ) if chart2 not in self._codomain.atlas(): - raise ValueError("the {}".format(chart2) + - " has not been defined on the {}".format(self._codomain)) + raise ValueError( + "the {}".format(chart2) + + " has not been defined on the {}".format(self._codomain) + ) self._coord_expression.clear() self._del_derived() n2 = self._codomain.dim() if n2 > 1: if len(coord_functions) != n2: - raise ValueError("{} coordinate functions must ".format(n2) + - "be provided.") - self._coord_expression[(chart1, chart2)] = \ - chart1.multifunction(*coord_functions) + raise ValueError( + "{} coordinate functions must ".format(n2) + "be provided." + ) + self._coord_expression[(chart1, chart2)] = chart1.multifunction( + *coord_functions + ) else: if isinstance(coord_functions, (list, tuple)): coord_functions = coord_functions[0] - self._coord_expression[(chart1, chart2)] = \ - chart1.multifunction(coord_functions) + self._coord_expression[(chart1, chart2)] = chart1.multifunction( + coord_functions + ) set_expression = set_expr @@ -1775,23 +1839,33 @@ def add_expr(self, chart1, chart2, coord_functions): True """ if self._is_identity: - raise NotImplementedError("add_expr() must not be used for the identity map") + raise NotImplementedError( + "add_expr() must not be used for the identity map" + ) if chart1 not in self._domain.atlas(): - raise ValueError("the {}".format(chart1) + - " has not been defined on the {}".format(self._domain)) + raise ValueError( + "the {}".format(chart1) + + " has not been defined on the {}".format(self._domain) + ) if chart2 not in self._codomain.atlas(): - raise ValueError("the {}".format(chart2) + - " has not been defined on the {}".format(self._codomain)) + raise ValueError( + "the {}".format(chart2) + + " has not been defined on the {}".format(self._codomain) + ) self._del_derived() n2 = self._codomain.dim() if n2 > 1: if len(coord_functions) != n2: raise ValueError("{} coordinate functions must be provided".format(n2)) - self._coord_expression[(chart1, chart2)] = chart1.multifunction(*coord_functions) + self._coord_expression[(chart1, chart2)] = chart1.multifunction( + *coord_functions + ) else: if isinstance(coord_functions, (list, tuple)): coord_functions = coord_functions[0] - self._coord_expression[(chart1, chart2)] = chart1.multifunction(coord_functions) + self._coord_expression[(chart1, chart2)] = chart1.multifunction( + coord_functions + ) add_expression = add_expr @@ -1879,12 +1953,16 @@ def restrict(self, subdomain, subcodomain=None): return self if (subdomain, subcodomain) not in self._restrictions: if not subdomain.is_subset(self._domain): - raise ValueError("the specified domain is not a subset" - " of the domain of definition of the" - " continuous map") + raise ValueError( + "the specified domain is not a subset" + " of the domain of definition of the" + " continuous map" + ) if not subcodomain.is_subset(self._codomain): - raise ValueError("the specified codomain is not a subset" - " of the codomain of the continuous map") + raise ValueError( + "the specified codomain is not a subset" + " of the codomain of the continuous map" + ) # Special case of the identity map: if self._is_identity: self._restrictions[(subdomain, subcodomain)] = subdomain.identity_map() @@ -1892,7 +1970,10 @@ def restrict(self, subdomain, subcodomain=None): # First one tries to get the restriction from a tighter domain: for dom, rst in self._restrictions.items(): - if subdomain.is_subset(dom[0]) and (subdomain, subcodomain) in rst._restrictions: + if ( + subdomain.is_subset(dom[0]) + and (subdomain, subcodomain) in rst._restrictions + ): res = rst._restrictions[(subdomain, subcodomain)] self._restrictions[(subdomain, subcodomain)] = res self._restrictions.update(res._restrictions) @@ -1907,18 +1988,18 @@ def restrict(self, subdomain, subcodomain=None): # Maybe it didn't exist but could have: for dom, rst in self._restrictions.items(): if subdomain.is_subset(dom[0]) and subcodomain.is_subset(dom[1]): - res = rst.restrict(subdomain,subcodomain) # all propagation - # is done here + res = rst.restrict(subdomain, subcodomain) # all propagation + # is done here # should be useless: - self._restrictions[(subdomain,subcodomain)] = res + self._restrictions[(subdomain, subcodomain)] = res self._restrictions_graph[(subdomain, subcodomain)] = res - return self._restrictions[(subdomain,subcodomain)] + return self._restrictions[(subdomain, subcodomain)] # Secondly one tries to get the restriction from one previously # defined on a larger domain: for dom, ext in self._extensions_graph.items(): - if (subdomain,subcodomain) in ext._restrictions: - res = ext._restrictions[(subdomain,subcodomain)] + if (subdomain, subcodomain) in ext._restrictions: + res = ext._restrictions[(subdomain, subcodomain)] self._restrictions[(subdomain, subcodomain)] = res self._restrictions.update(res._restrictions) self._restrictions_graph.update(res._restrictions_graph) @@ -1931,8 +2012,7 @@ def restrict(self, subdomain, subcodomain=None): # Generic case: homset = Hom(subdomain, subcodomain) - resu = type(self)(homset, name=self._name, - latex_name=self._latex_name) + resu = type(self)(homset, name=self._name, latex_name=self._latex_name) for charts in self._coord_expression: for ch1 in charts[0]._subcharts: if ch1._domain.is_subset(subdomain): @@ -1945,12 +2025,15 @@ def restrict(self, subdomain, subcodomain=None): for sch2 in ch2._subcharts: if (ch1, sch2) in resu._coord_expression: del resu._coord_expression[(ch1, sch2)] - coord_functions = self._coord_expression[charts].expr() - resu._coord_expression[(ch1, ch2)] = \ - ch1.multifunction(*coord_functions) + coord_functions = self._coord_expression[ + charts + ].expr() + resu._coord_expression[(ch1, ch2)] = ( + ch1.multifunction(*coord_functions) + ) # propagate extensions - for dom, ext in self._extensions_graph.items(): # includes self + for dom, ext in self._extensions_graph.items(): # includes self ext._restrictions[(subdomain, subcodomain)] = resu ext._restrictions_graph[(subdomain, subcodomain)] = resu @@ -2047,20 +2130,20 @@ def __invert__(self): """ 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: raise ValueError("the {} is not an isomorphism".format(self)) - coord_functions = {} # coordinate expressions of the result - for (chart1, chart2) in self._coord_expression: + coord_functions = {} # coordinate expressions of the result + for chart1, chart2 in self._coord_expression: coord_map = self._coord_expression[(chart1, chart2)] n1 = len(chart1._xx) n2 = len(chart2._xx) # New symbolic variables (different from chart2._xx to allow for a # correct solution even when chart2 = chart1): x2 = SR.temp_var(n=n2) - equations = [x2[i] == coord_map._functions[i].expr() - for i in range(n2)] + equations = [x2[i] == coord_map._functions[i].expr() for i in range(n2)] solutions = solve(equations, chart1._xx, solution_dict=True) if not solutions: raise ValueError("no solution found") @@ -2068,8 +2151,7 @@ def __invert__(self): raise ValueError("non-unique solution found") substitutions = dict(zip(x2, chart2._xx)) sol = solutions[0] - inv_functions = [sol[chart1._xx[i]].subs(substitutions) - for i in range(n1)] + inv_functions = [sol[chart1._xx[i]].subs(substitutions) for i in range(n1)] for i in range(n1): x = inv_functions[i] try: @@ -2088,9 +2170,13 @@ def __invert__(self): else: latex_name = self._latex_name + r'^{-1}' homset = Hom(self._codomain, self._domain) - self._inverse = type(self)(homset, coord_functions=coord_functions, - name=name, latex_name=latex_name, - is_isomorphism=True) + self._inverse = type(self)( + homset, + coord_functions=coord_functions, + name=name, + latex_name=latex_name, + is_isomorphism=True, + ) return self._inverse inverse = __invert__ diff --git a/src/sage/manifolds/continuous_map_image.py b/src/sage/manifolds/continuous_map_image.py index bbcfa672a5a..78000be81ab 100644 --- a/src/sage/manifolds/continuous_map_image.py +++ b/src/sage/manifolds/continuous_map_image.py @@ -39,7 +39,9 @@ class ImageManifoldSubset(ManifoldSubset): ``map`` """ - def __init__(self, map, inverse=None, name=None, latex_name=None, domain_subset=None): + def __init__( + self, map, inverse=None, name=None, latex_name=None, domain_subset=None + ): r""" Construct a manifold subset that is the image of a continuous map. diff --git a/src/sage/manifolds/family.py b/src/sage/manifolds/family.py index e58faf0e885..8a544061843 100644 --- a/src/sage/manifolds/family.py +++ b/src/sage/manifolds/family.py @@ -15,7 +15,7 @@ - Matthias Koeppe (2021): initial version """ -#***************************************************************************** +# ***************************************************************************** # Copyright (C) 2021 Matthias Koeppe # # This program is free software: you can redistribute it and/or modify @@ -23,7 +23,7 @@ # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ -#***************************************************************************** +# ***************************************************************************** from functools import total_ordering @@ -32,7 +32,6 @@ @total_ordering class ManifoldObjectFiniteFamily(FiniteFamily): - r""" Finite family of manifold objects, indexed by their names. @@ -66,6 +65,7 @@ class ManifoldObjectFiniteFamily(FiniteFamily): ... TypeError: all objects must have the same manifold """ + def __init__(self, objects=(), keys=None): r""" Initialize a new instance of :class:`ManifoldObjectFiniteFamily`. @@ -98,8 +98,9 @@ def __init__(self, objects=(), keys=None): if keys is None: keys = sorted(dictionary.keys()) FiniteFamily.__init__(self, dictionary, keys) - names_and_latex_names = sorted((object._name, object._latex_name) - for object in self) + names_and_latex_names = sorted( + (object._name, object._latex_name) for object in self + ) self._name = '{' + ', '.join(keys) + '}' latex_names = (latex_name for name, latex_name in names_and_latex_names) self._latex_name = r'\{' + ', '.join(latex_names) + r'\}' @@ -110,7 +111,9 @@ def __init__(self, objects=(), keys=None): self._manifold = None else: if not all(object._manifold == self._manifold for object in object_iter): - raise TypeError(f'all {self._repr_object_type()} must have the same manifold') + raise TypeError( + f'all {self._repr_object_type()} must have the same manifold' + ) def _repr_object_type(self): r""" @@ -164,7 +167,9 @@ def __repr__(self): 'Set {A, B} of objects of the 2-dimensional topological manifold M' """ if self: - return "Set {} of {} of the {}".format(self._name, self._repr_object_type(), self._manifold) + return "Set {} of {} of the {}".format( + self._name, self._repr_object_type(), self._manifold + ) else: return "{}" @@ -185,7 +190,6 @@ def _latex_(self): class ManifoldSubsetFiniteFamily(ManifoldObjectFiniteFamily): - r""" Finite family of subsets of a topological manifold, indexed by their names. @@ -233,14 +237,17 @@ def from_subsets_or_families(cls, *subsets_or_families): sage: ManifoldSubsetFiniteFamily.from_subsets_or_families(A, Bs, Cs) Set {A, B0, B1, B2, B3, B4, C0, C1} of subsets of the 2-dimensional topological manifold M """ + def generate_subsets(): from sage.manifolds.subset import ManifoldSubset + for arg in subsets_or_families: if isinstance(arg, ManifoldSubset): yield arg else: # arg must be an iterable of ManifoldSubset instances yield from arg + return cls(generate_subsets()) def _repr_object_type(self): diff --git a/src/sage/manifolds/manifold_homset.py b/src/sage/manifolds/manifold_homset.py index 2b3c8564622..998b755ea6e 100644 --- a/src/sage/manifolds/manifold_homset.py +++ b/src/sage/manifolds/manifold_homset.py @@ -16,7 +16,7 @@ - [Lee2011]_ - [KN1963]_ """ -#****************************************************************************** +# ****************************************************************************** # Copyright (C) 2015 Eric Gourgoulhon # Copyright (C) 2016 Travis Scrimshaw # @@ -25,7 +25,7 @@ # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ -#***************************************************************************** +# ***************************************************************************** from sage.categories.homset import Homset from sage.manifolds.continuous_map import ContinuousMap @@ -173,12 +173,17 @@ def __init__(self, domain, codomain, name=None, latex_name=None): embedded in the Euclidean plane E^2 to the Euclidean plane E^2 """ from sage.manifolds.manifold import TopologicalManifold + if not isinstance(domain, TopologicalManifold): - raise TypeError("domain = {} is not an ".format(domain) + - "instance of TopologicalManifold") + raise TypeError( + "domain = {} is not an ".format(domain) + + "instance of TopologicalManifold" + ) if not isinstance(codomain, TopologicalManifold): - raise TypeError("codomain = {} is not an ".format(codomain) + - "instance of TopologicalManifold") + raise TypeError( + "codomain = {} is not an ".format(codomain) + + "instance of TopologicalManifold" + ) common_cat = domain.category()._meet_(codomain.category()) Homset.__init__(self, domain, codomain, category=common_cat) if name is None: @@ -187,7 +192,8 @@ def __init__(self, domain, codomain, name=None, latex_name=None): self._name = name if latex_name is None: self._latex_name = r"\mathrm{{Hom}}\left({},{}\right)".format( - domain._latex_name, codomain._latex_name) + domain._latex_name, codomain._latex_name + ) else: self._latex_name = latex_name @@ -211,8 +217,14 @@ def _latex_(self): #### Parent methods #### - def _element_constructor_(self, coord_functions, name=None, latex_name=None, - is_isomorphism=False, is_identity=False): + def _element_constructor_( + self, + coord_functions, + name=None, + latex_name=None, + is_isomorphism=False, + is_identity=False, + ): r""" Construct an element of the homset, i.e. a continuous map `M \to N`, where `M` is the domain of the homset and `N` its codomain. @@ -266,10 +278,14 @@ def _element_constructor_(self, coord_functions, name=None, latex_name=None, (x, y) ↦ (x, y) """ # Standard construction - return self.element_class(self, coord_functions=coord_functions, - name=name, latex_name=latex_name, - is_isomorphism=is_isomorphism, - is_identity=is_identity) + return self.element_class( + self, + coord_functions=coord_functions, + name=name, + latex_name=latex_name, + is_isomorphism=is_isomorphism, + is_identity=is_identity, + ) def _an_element_(self): r""" @@ -330,8 +346,9 @@ def _coerce_map_from_(self, other): True """ if isinstance(other, TopologicalManifoldHomset): - return (other.domain().has_coerce_map_from(self.domain()) - and self.codomain().has_coerce_map_from(other.codomain())) + return other.domain().has_coerce_map_from( + self.domain() + ) and self.codomain().has_coerce_map_from(other.codomain()) return False #!# check diff --git a/src/sage/manifolds/operators.py b/src/sage/manifolds/operators.py index eed5df22eb5..6fff6a3a654 100644 --- a/src/sage/manifolds/operators.py +++ b/src/sage/manifolds/operators.py @@ -33,7 +33,7 @@ - Eric Gourgoulhon (2018): initial version """ -#***************************************************************************** +# ***************************************************************************** # Copyright (C) 2018 Eric Gourgoulhon # # This program is free software: you can redistribute it and/or modify @@ -41,7 +41,7 @@ # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ -#***************************************************************************** +# ***************************************************************************** def grad(scalar): @@ -354,4 +354,5 @@ def dalembertian(field): """ return field.dalembertian() + # NB: norm() is already defined in src/sage/misc/functional.py From 75f2667dbc0a8e21c5bd9e7840557c443d025c10 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 9 Dec 2024 21:27:45 +0800 Subject: [PATCH 03/69] Apply suggestions from code review Co-authored-by: gmou3 <32706872+gmou3@users.noreply.github.com> --- src/sage/manifolds/catalog.py | 4 ++-- src/sage/manifolds/chart.py | 2 +- src/sage/manifolds/chart_func.py | 2 +- src/sage/manifolds/continuous_map.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/manifolds/catalog.py b/src/sage/manifolds/catalog.py index aa75ed115b8..af0d1a663ec 100644 --- a/src/sage/manifolds/catalog.py +++ b/src/sage/manifolds/catalog.py @@ -198,7 +198,7 @@ def Kerr(m=1, a=0, coordinates='BL', names=None): M._first_ngens = C._first_ngens g = M.metric('g') t, r, th, ph = C[:] - rho = sqrt(r**2 + a**2 * cos(th) ** 2) + rho = sqrt(r**2 + a**2 * cos(th)**2) g[0, 0], g[1, 1], g[2, 2], g[3, 3] = ( -(1 - 2 * m * r / rho**2), 1 + 2 * m * r / rho**2, @@ -240,7 +240,7 @@ def Kerr(m=1, a=0, coordinates='BL', names=None): return M raise NotImplementedError( - "coordinates system not implemented, see help" " for details" + "coordinates system not implemented, see help for details" ) diff --git a/src/sage/manifolds/chart.py b/src/sage/manifolds/chart.py index 3468ba44426..ec8298a480b 100644 --- a/src/sage/manifolds/chart.py +++ b/src/sage/manifolds/chart.py @@ -3197,7 +3197,7 @@ def _plot_xx_list(xx_list, rem_coords, ranges, steps, number_values): else: if not isinstance(mapping, ContinuousMap): raise TypeError( - "the argument 'mapping' must be a " "continuous manifold map" + "the argument 'mapping' must be a continuous manifold map" ) if not self.domain().is_subset(mapping.domain()): raise ValueError( diff --git a/src/sage/manifolds/chart_func.py b/src/sage/manifolds/chart_func.py index 30adb1e18c9..8e9ac906059 100644 --- a/src/sage/manifolds/chart_func.py +++ b/src/sage/manifolds/chart_func.py @@ -595,7 +595,7 @@ def set_expr(self, calc_method, expression): """ if self.is_immutable(): raise ValueError( - "the expressions of an immutable element cannot " "be changed" + "the expressions of an immutable element cannot be changed" ) for vv in self._express.values(): if not bool( diff --git a/src/sage/manifolds/continuous_map.py b/src/sage/manifolds/continuous_map.py index 22f44b5d430..49a88430a3d 100644 --- a/src/sage/manifolds/continuous_map.py +++ b/src/sage/manifolds/continuous_map.py @@ -397,7 +397,7 @@ def __init__( self._is_isomorphism = True if domain != codomain: raise ValueError( - "the domain and codomain must coincide" " for the identity map" + "the domain and codomain must coincide for the identity map" ) if name is None: name = 'Id_' + domain._name From 52762fa98f28bfc0b35140d9ecd143ae9fb55af3 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sat, 14 Dec 2024 21:13:26 +0700 Subject: [PATCH 04/69] Minor docfix of interpolation() method --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index ac5e445908d..2aeff11387f 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -432,8 +432,9 @@ cdef class MPolynomialRing_base(CommutativeRing): Also, if the solution is not unique, it spits out one solution, without any notice that there are more. - Lastly, the interpolation function for univariate polynomial rings - is called :meth:`lagrange_polynomial`. + Lastly, the interpolation function for univariate polynomial rings, + :meth:`~sage.rings.polynomial.polynomial_ring.PolynomialRing_field.lagrange_polynomial`, + is called. .. WARNING:: @@ -453,7 +454,7 @@ cdef class MPolynomialRing_base(CommutativeRing): .. SEEALSO:: - :meth:`lagrange_polynomial` + :meth:`~sage.rings.polynomial.polynomial_ring.PolynomialRing_field.lagrange_polynomial` """ from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector From a699113e1575e0379736228734d6ae6c43f4edb6 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sat, 9 Nov 2024 18:14:25 +0700 Subject: [PATCH 05/69] Allow passing view_annotate=True to Cython compilation --- src/sage/misc/cython.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index c542e0d1919..01f3d7f580d 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -24,6 +24,7 @@ import re import sys import shutil +import webbrowser from sage.env import (SAGE_LOCAL, cython_aliases, sage_include_directories) @@ -79,8 +80,8 @@ def _standard_libs_libdirs_incdirs_aliases(): def cython(filename, verbose=0, compile_message=False, - use_cache=False, create_local_c_file=False, annotate=True, sage_namespace=True, - create_local_so_file=False): + use_cache=False, create_local_c_file=False, annotate=True, view_annotate=False, + sage_namespace=True, create_local_so_file=False): r""" Compile a Cython file. This converts a Cython file to a C (or C++ file), and then compiles that. The .c file and the .so file are @@ -110,6 +111,9 @@ def cython(filename, verbose=0, compile_message=False, in the temporary directory, but if ``create_local_c_file`` is also True, then save a copy of the .html file in the current directory. + - ``view_annotate`` -- boolean (default: ``False``); if ``True``, open the + annotated html file in a web browser using :func:`webbrowser.open` + - ``sage_namespace`` -- boolean (default: ``True``); if ``True``, import ``sage.all`` @@ -392,6 +396,11 @@ def cython(filename, verbose=0, compile_message=False, shutil.copy(os.path.join(target_dir, name + ".html"), os.curdir) + if view_annotate: + if not annotate: + raise ValueError("Cannot view annotated file without creating it") + webbrowser.open(os.path.join(target_dir, name + ".html")) + # This emulates running "setup.py build" with the correct options # # setuptools plugins considered harmful: From 64890af2100c4b36df1edd54c919382b34a2eaf7 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 10 Nov 2024 18:19:54 +0700 Subject: [PATCH 06/69] Add tests for view_annotate --- src/sage/misc/cython.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index 01f3d7f580d..3016167c0be 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -241,6 +241,23 @@ def cython(filename, verbose=0, compile_message=False, RuntimeError: Error compiling Cython file: ... ...: 'sage/misc.pxd' not found + + Test ``view_annotate``:: + + sage: cython(''' + ....: def f(int n): + ....: return n*n + ....: ''', view_annotate=True) # optional -- webbrowser + + :: + + sage: cython(''' + ....: def f(int n): + ....: return n*n + ....: ''', view_annotate=True, annotate=False) + Traceback (most recent call last): + ... + ValueError: Cannot view annotated file without creating it """ if not filename.endswith('pyx'): print("Warning: file (={}) should have extension .pyx".format(filename), file=sys.stderr) From 0f386e9fff4a4ce2e649fda912b8e1b27656bd9e Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 14 Nov 2024 21:42:23 +0700 Subject: [PATCH 07/69] Add view-annotate to IPython magic --- src/sage/repl/ipython_extension.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index 329a7b9b95a..15a6c0a7edc 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -357,6 +357,7 @@ def cython(self, line, cell): - ``--use-cache`` - ``--create-local-c-file`` - ``--annotate`` + - ``--view-annotate`` - ``--sage-namespace`` - ``--create-local-so-file`` - ``--no-compile-message``, ``--no-use-cache``, etc. @@ -434,6 +435,7 @@ def error(self, message): 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("--view-annotate", action=argparse.BooleanOptionalAction) parser.add_argument("--sage-namespace", action=argparse.BooleanOptionalAction) parser.add_argument("--create-local-so-file", action=argparse.BooleanOptionalAction) args = parser.parse_args(shlex.split(line)) From f90425dbd93b47eb8cf709ddbdbb1b8ad9161554 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sat, 7 Dec 2024 23:14:29 +0700 Subject: [PATCH 08/69] Allow view-annotate to display in Sage notebook --- src/sage/misc/cython.py | 21 +++++++++++-- src/sage/repl/ipython_extension.py | 48 ++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index 3016167c0be..9b3e2428865 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -81,7 +81,7 @@ def _standard_libs_libdirs_incdirs_aliases(): def cython(filename, verbose=0, compile_message=False, use_cache=False, create_local_c_file=False, annotate=True, view_annotate=False, - sage_namespace=True, create_local_so_file=False): + view_annotate_callback=webbrowser.open, sage_namespace=True, create_local_so_file=False): r""" Compile a Cython file. This converts a Cython file to a C (or C++ file), and then compiles that. The .c file and the .so file are @@ -114,6 +114,11 @@ def cython(filename, verbose=0, compile_message=False, - ``view_annotate`` -- boolean (default: ``False``); if ``True``, open the annotated html file in a web browser using :func:`webbrowser.open` + - ``view_annotate_callback`` -- function (default: ``webbrowser.open``); a function + that takes a string being the path to the html file. This can be overridden to + change what to do with the annotated html file. Have no effect unless + ``view_annotate`` is ``True`` + - ``sage_namespace`` -- boolean (default: ``True``); if ``True``, import ``sage.all`` @@ -258,6 +263,18 @@ def cython(filename, verbose=0, compile_message=False, Traceback (most recent call last): ... ValueError: Cannot view annotated file without creating it + + :: + + sage: collected_paths = [] + sage: cython(''' + ....: def f(int n): + ....: return n*n + ....: ''', view_annotate=True, view_annotate_callback=collected_paths.append) + sage: collected_paths + ['...'] + sage: len(collected_paths) + 1 """ if not filename.endswith('pyx'): print("Warning: file (={}) should have extension .pyx".format(filename), file=sys.stderr) @@ -416,7 +433,7 @@ def cython(filename, verbose=0, compile_message=False, if view_annotate: if not annotate: raise ValueError("Cannot view annotated file without creating it") - webbrowser.open(os.path.join(target_dir, name + ".html")) + view_annotate_callback(os.path.join(target_dir, name + ".html")) # This emulates running "setup.py build" with the correct options # diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index 15a6c0a7edc..34d7d15c36f 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -65,6 +65,8 @@ """ from IPython.core.magic import Magics, magics_class, line_magic, cell_magic +from IPython.core.display import HTML +from IPython import get_ipython from sage.repl.load import load_wrap from sage.env import SAGE_IMPORTALL, SAGE_STARTUP_FILE @@ -72,6 +74,14 @@ from sage.misc.misc import run_once +def _running_in_notebook(): + try: + from ipykernel.zmqshell import ZMQInteractiveShell + except ImportError: + return False + return isinstance(get_ipython(), ZMQInteractiveShell) + + @magics_class class SageMagics(Magics): @@ -364,6 +374,16 @@ def cython(self, line, cell): See :func:`~sage.misc.cython.cython` for details. + For ``--view-annotate``, the following additional choices are allowed: + + - ``--view-annotate=none`` (default) + - ``--view-annotate=auto`` (same as ``--view-annotate``); select one of the + choices below automatically + - ``--view-annotate=webbrowser``; open the annotation in a web browser + (preferred if the Sage command line is used) + - ``--view-annotate=displayhtml``; display the annotation inline in the notebook + (preferred if the Sage notebook is used) + - ``cell`` -- string; the Cython source code to process OUTPUT: none; the Cython code is compiled and loaded @@ -404,6 +424,15 @@ def cython(self, line, cell): ....: ''') UsageError: unrecognized arguments: --help + Test ``--view-annotate`` invalid arguments:: + + sage: # needs sage.misc.cython + sage: shell.run_cell(''' + ....: %%cython --view-annotate=xx + ....: print(1) + ....: ''') + UsageError: argument --view-annotate: invalid choice: 'xx' (choose from 'none', 'auto', 'webbrowser', 'displayhtml') + Test invalid quotes:: sage: # needs sage.misc.cython @@ -435,11 +464,26 @@ def error(self, message): 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("--view-annotate", action=argparse.BooleanOptionalAction) + parser.add_argument("--view-annotate", choices=["none", "auto", "webbrowser", "displayhtml"], + nargs="?", const="auto", default="none") parser.add_argument("--sage-namespace", 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}) + view_annotate = args.view_annotate + del args.view_annotate + if view_annotate == "auto": + if _running_in_notebook(): + view_annotate = "displayhtml" + else: + view_annotate = "webbrowser" + args_dict = {k: v for k, v in args.__dict__.items() if v is not None} + if view_annotate != "none": + args_dict["view_annotate"] = True + if view_annotate == "displayhtml": + path_to_annotate_html_container = [] + cython_compile(cell, **args_dict, view_annotate_callback=path_to_annotate_html_container.append) + return HTML(filename=path_to_annotate_html_container[0]) + return cython_compile(cell, **args_dict) @cell_magic def fortran(self, line, cell): From 011fd6caa4864a88b0f49817bb0a99fc7e80b755 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sat, 7 Dec 2024 23:29:18 +0700 Subject: [PATCH 09/69] Fix pyright --- src/sage/repl/ipython_extension.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index 34d7d15c36f..9e1645e22df 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -66,7 +66,7 @@ from IPython.core.magic import Magics, magics_class, line_magic, cell_magic from IPython.core.display import HTML -from IPython import get_ipython +from IPython.core.getipython import get_ipython from sage.repl.load import load_wrap from sage.env import SAGE_IMPORTALL, SAGE_STARTUP_FILE From 0fc93c2951025b7161d001b81fb338a9660cbd9b Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:14:11 +0700 Subject: [PATCH 10/69] Add a test for view-annotate=displayhtml --- src/sage/repl/ipython_extension.py | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index 9e1645e22df..c159f193ec5 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -358,6 +358,12 @@ def cython(self, line, cell): This is syntactic sugar on the :func:`~sage.misc.cython.cython_compile` function. + Note that there is also the ``%%cython`` cell magic provided by Cython, + which can be loaded with ``%load_ext cython``, see + `Cython documentation `_ + for more details. + The semantic is slightly different from the version provided by Sage. + INPUT: - ``line`` -- parsed as keyword arguments. The allowed arguments are: @@ -433,6 +439,36 @@ def cython(self, line, cell): ....: ''') UsageError: argument --view-annotate: invalid choice: 'xx' (choose from 'none', 'auto', 'webbrowser', 'displayhtml') + Test ``--view-annotate=displayhtml`` (note that in a notebook environment + an inline HTML frame will be displayed):: + + sage: # needs sage.misc.cython + sage: shell.run_cell(''' + ....: %%cython --view-annotate=displayhtml + ....: print(1) + ....: ''') + 1 + + + Test ``--view-annotate=webbrowser``:: + + sage: # needs sage.misc.cython webbrowser + sage: shell.run_cell(''' + ....: %%cython --view-annotate + ....: print(1) + ....: ''') + 1 + sage: shell.run_cell(''' + ....: %%cython --view-annotate=auto + ....: print(1) + ....: ''') + 1 + sage: shell.run_cell(''' + ....: %%cython --view-annotate=webbrowser + ....: print(1) + ....: ''') + 1 + Test invalid quotes:: sage: # needs sage.misc.cython From 4f7937ded0990b750ab0433b1d74c68c9af5758d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 16 Dec 2024 13:57:41 +0100 Subject: [PATCH 11/69] simplify some call of isintance in pyx files --- src/sage/ext/fast_callable.pyx | 3 ++- src/sage/libs/ntl/ntl_mat_GF2.pyx | 8 +++---- src/sage/libs/ntl/ntl_mat_GF2E.pyx | 8 +++---- src/sage/libs/singular/function.pyx | 22 ++++++++----------- src/sage/matrix/matrix2.pyx | 10 ++++++--- src/sage/matrix/matrix_gfpn_dense.pyx | 10 ++++----- src/sage/numerical/mip.pyx | 2 +- src/sage/numerical/sdp.pyx | 5 +++-- .../rings/finite_rings/element_givaro.pyx | 2 +- src/sage/rings/integer.pyx | 2 +- src/sage/rings/morphism.pyx | 9 +++++--- src/sage/rings/padics/common_conversion.pyx | 12 +++++----- .../rings/polynomial/multi_polynomial.pyx | 2 +- .../rings/polynomial/polynomial_element.pyx | 5 ++--- .../polynomial/polynomial_modn_dense_ntl.pyx | 2 +- .../polynomial/polynomial_rational_flint.pyx | 2 +- .../rings/polynomial/polynomial_template.pxi | 8 +++---- src/sage/symbolic/ring.pyx | 3 ++- 18 files changed, 60 insertions(+), 55 deletions(-) diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index 89c34b1f0fc..8b9fcd70614 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -477,7 +477,8 @@ def fast_callable(x, domain=None, vars=None, if vars is None: from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base - if isinstance(x.parent(), PolynomialRing_general) or isinstance(x.parent(), MPolynomialRing_base): + if isinstance(x.parent(), (PolynomialRing_general, + MPolynomialRing_base)): vars = x.parent().variable_names() else: # constant diff --git a/src/sage/libs/ntl/ntl_mat_GF2.pyx b/src/sage/libs/ntl/ntl_mat_GF2.pyx index 479f4505b71..dd910a567c0 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2.pyx @@ -315,10 +315,10 @@ cdef class ntl_mat_GF2(): if isinstance(ij, tuple) and len(ij) == 2: i, j = ij - elif self.x.NumCols()==1 and (isinstance(ij, Integer) or isinstance(ij, int)): + elif self.x.NumCols() == 1 and isinstance(ij, (Integer, int)): i = ij j = 0 - elif self.x.NumRows()==1 and (isinstance(ij, Integer) or isinstance(ij, int)): + elif self.x.NumRows() == 1 and isinstance(ij, (Integer, int)): i = 0 j = ij else: @@ -342,10 +342,10 @@ cdef class ntl_mat_GF2(): cdef int i, j if isinstance(ij, tuple) and len(ij) == 2: i, j = ij - elif self.x.NumCols() == 1 and (isinstance(ij, Integer) or isinstance(ij, int)): + elif self.x.NumCols() == 1 and isinstance(ij, (Integer, int)): i = ij j = 0 - elif self.x.NumRows() == 1 and (isinstance(ij, Integer) or isinstance(ij, int)): + elif self.x.NumRows() == 1 and isinstance(ij, (Integer, int)): i = 0 j = ij else: diff --git a/src/sage/libs/ntl/ntl_mat_GF2E.pyx b/src/sage/libs/ntl/ntl_mat_GF2E.pyx index eb044cbfc37..b7c34d2dc46 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2E.pyx @@ -377,10 +377,10 @@ cdef class ntl_mat_GF2E(): if isinstance(ij, tuple) and len(ij) == 2: i, j = ij - elif self.x.NumCols()==1 and (isinstance(ij, Integer) or isinstance(ij, int)): + elif self.x.NumCols() == 1 and isinstance(ij, (Integer, int)): i = ij j = 0 - elif self.x.NumRows()==1 and (isinstance(ij, Integer) or isinstance(ij, int)): + elif self.x.NumRows() == 1 and isinstance(ij, (Integer, int)): i = 0 j = ij else: @@ -411,10 +411,10 @@ cdef class ntl_mat_GF2E(): cdef int i, j if isinstance(ij, tuple) and len(ij) == 2: i, j = ij - elif self.x.NumCols() == 1 and (isinstance(ij, Integer) or isinstance(ij, int)): + elif self.x.NumCols() == 1 and isinstance(ij, (Integer, int)): i = ij j = 0 - elif self.x.NumRows() == 1 and (isinstance(ij, Integer) or isinstance(ij, int)): + elif self.x.NumRows() == 1 and isinstance(ij, (Integer, int)): i = 0 j = ij else: diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index 7bf2afafbe8..e410cb2ff11 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -386,11 +386,8 @@ def is_sage_wrapper_for_singular_ring(ring): sage: is_sage_wrapper_for_singular_ring(P) True """ - if isinstance(ring, MPolynomialRing_libsingular): - return True - if isinstance(ring, NCPolynomialRing_plural): - return True - return False + return isinstance(ring, (MPolynomialRing_libsingular, + NCPolynomialRing_plural)) cdef new_sage_polynomial(ring, poly *p): @@ -523,8 +520,7 @@ cdef class Converter(SageObject): elif is_sage_wrapper_for_singular_ring(a): v = self.append_ring(a) - elif isinstance(a, MPolynomialIdeal) or \ - isinstance(a, NCPolynomialIdeal): + elif isinstance(a, (MPolynomialIdeal, NCPolynomialIdeal)): v = self.append_ideal(a) elif isinstance(a, int): @@ -569,8 +565,7 @@ cdef class Converter(SageObject): elif isinstance(a, tuple): is_intvec = True for i in a: - if not (isinstance(i, int) - or isinstance(i, Integer)): + if not isinstance(i, (int, Integer)): is_intvec = False break if is_intvec: @@ -584,7 +579,7 @@ cdef class Converter(SageObject): v = self.append_int(a) else: - raise TypeError("unknown argument type '%s'"%(type(a),)) + raise TypeError("unknown argument type '%s'" % (type(a),)) if attributes and a in attributes: for attrib in attributes[a]: @@ -593,7 +588,7 @@ cdef class Converter(SageObject): atSet(v, omStrDup("isSB"), val, INT_CMD) setFlag(v, FLAG_STD) else: - raise NotImplementedError("Support for attribute '%s' not implemented yet."%attrib) + raise NotImplementedError("Support for attribute '%s' not implemented yet." % attrib) def ring(self): """ @@ -1304,8 +1299,9 @@ cdef class SingularFunction(SageObject): from sage.rings.rational_field import QQ dummy_ring = PolynomialRing(QQ, "dummy", implementation='singular') # seems a reasonable default ring = dummy_ring - if not (isinstance(ring, MPolynomialRing_libsingular) or isinstance(ring, NCPolynomialRing_plural)): - raise TypeError("cannot call Singular function '%s' with ring parameter of type '%s'" % (self._name,type(ring))) + if not isinstance(ring, (MPolynomialRing_libsingular, + NCPolynomialRing_plural)): + raise TypeError("cannot call Singular function '%s' with ring parameter of type '%s'" % (self._name, type(ring))) return call_function(self, args, ring, interruptible, attributes) def _instancedoc_(self): diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index dec25a76e54..45e3f6f8263 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -4659,11 +4659,15 @@ cdef class Matrix(Matrix1): algorithm = 'default' elif algorithm not in ['default', 'generic', 'flint', 'pari', 'padic', 'pluq']: raise ValueError("matrix kernel algorithm '%s' not recognized" % algorithm) - elif algorithm == 'padic' and not (isinstance(R, IntegerRing_class) or isinstance(R, RationalField)): + elif algorithm == 'padic' and not isinstance(R, (IntegerRing_class, + RationalField)): raise ValueError("'padic' matrix kernel algorithm only available over the rationals and the integers, not over %s" % R) - elif algorithm == 'flint' and not (isinstance(R, IntegerRing_class) or isinstance(R, RationalField)): + elif algorithm == 'flint' and not isinstance(R, (IntegerRing_class, + RationalField)): raise ValueError("'flint' matrix kernel algorithm only available over the rationals and the integers, not over %s" % R) - elif algorithm == 'pari' and not (isinstance(R, IntegerRing_class) or (isinstance(R, NumberField) and not isinstance(R, RationalField))): + elif algorithm == 'pari' and not isinstance(R, (IntegerRing_class, + NumberField, + RationalField)): raise ValueError("'pari' matrix kernel algorithm only available over non-trivial number fields and the integers, not over %s" % R) elif algorithm == 'generic' and R not in _Fields: raise ValueError("'generic' matrix kernel algorithm only available over a field, not over %s" % R) diff --git a/src/sage/matrix/matrix_gfpn_dense.pyx b/src/sage/matrix/matrix_gfpn_dense.pyx index 9d4e113e522..b73013ebcf8 100644 --- a/src/sage/matrix/matrix_gfpn_dense.pyx +++ b/src/sage/matrix/matrix_gfpn_dense.pyx @@ -903,12 +903,12 @@ cdef class Matrix_gfpn_dense(Matrix_dense): else: raise ValueError("Matrix is empty") if (i < 0) or (i >= self.Data.Nor): - raise IndexError("Index {} out of range 0..{}",format(i,self.Data.Nor-1)) + raise IndexError("Index {} out of range 0..{}",format(i, self.Data.Nor-1)) cdef PTR p - p = MatGetPtr(self.Data,i) - L = [FfToInt(FfExtract(p,k)) for k in range(self.Data.Noc)] - if j!=-1: - if not(isinstance(j,int) or isinstance(j,Integer)): + p = MatGetPtr(self.Data, i) + L = [FfToInt(FfExtract(p, k)) for k in range(self.Data.Noc)] + if j != -1: + if not isinstance(j, (int, Integer)): raise TypeError("Second index must be an integer") if j >= self.Data.Nor: raise IndexError("Index out of range") diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 78ac846d3df..36ec9bfed0d 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -2129,7 +2129,7 @@ cdef class MixedIntegerLinearProgram(SageObject): from sage.numerical.linear_functions import LinearFunction, LinearConstraint from sage.numerical.linear_tensor import LinearTensor from sage.numerical.linear_tensor_constraints import LinearTensorConstraint - if isinstance(linear_function, LinearFunction) or isinstance(linear_function, LinearTensor): + if isinstance(linear_function, (LinearFunction, LinearTensor)): # Find the parent for the coefficients if isinstance(linear_function, LinearFunction): M = linear_function.parent().base_ring() diff --git a/src/sage/numerical/sdp.pyx b/src/sage/numerical/sdp.pyx index 6693b943806..2278200e772 100644 --- a/src/sage/numerical/sdp.pyx +++ b/src/sage/numerical/sdp.pyx @@ -892,7 +892,8 @@ cdef class SemidefiniteProgram(SageObject): from sage.numerical.linear_tensor_constraints import LinearTensorConstraint from sage.numerical.linear_tensor import LinearTensor - if isinstance(linear_function, LinearTensorConstraint) or isinstance(linear_function, LinearConstraint): + if isinstance(linear_function, (LinearTensorConstraint, + LinearConstraint)): c = linear_function if c.is_equation(): self.add_constraint(c.lhs()-c.rhs(), name=name) @@ -900,7 +901,7 @@ cdef class SemidefiniteProgram(SageObject): else: self.add_constraint(c.lhs()-c.rhs(), name=name) - elif isinstance(linear_function, LinearFunction) or isinstance(linear_function, LinearTensor): + elif isinstance(linear_function, (LinearFunction, LinearTensor)): l = sorted(linear_function.dict().items()) self._backend.add_linear_constraint(l, name) diff --git a/src/sage/rings/finite_rings/element_givaro.pyx b/src/sage/rings/finite_rings/element_givaro.pyx index bb5a9f6b376..695ecd2c8bf 100644 --- a/src/sage/rings/finite_rings/element_givaro.pyx +++ b/src/sage/rings/finite_rings/element_givaro.pyx @@ -359,7 +359,7 @@ cdef class Cache_givaro(Cache_base): else: raise TypeError("unable to coerce from a finite field other than the prime subfield") - elif isinstance(e, (int, Integer)) or isinstance(e, IntegerMod_abstract): + elif isinstance(e, (int, Integer, IntegerMod_abstract)): try: e_int = e % self.characteristic() self.objectptr.initi(res, e_int) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index c9d1ff65bc6..da004072ccd 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -684,7 +684,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): mpz_set_str_python(self.value, str_to_bytes(x), base) return - elif (isinstance(x, list) or isinstance(x, tuple)) and base > 1: + elif isinstance(x, (list, tuple)) and base > 1: b = the_integer_ring(base) if b == 2: # we use a faster method for j in range(len(x)): diff --git a/src/sage/rings/morphism.pyx b/src/sage/rings/morphism.pyx index 3079bfa3974..cca8b5aedb6 100644 --- a/src/sage/rings/morphism.pyx +++ b/src/sage/rings/morphism.pyx @@ -1045,8 +1045,10 @@ cdef class RingHomomorphism(RingMap): # avoid adding the 0-ideal to the graph ideal in order to benefit # from a cached Gröbner basis graph_I = graph - elif (isinstance(B, MPolynomialRing_base) or isinstance(B, PolynomialRing_general) - or isinstance(B, QuotientRing_nc) or isinstance(B, PolynomialQuotientRing_generic)): + elif isinstance(B, (MPolynomialRing_base, + PolynomialRing_general, + QuotientRing_nc, + PolynomialQuotientRing_generic)): graph_I = graph + from_B(I) else: # nonzero fractional ideals of number fields not yet supported @@ -3150,7 +3152,8 @@ def _tensor_product_ring(B, A): def term_order(A): # univariate rings do not have a term order - if (isinstance(A, PolynomialRing_general) or isinstance(A, PolynomialQuotientRing_generic) + if (isinstance(A, (PolynomialRing_general, + PolynomialQuotientRing_generic)) or (isinstance(A, (NumberField, FiniteField)) and not A.is_prime_field())): return TermOrder('lex', 1) diff --git a/src/sage/rings/padics/common_conversion.pyx b/src/sage/rings/padics/common_conversion.pyx index a352cc74c18..6831fbde141 100644 --- a/src/sage/rings/padics/common_conversion.pyx +++ b/src/sage/rings/padics/common_conversion.pyx @@ -106,7 +106,7 @@ cdef long get_ordp(x, PowComputer_class prime_pow) except? -10000: k = mpz_remove(temp.value, mpq_numref((x).value), prime_pow.prime.value) if k == 0: k = -mpz_remove(temp.value, mpq_denref((x).value), prime_pow.prime.value) - elif isinstance(x, (list,tuple)): + elif isinstance(x, (list, tuple)): f = prime_pow.f if (e == 1 and len(x) > f) or (e != 1 and len(x) > e): # could reduce modulo the defining polynomial but that isn't currently supported @@ -114,11 +114,11 @@ cdef long get_ordp(x, PowComputer_class prime_pow) except? -10000: k = maxordp shift = 0 for a in x: - if isinstance(a, (list,tuple)): + if isinstance(a, (list, tuple)): if e == 1 or f == 1: raise ValueError("nested lists not allowed for unramified and eisenstein extensions") for b in a: - if isinstance(b, (list,tuple)): + if isinstance(b, (list, tuple)): raise ValueError("list nesting too deep") curterm = get_ordp(b, prime_pow) k = min(k, curterm + shift, maxordp) @@ -191,13 +191,13 @@ cdef long get_preccap(x, PowComputer_class prime_pow) except? -10000: cdef long k, shift, e = prime_pow.e cdef Integer prec cdef GEN pari_tmp - if isinstance(x, int) or isinstance(x, Integer) or isinstance(x, Rational): + if isinstance(x, (int, Integer, Rational)): return maxordp - elif isinstance(x, (list,tuple)): + elif isinstance(x, (list, tuple)): k = maxordp shift = 0 for a in x: - if isinstance(a, (list,tuple)): + if isinstance(a, (list, tuple)): for b in a: curterm = get_preccap(b, prime_pow) k = min(k, curterm + shift) diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index 0e25b72dbb9..87b4e2d081c 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -784,7 +784,7 @@ cdef class MPolynomial(CommutativePolynomial): P = P.change_ring(names=P.variable_names() + [str(var)]) return P(self)._homogenize(len(V)) - elif isinstance(var, int) or isinstance(var, Integer): + elif isinstance(var, (int, Integer)): if 0 <= var < P.ngens(): return self._homogenize(var) else: diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 389e538f83e..ca68d9c8751 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -11022,11 +11022,10 @@ cdef class Polynomial(CommutativePolynomial): x, = self.variables() - if isinstance(var, int) or isinstance(var, Integer): + if isinstance(var, (int, Integer)): if var: raise TypeError("Variable index %d must be < 1." % var) - else: - return sum(self.coefficients())*x**self.degree() + return sum(self.coefficients()) * x**self.degree() x_name = self.variable_name() var = str(var) diff --git a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx index 68605382f1f..7cf4f828ced 100644 --- a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx @@ -1848,7 +1848,7 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): return Polynomial.__call__(self, *args, **kwds) arg = args[0] cdef ntl_ZZ_p fx = ntl_ZZ_p(0, self.c), x = None - if isinstance(arg, int) or isinstance(arg, Integer): + if isinstance(arg, (int, Integer)): x = ntl_ZZ_p(arg, self.c) elif isinstance(arg, Element): if self._parent._base == (arg)._parent: # c++ pointer hack diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx index c11592cf2d6..979877606a7 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx @@ -236,7 +236,7 @@ cdef class Polynomial_rational_flint(Polynomial): elif isinstance(x, Rational): fmpq_poly_set_mpq(self._poly, ( x).value) - elif isinstance(x, list) or isinstance(x, tuple): + elif isinstance(x, (list, tuple)): if len(x) == 0: return diff --git a/src/sage/rings/polynomial/polynomial_template.pxi b/src/sage/rings/polynomial/polynomial_template.pxi index b76d62a9e92..35c260e67ea 100644 --- a/src/sage/rings/polynomial/polynomial_template.pxi +++ b/src/sage/rings/polynomial/polynomial_template.pxi @@ -117,16 +117,16 @@ cdef class Polynomial_template(Polynomial): celement_construct(&self.x, (self)._cparent) celement_set(&self.x, &(x).x, (self)._cparent) except NotImplementedError: - raise TypeError("%s not understood."%x) + raise TypeError("%s not understood." % x) - elif isinstance(x, int) or isinstance(x, Integer): + elif isinstance(x, (int, Integer)): try: celement_construct(&self.x, (self)._cparent) celement_set_si(&self.x, int(x), (self)._cparent) except NotImplementedError: raise TypeError("%s not understood."%x) - elif isinstance(x, list) or isinstance(x, tuple): + elif isinstance(x, (list, tuple)): celement_construct(&self.x, (self)._cparent) gen = celement_new((self)._cparent) monomial = celement_new((self)._cparent) @@ -629,7 +629,7 @@ cdef class Polynomial_template(Polynomial): 0 """ if not isinstance(self, Polynomial_template): - raise NotImplementedError("%s^%s not defined."%(ee,self)) + raise NotImplementedError("%s^%s not defined." % (ee, self)) cdef bint recip = 0, do_sig cdef long e diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index 96f3a445e9c..f1f6e833873 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -219,7 +219,8 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): if R._is_numerical(): # Almost anything with a coercion into any precision of CC return R not in (RLF, CLF) - elif isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base) or isinstance(R, FractionField_generic) or isinstance(R, LaurentPolynomialRing_generic): + elif isinstance(R, (PolynomialRing_general, MPolynomialRing_base, + FractionField_generic, LaurentPolynomialRing_generic)): base = R.base_ring() return base is not self and self.has_coerce_map_from(base) elif (R is InfinityRing or R is UnsignedInfinityRing From 7ac11619aef9c84ba30938bf7ea02e21fb868e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 17 Dec 2024 08:07:12 +0100 Subject: [PATCH 12/69] fix linter warning --- src/sage/libs/ntl/ntl_mat_GF2E.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/libs/ntl/ntl_mat_GF2E.pyx b/src/sage/libs/ntl/ntl_mat_GF2E.pyx index b7c34d2dc46..7841952cacc 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2E.pyx @@ -414,7 +414,7 @@ cdef class ntl_mat_GF2E(): elif self.x.NumCols() == 1 and isinstance(ij, (Integer, int)): i = ij j = 0 - elif self.x.NumRows() == 1 and isinstance(ij, (Integer, int)): + elif self.x.NumRows() == 1 and isinstance(ij, (Integer, int)): i = 0 j = ij else: From e7c99f7ba765af2486141b3deb0e8800e06fbf20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 18 Dec 2024 09:40:59 +0100 Subject: [PATCH 13/69] fix wrong change in matrix2 --- src/sage/matrix/matrix2.pyx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 45e3f6f8263..790115a4e49 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -4665,9 +4665,7 @@ cdef class Matrix(Matrix1): elif algorithm == 'flint' and not isinstance(R, (IntegerRing_class, RationalField)): raise ValueError("'flint' matrix kernel algorithm only available over the rationals and the integers, not over %s" % R) - elif algorithm == 'pari' and not isinstance(R, (IntegerRing_class, - NumberField, - RationalField)): + elif algorithm == 'pari' and not (isinstance(R, (IntegerRing_class, NumberField)) and not isinstance(R, RationalField)): raise ValueError("'pari' matrix kernel algorithm only available over non-trivial number fields and the integers, not over %s" % R) elif algorithm == 'generic' and R not in _Fields: raise ValueError("'generic' matrix kernel algorithm only available over a field, not over %s" % R) From a93f1398731d506f361c7168c913f45f152504ed Mon Sep 17 00:00:00 2001 From: Giorgos Mousa Date: Fri, 20 Dec 2024 10:32:25 +0200 Subject: [PATCH 14/69] `build/pkgs`: Remove `libtheora` --- build/pkgs/libtheora/SPKG.rst | 54 ----------------------- build/pkgs/libtheora/checksums.ini | 3 -- build/pkgs/libtheora/dependencies | 4 -- build/pkgs/libtheora/distros/conda.txt | 1 - build/pkgs/libtheora/distros/fedora.txt | 2 - build/pkgs/libtheora/distros/homebrew.txt | 1 - build/pkgs/libtheora/distros/macports.txt | 1 - build/pkgs/libtheora/distros/opensuse.txt | 1 - build/pkgs/libtheora/distros/repology.txt | 1 - build/pkgs/libtheora/distros/void.txt | 1 - build/pkgs/libtheora/package-version.txt | 1 - build/pkgs/libtheora/spkg-install.in | 24 ---------- build/pkgs/libtheora/type | 1 - 13 files changed, 95 deletions(-) delete mode 100644 build/pkgs/libtheora/SPKG.rst delete mode 100644 build/pkgs/libtheora/checksums.ini delete mode 100644 build/pkgs/libtheora/dependencies delete mode 100644 build/pkgs/libtheora/distros/conda.txt delete mode 100644 build/pkgs/libtheora/distros/fedora.txt delete mode 100644 build/pkgs/libtheora/distros/homebrew.txt delete mode 100644 build/pkgs/libtheora/distros/macports.txt delete mode 100644 build/pkgs/libtheora/distros/opensuse.txt delete mode 100644 build/pkgs/libtheora/distros/repology.txt delete mode 100644 build/pkgs/libtheora/distros/void.txt delete mode 100644 build/pkgs/libtheora/package-version.txt delete mode 100644 build/pkgs/libtheora/spkg-install.in delete mode 100644 build/pkgs/libtheora/type diff --git a/build/pkgs/libtheora/SPKG.rst b/build/pkgs/libtheora/SPKG.rst deleted file mode 100644 index 0c2c9e1c642..00000000000 --- a/build/pkgs/libtheora/SPKG.rst +++ /dev/null @@ -1,54 +0,0 @@ -libtheora: Library for the Theora video codec -============================================= - -Description ------------ - -libtheora is the official reference library for the Theora video codec. -Theora is a free and open video compression format from the Xiph.org -Foundation. - -Website: http://www.xiph.org/theora - -License -------- - -Copyright (c) 2002, Xiph.org Foundation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -- Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -- Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -Upstream Contact ----------------- - -The Xiph.org mailing lists - see http://lists.xiph.org/mailman/listinfo - -Special Update/Build Instructions ---------------------------------- - -- No changes went into src. diff --git a/build/pkgs/libtheora/checksums.ini b/build/pkgs/libtheora/checksums.ini deleted file mode 100644 index b940bb462c1..00000000000 --- a/build/pkgs/libtheora/checksums.ini +++ /dev/null @@ -1,3 +0,0 @@ -tarball=libtheora-VERSION.tar.bz2 -sha1=8dcaa8e61cd86eb1244467c0b64b9ddac04ae262 -sha256=b6ae1ee2fa3d42ac489287d3ec34c5885730b1296f0801ae577a35193d3affbc diff --git a/build/pkgs/libtheora/dependencies b/build/pkgs/libtheora/dependencies deleted file mode 100644 index e62d879d3a4..00000000000 --- a/build/pkgs/libtheora/dependencies +++ /dev/null @@ -1,4 +0,0 @@ -libogg libpng - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/libtheora/distros/conda.txt b/build/pkgs/libtheora/distros/conda.txt deleted file mode 100644 index 944587f5d50..00000000000 --- a/build/pkgs/libtheora/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -libtheora diff --git a/build/pkgs/libtheora/distros/fedora.txt b/build/pkgs/libtheora/distros/fedora.txt deleted file mode 100644 index 8043f5eea67..00000000000 --- a/build/pkgs/libtheora/distros/fedora.txt +++ /dev/null @@ -1,2 +0,0 @@ -libtheora -libtheora-devel diff --git a/build/pkgs/libtheora/distros/homebrew.txt b/build/pkgs/libtheora/distros/homebrew.txt deleted file mode 100644 index bddb694122d..00000000000 --- a/build/pkgs/libtheora/distros/homebrew.txt +++ /dev/null @@ -1 +0,0 @@ -theora diff --git a/build/pkgs/libtheora/distros/macports.txt b/build/pkgs/libtheora/distros/macports.txt deleted file mode 100644 index 944587f5d50..00000000000 --- a/build/pkgs/libtheora/distros/macports.txt +++ /dev/null @@ -1 +0,0 @@ -libtheora diff --git a/build/pkgs/libtheora/distros/opensuse.txt b/build/pkgs/libtheora/distros/opensuse.txt deleted file mode 100644 index 156db81fdea..00000000000 --- a/build/pkgs/libtheora/distros/opensuse.txt +++ /dev/null @@ -1 +0,0 @@ -pkgconfig(theora) diff --git a/build/pkgs/libtheora/distros/repology.txt b/build/pkgs/libtheora/distros/repology.txt deleted file mode 100644 index 944587f5d50..00000000000 --- a/build/pkgs/libtheora/distros/repology.txt +++ /dev/null @@ -1 +0,0 @@ -libtheora diff --git a/build/pkgs/libtheora/distros/void.txt b/build/pkgs/libtheora/distros/void.txt deleted file mode 100644 index cc4b4b3d8be..00000000000 --- a/build/pkgs/libtheora/distros/void.txt +++ /dev/null @@ -1 +0,0 @@ -libtheora-devel diff --git a/build/pkgs/libtheora/package-version.txt b/build/pkgs/libtheora/package-version.txt deleted file mode 100644 index 524cb55242b..00000000000 --- a/build/pkgs/libtheora/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -1.1.1 diff --git a/build/pkgs/libtheora/spkg-install.in b/build/pkgs/libtheora/spkg-install.in deleted file mode 100644 index b1f58b44681..00000000000 --- a/build/pkgs/libtheora/spkg-install.in +++ /dev/null @@ -1,24 +0,0 @@ -cd src - -./configure \ - --prefix="$SAGE_LOCAL" \ - --libdir="$SAGE_LOCAL/lib" \ - --with-ogg="$SAGE_LOCAL" -if [ $? -ne 0 ]; then - echo "Error configuring libtheora" - exit 1 -fi - -$MAKE -if [ $? -ne 0 ]; then - echo "Error building libtheora" - exit 1 -fi - -$MAKE -j1 install -if [ $? -ne 0 ]; then - echo "Error installing libtheora" - exit 1 -fi - -cp examples/.libs/png2theora $SAGE_LOCAL/bin diff --git a/build/pkgs/libtheora/type b/build/pkgs/libtheora/type deleted file mode 100644 index 9839eb20815..00000000000 --- a/build/pkgs/libtheora/type +++ /dev/null @@ -1 +0,0 @@ -experimental From d13ef9c9bdee940018667ec9993271a2a5f8d13b Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 20 Dec 2024 18:34:01 +0800 Subject: [PATCH 15/69] Improve Meson CI workflow --- .github/workflows/ci-meson.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-meson.yml b/.github/workflows/ci-meson.yml index 41e5f7f5ff8..34e9c659b25 100644 --- a/.github/workflows/ci-meson.yml +++ b/.github/workflows/ci-meson.yml @@ -69,7 +69,12 @@ jobs: export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" export CC="ccache $CC" export CXX="ccache $CXX" - pip install --no-build-isolation --config-settings=builddir=builddir . -v + # Use --no-deps and pip check below to verify that all necessary dependencies are installed via conda + pip install --no-build-isolation --no-deps --config-settings=builddir=builddir . -v + + - name: Verify dependencies + shell: bash -l {0} + run: pip check - name: Test shell: bash -l {0} @@ -77,3 +82,10 @@ jobs: # We don't install sage_setup, so don't try to test it rm -R ./src/sage_setup/ ./sage -t --all -p4 + + - name: Upload log + uses: actions/upload-artifact@v4.5.0 + if: failure() + with: + name: ${{ runner.os }}-meson-${{ matrix.python }}-log + path: builddir/meson-logs/ From 67e2f801dc8c1e958b2cf982dd6a797c96a962b9 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sat, 21 Dec 2024 10:38:33 +0100 Subject: [PATCH 16/69] Fix test failure with giac 1.9.0.998 --- src/sage/libs/giac/giac.pyx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/sage/libs/giac/giac.pyx b/src/sage/libs/giac/giac.pyx index 65279b16504..7c32771bee8 100644 --- a/src/sage/libs/giac/giac.pyx +++ b/src/sage/libs/giac/giac.pyx @@ -382,13 +382,8 @@ def _giac(s): sage: (1+2*sin(3*x)).solve(x).simplify() ...list[-pi/18,7*pi/18] - sage: libgiac.solve('sin(3*x)>2*sin(x)',x) - Traceback (most recent call last): - ... - RuntimeError: Unable to find numeric values solving equation. For - trigonometric equations this may be solved using assumptions, e.g. - assume(x>-pi && xx',x) + list[((x>(-sqrt(2))) and (x<0)),x>(sqrt(2))] You can also add some hypothesis to a giac symbol:: From 45f73f3e85bb3498e5edd039d83431d227dbd64c Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sat, 21 Dec 2024 21:51:25 +0900 Subject: [PATCH 17/69] Refactor argument processing --- src/sage/databases/cremona.py | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/sage/databases/cremona.py b/src/sage/databases/cremona.py index ca859214155..e257cfccfbd 100644 --- a/src/sage/databases/cremona.py +++ b/src/sage/databases/cremona.py @@ -1682,21 +1682,40 @@ def CremonaDatabase(name=None, mini=None, set_global=None): FeatureNotPresentError: database_should_not_exist_ellcurve is not available. '...db' not found in any of [...] ...Further installation instructions might be available at https://github.com/JohnCremona/ecdata. + + Verify that :issue:`39072` has been resolved:: + + sage: C = CremonaDatabase(mini=False) # optional - !database_cremona_ellcurve + Traceback (most recent call last): + ... + ValueError: full Cremona database is not available; run "sage -i database_cremona_ellcurve" to install it """ if set_global is not None: from sage.misc.superseded import deprecation deprecation(25825, "the set_global argument for CremonaDatabase is deprecated and ignored") + if name is None: - if DatabaseCremona().is_present(): - name = 'cremona' - else: + if mini is None: + if DatabaseCremona().is_present(): + name = 'cremona' + mini = False + else: + name = 'cremona mini' + mini = True + elif mini: name = 'cremona mini' - if name == 'cremona': - mini = False + else: + if not DatabaseCremona().is_present(): + raise ValueError('full Cremona database is not available; ' + 'run "sage -i database_cremona_ellcurve" to install it') + name = 'cremona' elif name == 'cremona mini': mini = True - if mini is None: - raise ValueError('mini must be set as either True or False') + elif name == 'cremona': + mini = False + else: + if mini is None: + raise ValueError('mini must be set as either True or False') if mini: return MiniCremonaDatabase(name) From 432513e16593d6a9efb376288e6c448009eaa74c Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sun, 22 Dec 2024 15:21:27 +0900 Subject: [PATCH 18/69] Rephrase the warning message --- src/sage/databases/cremona.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/databases/cremona.py b/src/sage/databases/cremona.py index e257cfccfbd..c1c97cfac16 100644 --- a/src/sage/databases/cremona.py +++ b/src/sage/databases/cremona.py @@ -1688,7 +1688,7 @@ def CremonaDatabase(name=None, mini=None, set_global=None): sage: C = CremonaDatabase(mini=False) # optional - !database_cremona_ellcurve Traceback (most recent call last): ... - ValueError: full Cremona database is not available; run "sage -i database_cremona_ellcurve" to install it + ValueError: full Cremona database is not available; consider using mini Cremona database by mini=True """ if set_global is not None: from sage.misc.superseded import deprecation @@ -1707,7 +1707,7 @@ def CremonaDatabase(name=None, mini=None, set_global=None): else: if not DatabaseCremona().is_present(): raise ValueError('full Cremona database is not available; ' - 'run "sage -i database_cremona_ellcurve" to install it') + 'consider using mini Cremona database by mini=True') name = 'cremona' elif name == 'cremona mini': mini = True From 9a081d702529232eb8b87124c8a98cabb6594977 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 24 Nov 2024 18:25:30 +0700 Subject: [PATCH 19/69] Make Sequence pretty-printed in IPython --- src/sage/repl/display/fancy_repr.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/sage/repl/display/fancy_repr.py b/src/sage/repl/display/fancy_repr.py index 044f8e3f6b2..05a6113fcb6 100644 --- a/src/sage/repl/display/fancy_repr.py +++ b/src/sage/repl/display/fancy_repr.py @@ -117,10 +117,12 @@ def __init__(self): del type_repr[types.BuiltinFunctionType] del type_repr[types.FunctionType] del type_repr[str] + from sage.structure.sequence import Sequence_generic + type_repr[Sequence_generic] = type_repr[list] self._type_repr = type_repr def __call__(self, obj, p, cycle): - """ + r""" Format object. INPUT: @@ -142,6 +144,11 @@ def __call__(self, obj, p, cycle): sage: pp = SomeIPythonRepr() sage: pp.format_string(set([1, 2, 3])) '{1, 2, 3}' + + TESTS:: + + sage: pp.format_string(Sequence([[1]*20, [2]*20])) + '[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]]' """ try: pretty_repr = self._type_repr[type(obj)] @@ -218,7 +225,7 @@ class PlainPythonRepr(ObjectReprABC): def __call__(self, obj, p, cycle): r""" - Format matrix. + Format object. INPUT: From 061c9f7841ddfbb17b3ac7eaf18cc3c3fb67013e Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 11 Dec 2024 20:34:40 +0700 Subject: [PATCH 20/69] Fix most of the tests --- src/doc/de/tutorial/programming.rst | 16 +- src/doc/de/tutorial/tour_advanced.rst | 45 +-- src/doc/de/tutorial/tour_linalg.rst | 6 +- src/doc/en/constructions/linear_algebra.rst | 61 ++- .../prep/Quickstarts/Graphs-and-Discrete.rst | 6 +- .../en/prep/Quickstarts/Linear-Algebra.rst | 5 +- .../level_one_forms.rst | 31 +- .../modabvar.rst | 6 +- .../modular_forms_and_hecke_operators.rst | 26 +- .../nf_galois_groups.rst | 26 +- src/doc/en/tutorial/programming.rst | 16 +- src/doc/en/tutorial/tour_advanced.rst | 45 +-- src/doc/en/tutorial/tour_linalg.rst | 6 +- src/doc/es/tutorial/tour_linalg.rst | 6 +- src/doc/fr/tutorial/programming.rst | 16 +- src/doc/fr/tutorial/tour_advanced.rst | 45 +-- src/doc/fr/tutorial/tour_linalg.rst | 6 +- src/doc/ja/tutorial/programming.rst | 16 +- src/doc/ja/tutorial/tour_advanced.rst | 45 +-- src/doc/ja/tutorial/tour_linalg.rst | 6 +- src/doc/pt/tutorial/programming.rst | 16 +- src/doc/pt/tutorial/tour_advanced.rst | 45 +-- src/doc/pt/tutorial/tour_linalg.rst | 6 +- src/doc/ru/tutorial/programming.rst | 16 +- src/doc/ru/tutorial/tour_advanced.rst | 45 +-- src/doc/ru/tutorial/tour_linalg.rst | 6 +- src/sage/calculus/wester.py | 23 +- src/sage/categories/pushout.py | 20 +- src/sage/coding/linear_code.py | 8 +- src/sage/coding/linear_code_no_metric.py | 10 +- .../hyperplane_arrangement/hyperplane.py | 5 +- src/sage/geometry/lattice_polytope.py | 121 +++--- src/sage/geometry/toric_lattice.py | 20 +- src/sage/graphs/generic_graph.py | 275 +++++++------ src/sage/matrix/matrix2.pyx | 377 +++++++++--------- src/sage/matrix/matrix_integer_dense.pyx | 16 +- src/sage/matrix/matrix_rational_dense.pyx | 18 +- src/sage/misc/functional.py | 16 +- src/sage/modular/abvar/abvar.py | 255 ++++++------ .../modular/abvar/abvar_ambient_jacobian.py | 20 +- src/sage/modular/abvar/homology.py | 35 +- src/sage/modular/abvar/homspace.py | 34 +- src/sage/modular/abvar/morphism.py | 4 +- src/sage/modular/abvar/torsion_subgroup.py | 6 +- .../modular/arithgroup/arithgroup_perm.py | 26 +- src/sage/modular/dirichlet.py | 42 +- src/sage/modular/hecke/ambient_module.py | 10 +- src/sage/modular/hecke/hecke_operator.py | 12 +- src/sage/modular/hecke/module.py | 69 ++-- src/sage/modular/hecke/submodule.py | 11 +- src/sage/modular/local_comp/local_comp.py | 64 +-- src/sage/modular/modform/ambient.py | 117 +++--- src/sage/modular/modform/ambient_g1.py | 11 +- src/sage/modular/modform/constructor.py | 29 +- .../modular/modform/cuspidal_submodule.py | 53 +-- .../modular/modform/eisenstein_submodule.py | 118 ++---- src/sage/modular/modform/element.py | 52 +-- .../modular/modform/hecke_operator_on_qexp.py | 7 +- src/sage/modular/modform/numerical.py | 55 +-- src/sage/modular/modform/ring.py | 8 +- src/sage/modular/modform/space.py | 280 +++++-------- src/sage/modular/modform/vm_basis.py | 48 +-- src/sage/modular/modsym/modsym.py | 32 +- src/sage/modular/modsym/space.py | 80 +--- src/sage/modular/quatalg/brandt.py | 8 +- src/sage/modular/ssmod/ssmod.py | 23 +- src/sage/modules/free_module.py | 109 +---- src/sage/modules/free_module_morphism.py | 18 +- src/sage/modules/free_quadratic_module.py | 6 +- src/sage/modules/matrix_morphism.py | 28 +- src/sage/modules/submodule.py | 5 +- src/sage/rings/finite_rings/homset.py | 56 ++- src/sage/rings/number_field/homset.py | 102 ++--- src/sage/rings/number_field/number_field.py | 359 ++++++++--------- .../rings/number_field/number_field_rel.py | 164 ++++---- src/sage/rings/rational_field.py | 6 +- src/sage/schemes/generic/algebraic_scheme.py | 34 +- src/sage/schemes/toric/divisor.py | 5 +- src/sage/structure/sequence.py | 6 +- src/sage/tensor/modules/comp.py | 12 +- .../tensor/modules/finite_rank_free_module.py | 12 +- src/sage/tests/book_stein_modform.py | 89 ++--- .../judson-abstract-algebra/galois-sage.py | 144 ++++--- .../judson-abstract-algebra/vect-sage.py | 5 +- 84 files changed, 1693 insertions(+), 2454 deletions(-) diff --git a/src/doc/de/tutorial/programming.rst b/src/doc/de/tutorial/programming.rst index ceeed63c84c..02b2d132351 100644 --- a/src/doc/de/tutorial/programming.rst +++ b/src/doc/de/tutorial/programming.rst @@ -263,15 +263,9 @@ aussehen könnten. Hier sind einige Beispiele: sqrt(2) sage: V = VectorSpace(QQ,2) sage: V.basis() - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: basis(V) - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: M = MatrixSpace(GF(7), 2); M Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 sage: A = M([1,2,3,4]); A @@ -425,11 +419,7 @@ Vektorräumen. Es ist wichtig, dass sie nicht verändert werden können. :: sage: V = QQ^3; B = V.basis(); B - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] sage: type(B) sage: B[0] = B[1] diff --git a/src/doc/de/tutorial/tour_advanced.rst b/src/doc/de/tutorial/tour_advanced.rst index 7ee92b357df..56523ae5650 100644 --- a/src/doc/de/tutorial/tour_advanced.rst +++ b/src/doc/de/tutorial/tour_advanced.rst @@ -20,12 +20,10 @@ die Kurven als irreduzible Komponenten der Vereinigung zurück erhalten. Affine Plane Curve over Rational Field defined by x^5 + x^3*y^2 + x^2*y^3 + y^5 - x^3 - y^3 - x^2 - y^2 + 1 sage: D.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 + y^2 - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^3 + y^3 - 1 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^2 + y^2 - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^3 + y^3 - 1] Wir können auch alle Punkte im Schnitt der beiden Kurven finden, indem wir diese schneiden und dann die irreduziblen Komponenten berechnen. @@ -36,17 +34,15 @@ wir diese schneiden und dann die irreduziblen Komponenten berechnen. sage: V = C2.intersection(C3) sage: V.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y, - x - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y - 1, - x, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x + y + 2, - 2*y^2 + 4*y + 3 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y, + x - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y - 1, + x, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x + y + 2, + 2*y^2 + 4*y + 3] Also sind zum Beispiel :math:`(1,0)` und :math:`(0,1)` auf beiden Kurven (wie man sofort sieht), genauso wie bestimmte (quadratischen) @@ -333,10 +329,8 @@ Faktorisierung des Moduls entsprechen. [1, 2, 2, 1, 1, 2, 2, 1] sage: G.decomposition() - [ - Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, - Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2 - ] + [Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, + Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2] Als nächstes konstruieren wir die Gruppe der Dirichlet-Charaktere mod 20, jedoch mit Werten in :math:`\QQ(i)`: @@ -465,9 +459,7 @@ Nun berechnen wir ein paar charakteristische Polynome und [-2 0] [ 0 -2] sage: S.q_expansion_basis(10) - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10)] Wir können sogar Räume von Modulsymbolen mit Charakteren berechnen. @@ -487,10 +479,7 @@ Wir können sogar Räume von Modulsymbolen mit Charakteren berechnen. sage: S.T(2).charpoly('x').factor() (x + zeta6 + 1)^2 sage: S.q_expansion_basis(10) - [ - q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 - + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10) - ] + [q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10)] Hier ist ein weiteres Beispiel davon wie Sage mit den Operationen von Hecke-Operatoren auf dem Raum von Modulformen rechnen kann. diff --git a/src/doc/de/tutorial/tour_linalg.rst b/src/doc/de/tutorial/tour_linalg.rst index 1be6540c89e..319d038c65d 100644 --- a/src/doc/de/tutorial/tour_linalg.rst +++ b/src/doc/de/tutorial/tour_linalg.rst @@ -63,11 +63,7 @@ Sage kann auch Eigenwerte und Eigenvektoren berechnen:: [-2*I, 2*I] sage: B = matrix([[1, 3], [3, 1]]) sage: B.eigenvectors_left() - [(4, [ - (1, 1) - ], 1), (-2, [ - (1, -1) - ], 1)] + [(4, [(1, 1)], 1), (-2, [(1, -1)], 1)] (Die Syntax der Ausgabe von ``eigenvectors_left`` ist eine Liste von Tripeln: (Eigenwert, Eigenvektor, Vielfachheit).) Eigenwerte und diff --git a/src/doc/en/constructions/linear_algebra.rst b/src/doc/en/constructions/linear_algebra.rst index b25cdf94634..4327dedb0c1 100644 --- a/src/doc/en/constructions/linear_algebra.rst +++ b/src/doc/en/constructions/linear_algebra.rst @@ -22,10 +22,7 @@ one can create a subspace. Note the basis computed by Sage is sage: V = VectorSpace(GF(2),8) sage: S = V.subspace([V([1,1,0,0,0,0,0,0]),V([1,0,0,0,0,1,1,0])]) sage: S.basis() - [ - (1, 0, 0, 0, 0, 1, 1, 0), - (0, 1, 0, 0, 0, 1, 1, 0) - ] + [(1, 0, 0, 0, 0, 1, 1, 0), (0, 1, 0, 0, 0, 1, 1, 0)] sage: S.dimension() 2 @@ -205,26 +202,21 @@ gives matrices :math:`D` and :math:`P` such that :math:`AP=PD` (resp. sage: A.eigenvalues() [3, 2, 1] sage: A.eigenvectors_right() - [(3, [ - (0, 0, 1) - ], 1), (2, [ - (1, 1, 0) - ], 1), (1, [ - (1, 0, 0) - ], 1)] + [(3, [(0, 0, 1)], 1), (2, [(1, 1, 0)], 1), (1, [(1, 0, 0)], 1)] sage: A.eigenspaces_right() - [ - (3, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [0 0 1]), - (2, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [1 1 0]), - (1, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [1 0 0]) - ] + [(3, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [0 0 1]), + (2, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [1 1 0]), + (1, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [1 0 0])] sage: D, P = A.eigenmatrix_right() sage: D @@ -256,20 +248,19 @@ floating point entries (over ``CDF`` and ``RDF``) can be obtained with the sage: MS = MatrixSpace(QQ, 2, 2) sage: A = MS([1,-4,1, -1]) sage: A.eigenspaces_left(format='all') - [ - (-1.732050807568878?*I, Vector space of degree 2 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 -1 - 1.732050807568878?*I]), - (1.732050807568878?*I, Vector space of degree 2 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 -1 + 1.732050807568878?*I]) - ] + [(-1.732050807568878?*I, + Vector space of degree 2 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 -1 - 1.732050807568878?*I]), + (1.732050807568878?*I, + Vector space of degree 2 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 -1 + 1.732050807568878?*I])] sage: A.eigenspaces_left(format='galois') - [ - (a0, Vector space of degree 2 and dimension 1 over Number Field in a0 with defining polynomial x^2 + 3 - User basis matrix: - [ 1 a0 - 1]) - ] + [(a0, + Vector space of degree 2 and dimension 1 over Number Field in a0 with defining polynomial x^2 + 3 + User basis matrix: + [ 1 a0 - 1])] Another approach is to use the interface with Maxima: diff --git a/src/doc/en/prep/Quickstarts/Graphs-and-Discrete.rst b/src/doc/en/prep/Quickstarts/Graphs-and-Discrete.rst index 771198b48d2..9917bd45e57 100644 --- a/src/doc/en/prep/Quickstarts/Graphs-and-Discrete.rst +++ b/src/doc/en/prep/Quickstarts/Graphs-and-Discrete.rst @@ -325,11 +325,7 @@ Start with a generator matrix over :math:`\ZZ/2\ZZ`. :: sage: D.basis() - [ - (1, 0, 1, 0, 1, 0, 1), - (0, 1, 1, 0, 0, 1, 1), - (0, 0, 0, 1, 1, 1, 1) - ] + [(1, 0, 1, 0, 1, 0, 1), (0, 1, 1, 0, 0, 1, 1), (0, 0, 0, 1, 1, 1, 1)] :: diff --git a/src/doc/en/prep/Quickstarts/Linear-Algebra.rst b/src/doc/en/prep/Quickstarts/Linear-Algebra.rst index 58cb44edd3c..93deaa9842a 100644 --- a/src/doc/en/prep/Quickstarts/Linear-Algebra.rst +++ b/src/doc/en/prep/Quickstarts/Linear-Algebra.rst @@ -256,10 +256,7 @@ of the matrix):: Or we can get the basis vectors explicitly as a list of vectors:: sage: V.basis() - [ - (1, 0, -1/3), - (0, 1, -2/3) - ] + [(1, 0, -1/3), (0, 1, -2/3)] .. note:: Kernels are **vector spaces** and bases are "\ **echelonized**\ " diff --git a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/level_one_forms.rst b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/level_one_forms.rst index e2777d45512..dba40ee090b 100644 --- a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/level_one_forms.rst +++ b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/level_one_forms.rst @@ -47,22 +47,31 @@ rather nice diagonal shape. :: sage: victor_miller_basis(24, 6) - [ - 1 + 52416000*q^3 + 39007332000*q^4 + 6609020221440*q^5 + O(q^6), - q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 + O(q^6), - q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + O(q^6) - ] + [1 + 52416000*q^3 + 39007332000*q^4 + 6609020221440*q^5 + O(q^6), + q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 + O(q^6), + q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + O(q^6)] sage: from sage.modular.dims import dimension_modular_forms sage: dimension_modular_forms(1,200) 17 sage: B = victor_miller_basis(200, 18) #5 seconds sage: B - [ - 1 + 79288314420681734048660707200000*q^17 + O(q^18), - q + 2687602718106772837928968846869*q^17 + O(q^18), - ... - q^16 + 96*q^17 + O(q^18) - ] + [1 + 79288314420681734048660707200000*q^17 + O(q^18), + q + 2687602718106772837928968846869*q^17 + O(q^18), + q^2 + 85789116961248834349485762560*q^17 + O(q^18), + q^3 + 2567045661341737693075080984*q^17 + O(q^18), + q^4 + 71629117222531314878690304*q^17 + O(q^18), + q^5 + 1852433650992110376992650*q^17 + O(q^18), + q^6 + 44081333191517147315712*q^17 + O(q^18), + q^7 + 956892703246212300900*q^17 + O(q^18), + q^8 + 18748755998771700480*q^17 + O(q^18), + q^9 + 327218645736859401*q^17 + O(q^18), + q^10 + 5001104379048960*q^17 + O(q^18), + q^11 + 65427591611128*q^17 + O(q^18), + q^12 + 709488619776*q^17 + O(q^18), + q^13 + 6070433286*q^17 + O(q^18), + q^14 + 37596416*q^17 + O(q^18), + q^15 + 138420*q^17 + O(q^18), + q^16 + 96*q^17 + O(q^18)] Note: Craig Citro has made the above computation an order of magnitude faster in code he has not quite got into Sage yet. diff --git a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/modabvar.rst b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/modabvar.rst index 3c7d2688d18..de3fa3aaad4 100644 --- a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/modabvar.rst +++ b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/modabvar.rst @@ -35,10 +35,8 @@ compute some basic invariants. :: sage: D = J0(39).decomposition(); D - [ - Simple abelian subvariety 39a(1,39) of dimension 1 of J0(39), - Simple abelian subvariety 39b(1,39) of dimension 2 of J0(39) - ] + [Simple abelian subvariety 39a(1,39) of dimension 1 of J0(39), + Simple abelian subvariety 39b(1,39) of dimension 2 of J0(39)] sage: D[1].lattice() Free module of degree 6 and rank 4 over Integer Ring Echelon basis matrix: diff --git a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/modular_forms_and_hecke_operators.rst b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/modular_forms_and_hecke_operators.rst index 4d223f282d3..0914cc949fa 100644 --- a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/modular_forms_and_hecke_operators.rst +++ b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/modular_forms_and_hecke_operators.rst @@ -142,13 +142,11 @@ and :math:`k` is the weight. sage: S = CuspForms(Gamma0(25),4, prec=15); S Cuspidal subspace of dimension 5 of Modular Forms space ... sage: S.basis() - [ - q + q^9 - 8*q^11 - 8*q^14 + O(q^15), - q^2 - q^7 - q^8 - 7*q^12 + 7*q^13 + O(q^15), - q^3 + q^7 - 2*q^8 - 6*q^12 - 5*q^13 + O(q^15), - q^4 - q^6 - 3*q^9 + 5*q^11 - 2*q^14 + O(q^15), - q^5 - 4*q^10 + O(q^15) - ] + [q + q^9 - 8*q^11 - 8*q^14 + O(q^15), + q^2 - q^7 - q^8 - 7*q^12 + 7*q^13 + O(q^15), + q^3 + q^7 - 2*q^8 - 6*q^12 - 5*q^13 + O(q^15), + q^4 - q^6 - 3*q^9 + 5*q^11 - 2*q^14 + O(q^15), + q^5 - 4*q^10 + O(q^15)] Dimension Formulas ~~~~~~~~~~~~~~~~~~ @@ -200,9 +198,7 @@ described later. :: sage: CuspForms(DirichletGroup(5).0, 5).basis() - [ - q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - ... + O(q^6) - ] + [q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - 14*zeta4*q^4 + (15*zeta4 + 20)*q^5 + O(q^6)] Dirichlet Characters @@ -296,12 +292,10 @@ Hecke operator :math:`T_n`, and to compute the subspace sage: M = ModularForms(Gamma0(11),4) sage: M.basis() - [ - q + 3*q^3 - 6*q^4 - 7*q^5 + O(q^6), - q^2 - 4*q^3 + 2*q^4 + 8*q^5 + O(q^6), - 1 + O(q^6), - q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6) - ] + [q + 3*q^3 - 6*q^4 - 7*q^5 + O(q^6), + q^2 - 4*q^3 + 2*q^4 + 8*q^5 + O(q^6), + 1 + O(q^6), + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6)] sage: M.hecke_matrix(2) [0 2 0 0] [1 2 0 0] diff --git a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/nf_galois_groups.rst b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/nf_galois_groups.rst index 9e5b3b8fbf0..753b16b564a 100644 --- a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/nf_galois_groups.rst +++ b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/nf_galois_groups.rst @@ -101,20 +101,18 @@ You can also enumerate all complex embeddings of a number field: :: sage: K.complex_embeddings() - [ - Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Complex Field with 53 bits of precision - Defn: a |--> -0.629960524947437 - 1.09112363597172*I, - Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Complex Field with 53 bits of precision - Defn: a |--> -0.629960524947437 + 1.09112363597172*I, - Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Complex Field with 53 bits of precision - Defn: a |--> 1.25992104989487 - ] + [Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Complex Field with 53 bits of precision + Defn: a |--> -0.629960524947437 - 1.09112363597172*I, + Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Complex Field with 53 bits of precision + Defn: a |--> -0.629960524947437 + 1.09112363597172*I, + Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Complex Field with 53 bits of precision + Defn: a |--> 1.25992104989487] Class Numbers and Class Groups diff --git a/src/doc/en/tutorial/programming.rst b/src/doc/en/tutorial/programming.rst index 7e4fd9b3468..08c6ac267dd 100644 --- a/src/doc/en/tutorial/programming.rst +++ b/src/doc/en/tutorial/programming.rst @@ -248,15 +248,9 @@ examples. sqrt(2) sage: V = VectorSpace(QQ,2) sage: V.basis() - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: basis(V) - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: M = MatrixSpace(GF(7), 2); M Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 sage: A = M([1,2,3,4]); A @@ -407,11 +401,7 @@ sequences, since it's important that you don't change them. :: sage: V = QQ^3; B = V.basis(); B - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] sage: type(B) sage: B[0] = B[1] diff --git a/src/doc/en/tutorial/tour_advanced.rst b/src/doc/en/tutorial/tour_advanced.rst index a34bb01f5e4..da3dd7fc4c5 100644 --- a/src/doc/en/tutorial/tour_advanced.rst +++ b/src/doc/en/tutorial/tour_advanced.rst @@ -20,12 +20,10 @@ of the union. Affine Plane Curve over Rational Field defined by x^5 + x^3*y^2 + x^2*y^3 + y^5 - x^3 - y^3 - x^2 - y^2 + 1 sage: D.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 + y^2 - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^3 + y^3 - 1 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^2 + y^2 - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^3 + y^3 - 1] We can also find all points of intersection of the two curves by intersecting them and computing the irreducible components. @@ -36,17 +34,15 @@ intersecting them and computing the irreducible components. sage: V = C2.intersection(C3) sage: V.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y, - x - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y - 1, - x, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x + y + 2, - 2*y^2 + 4*y + 3 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y, + x - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y - 1, + x, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x + y + 2, + 2*y^2 + 4*y + 3] Thus, e.g., :math:`(1,0)` and :math:`(0,1)` are on both curves (visibly clear), as are certain (quadratic) points whose @@ -331,10 +327,8 @@ factorization of the modulus. [1, 2, 2, 1, 1, 2, 2, 1] sage: G.decomposition() - [ - Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, - Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2 - ] + [Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, + Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2] Next, we construct the group of Dirichlet characters mod 20, but with values in :math:`\QQ(i)`: @@ -462,9 +456,7 @@ Let's compute some characteristic polynomials and [-2 0] [ 0 -2] sage: S.q_expansion_basis(10) - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10)] We can even compute spaces of modular symbols with character. @@ -484,10 +476,7 @@ We can even compute spaces of modular symbols with character. sage: S.T(2).charpoly('x').factor() (x + zeta6 + 1)^2 sage: S.q_expansion_basis(10) - [ - q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 - + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10) - ] + [q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10)] Here is another example of how Sage can compute the action of Hecke operators on a space of modular forms. diff --git a/src/doc/en/tutorial/tour_linalg.rst b/src/doc/en/tutorial/tour_linalg.rst index 84a45f4931b..2cd87af0b97 100644 --- a/src/doc/en/tutorial/tour_linalg.rst +++ b/src/doc/en/tutorial/tour_linalg.rst @@ -63,11 +63,7 @@ Sage can also compute eigenvalues and eigenvectors:: [-2*I, 2*I] sage: B = matrix([[1, 3], [3, 1]]) sage: B.eigenvectors_left() - [(4, [ - (1, 1) - ], 1), (-2, [ - (1, -1) - ], 1)] + [(4, [(1, 1)], 1), (-2, [(1, -1)], 1)] (The syntax for the output of ``eigenvectors_left`` is a list of triples: (eigenvalue, eigenvector, multiplicity).) Eigenvalues and diff --git a/src/doc/es/tutorial/tour_linalg.rst b/src/doc/es/tutorial/tour_linalg.rst index a9b543cca0e..b82b16e2daa 100644 --- a/src/doc/es/tutorial/tour_linalg.rst +++ b/src/doc/es/tutorial/tour_linalg.rst @@ -71,11 +71,7 @@ Sage también puede calcular autovalores ("eigenvalues") y autovectores [-2*I, 2*I] sage: B = matrix([[1, 3], [3, 1]]) sage: B.eigenvectors_left() - [(4, [ - (1, 1) - ], 1), (-2, [ - (1, -1) - ], 1)] + [(4, [(1, 1)], 1), (-2, [(1, -1)], 1)] (La sintaxis de la salida de ``eigenvectors_left`` es una lista de tuplas: (autovalor, autovector, multiplicidad).) Los autovalores diff --git a/src/doc/fr/tutorial/programming.rst b/src/doc/fr/tutorial/programming.rst index 32f465cfc5c..508905bfedf 100644 --- a/src/doc/fr/tutorial/programming.rst +++ b/src/doc/fr/tutorial/programming.rst @@ -260,15 +260,9 @@ ne sont pas claires en notation orientée objet. Voici quelques exemples. sqrt(2) sage: V = VectorSpace(QQ,2) sage: V.basis() - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: basis(V) - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: M = MatrixSpace(GF(7), 2); M Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 sage: A = M([1,2,3,4]); A @@ -420,11 +414,7 @@ mutables, car il ne faut pas les modifier. :: sage: V = QQ^3; B = V.basis(); B - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] sage: type(B) sage: B[0] = B[1] diff --git a/src/doc/fr/tutorial/tour_advanced.rst b/src/doc/fr/tutorial/tour_advanced.rst index c6a0f2078e8..70ece3bc944 100644 --- a/src/doc/fr/tutorial/tour_advanced.rst +++ b/src/doc/fr/tutorial/tour_advanced.rst @@ -20,12 +20,10 @@ en tant que composante irréductible de la réunion. Affine Plane Curve over Rational Field defined by x^5 + x^3*y^2 + x^2*y^3 + y^5 - x^3 - y^3 - x^2 - y^2 + 1 sage: D.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 + y^2 - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^3 + y^3 - 1 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^2 + y^2 - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^3 + y^3 - 1] Nous pouvons également trouver tous les points d'intersection des deux courbes en les intersectant et en calculant les composantes @@ -37,17 +35,15 @@ irréductibles. sage: V = C2.intersection(C3) sage: V.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y, - x - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y - 1, - x, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x + y + 2, - 2*y^2 + 4*y + 3 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y, + x - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y - 1, + x, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x + y + 2, + 2*y^2 + 4*y + 3] Ainsi, par exemple, :math:`(1,0)` et :math:`(0,1)` appartiennent aux deux courbes (ce dont on pouvait directement s'apercevoir) ; il en va de même des @@ -332,10 +328,8 @@ caractères, de même qu'une décomposition en produit direct correspondant [1, 2, 2, 1, 1, 2, 2, 1] sage: G.decomposition() - [ - Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, - Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2 - ] + [Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, + Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2] Construisons à present le groupe de caractères de Dirichlet modulo 20, mais à valeur dans :math:`\QQ(i)`: @@ -462,9 +456,7 @@ Calculons quelques polynômes caractéristiques et développements en série de [-2 0] [ 0 -2] sage: S.q_expansion_basis(10) - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10)] On peut même calculer des espaces de formes modulaires avec caractères. @@ -484,10 +476,7 @@ On peut même calculer des espaces de formes modulaires avec caractères. sage: S.T(2).charpoly('x').factor() (x + zeta6 + 1)^2 sage: S.q_expansion_basis(10) - [ - q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 - + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10) - ] + [q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10)] Voici un autre exemple montrant comment Sage peut calculer l'action d'un opérateur de Hecke sur un espace de formes modulaires. diff --git a/src/doc/fr/tutorial/tour_linalg.rst b/src/doc/fr/tutorial/tour_linalg.rst index 582a915edef..96fea700391 100644 --- a/src/doc/fr/tutorial/tour_linalg.rst +++ b/src/doc/fr/tutorial/tour_linalg.rst @@ -63,11 +63,7 @@ Sage sait aussi calculer les valeurs propres et vecteurs propres:: [-2*I, 2*I] sage: B = matrix([[1, 3], [3, 1]]) sage: B.eigenvectors_left() - [(4, [ - (1, 1) - ], 1), (-2, [ - (1, -1) - ], 1)] + [(4, [(1, 1)], 1), (-2, [(1, -1)], 1)] (La sortie de ``eigenvectors_left`` est une liste de triplets (valeur propre, vecteur propre, multiplicité).) Sur ``QQ`` et ``RR``, on peut aussi utiliser diff --git a/src/doc/ja/tutorial/programming.rst b/src/doc/ja/tutorial/programming.rst index 1880cbd6d23..2b978c2f6a8 100644 --- a/src/doc/ja/tutorial/programming.rst +++ b/src/doc/ja/tutorial/programming.rst @@ -222,15 +222,9 @@ Sageでは,さらに多様な型が加わる. sqrt(2) sage: V = VectorSpace(QQ,2) sage: V.basis() - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: basis(V) - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: M = MatrixSpace(GF(7), 2); M Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 sage: A = M([1,2,3,4]); A @@ -387,11 +381,7 @@ Sageで使われる第三のリスト類似データ型が,シーケンスで :: sage: V = QQ^3; B = V.basis(); B - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] sage: type(B) sage: B[0] = B[1] diff --git a/src/doc/ja/tutorial/tour_advanced.rst b/src/doc/ja/tutorial/tour_advanced.rst index 8ca8ce5660c..6b8ed96904a 100644 --- a/src/doc/ja/tutorial/tour_advanced.rst +++ b/src/doc/ja/tutorial/tour_advanced.rst @@ -20,12 +20,10 @@ Sageでは,任意の代数多様体を定義することができるが,そ Affine Plane Curve over Rational Field defined by x^5 + x^3*y^2 + x^2*y^3 + y^5 - x^3 - y^3 - x^2 - y^2 + 1 sage: D.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 + y^2 - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^3 + y^3 - 1 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^2 + y^2 - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^3 + y^3 - 1] 以上の2本の曲線の交わりを取れば,全ての交点を求めてその既約成分を計算することもできる. @@ -36,17 +34,15 @@ Sageでは,任意の代数多様体を定義することができるが,そ sage: V = C2.intersection(C3) sage: V.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y, - x - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y - 1, - x, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x + y + 2, - 2*y^2 + 4*y + 3 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y, + x - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y - 1, + x, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x + y + 2, + 2*y^2 + 4*y + 3] というわけで,点 :math:`(1,0)` および :math:`(0,1)` が双方の曲線上にあるのはすぐ見てとることができるし, :math:`y` 成分が :math:`2y^2 + 4y + 3=0` を満足する(2次の)点についても同じことだ. @@ -313,10 +309,8 @@ Cremonaのデータベースへ直接にアクセスすることも可能だ. [1, 2, 2, 1, 1, 2, 2, 1] sage: G.decomposition() - [ - Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, - Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2 - ] + [Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, + Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2] 次に,mod 20,ただし値が :math:`\QQ(i)` 上に収まるディリクレ指標の群を作成する: @@ -438,9 +432,7 @@ Sageを使ってモジュラー空間の次元,モジュラー・シンポル [-2 0] [ 0 -2] sage: S.q_expansion_basis(10) - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10)] モジュラー・シンボルの空間を,指標を指定して生成することも可能だ. @@ -460,10 +452,7 @@ Sageを使ってモジュラー空間の次元,モジュラー・シンポル sage: S.T(2).charpoly('x').factor() (x + zeta6 + 1)^2 sage: S.q_expansion_basis(10) - [ - q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 - + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10) - ] + [q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10)] 以下の例では,モジュラー形式によって張られる空間に対するHecke演算子の作用を,Sageでどうやって計算するかを示す. diff --git a/src/doc/ja/tutorial/tour_linalg.rst b/src/doc/ja/tutorial/tour_linalg.rst index 227f879136e..5c8de8c1dd1 100644 --- a/src/doc/ja/tutorial/tour_linalg.rst +++ b/src/doc/ja/tutorial/tour_linalg.rst @@ -70,11 +70,7 @@ Sageは固有値と固有ベクトルの計算もしてくれる: [-2*I, 2*I] sage: B = matrix([[1, 3], [3, 1]]) sage: B.eigenvectors_left() - [(4, [ - (1, 1) - ], 1), (-2, [ - (1, -1) - ], 1)] + [(4, [(1, 1)], 1), (-2, [(1, -1)], 1)] ( ``eigenvectors_left`` の出力は,三つ組タプル(固有値,固有ベクトル,多重度)のリストになっている.) diff --git a/src/doc/pt/tutorial/programming.rst b/src/doc/pt/tutorial/programming.rst index ea1d6b2e348..51965d03671 100644 --- a/src/doc/pt/tutorial/programming.rst +++ b/src/doc/pt/tutorial/programming.rst @@ -275,15 +275,9 @@ exemplos. sqrt(2) sage: V = VectorSpace(QQ,2) sage: V.basis() - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: basis(V) - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: M = MatrixSpace(GF(7), 2); M Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 sage: A = M([1,2,3,4]); A @@ -433,11 +427,7 @@ imutáveis, pois é importante que elas não sejam modificadas. :: sage: V = QQ^3; B = V.basis(); B - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] sage: type(B) sage: B[0] = B[1] diff --git a/src/doc/pt/tutorial/tour_advanced.rst b/src/doc/pt/tutorial/tour_advanced.rst index 075b3b1551e..5a8fdd04de9 100644 --- a/src/doc/pt/tutorial/tour_advanced.rst +++ b/src/doc/pt/tutorial/tour_advanced.rst @@ -20,12 +20,10 @@ componentes irredutíveis da união. Affine Plane Curve over Rational Field defined by x^5 + x^3*y^2 + x^2*y^3 + y^5 - x^3 - y^3 - x^2 - y^2 + 1 sage: D.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 + y^2 - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^3 + y^3 - 1 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^2 + y^2 - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^3 + y^3 - 1] Você também pode encontrar todos os pontos de interseção das duas curvas, intersectando-as, e então calculando as componentes @@ -37,17 +35,15 @@ irredutíveis. sage: V = C2.intersection(C3) sage: V.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y, - x - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y - 1, - x, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x + y + 2, - 2*y^2 + 4*y + 3 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y, + x - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y - 1, + x, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x + y + 2, + 2*y^2 + 4*y + 3] Portanto, por exemplo, :math:`(1,0)` e :math:`(0,1)` estão em ambas as curvas (o que é claramente visível), como também estão certos pontos @@ -332,10 +328,8 @@ módulo. [1, 2, 2, 1, 1, 2, 2, 1] sage: G.decomposition() - [ - Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, - Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2 - ] + [Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, + Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2] A seguir, construímos o grupo de caracteres de Dirichlet mod 20, mas com valores em :math:`\QQ(i)`: @@ -463,9 +457,7 @@ Vamos calcular alguns polinômios característicos e expansões [-2 0] [ 0 -2] sage: S.q_expansion_basis(10) - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10)] Podemos até mesmo calcular espaços de símbolos modulares com carácter. @@ -485,10 +477,7 @@ Podemos até mesmo calcular espaços de símbolos modulares com carácter. sage: S.T(2).charpoly('x').factor() (x + zeta6 + 1)^2 sage: S.q_expansion_basis(10) - [ - q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 - + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10) - ] + [q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10)] Aqui está um outro exemplo de como o Sage pode calcular a ação de operadores de Hecke em um espaço de formas modulares. diff --git a/src/doc/pt/tutorial/tour_linalg.rst b/src/doc/pt/tutorial/tour_linalg.rst index 806a36c6446..bf79f9a16a2 100644 --- a/src/doc/pt/tutorial/tour_linalg.rst +++ b/src/doc/pt/tutorial/tour_linalg.rst @@ -61,11 +61,7 @@ O Sage também pode calcular autovalores e autovetores:: [-2*I, 2*I] sage: B = matrix([[1, 3], [3, 1]]) sage: B.eigenvectors_left() - [(4, [ - (1, 1) - ], 1), (-2, [ - (1, -1) - ], 1)] + [(4, [(1, 1)], 1), (-2, [(1, -1)], 1)] (A sintaxe para a resposta de ``eigenvectors_left`` é uma lista com três componentes: (autovalor, autovetor, multiplicidade).) Autovalores diff --git a/src/doc/ru/tutorial/programming.rst b/src/doc/ru/tutorial/programming.rst index 0ea10634c0b..c8caf6ade63 100644 --- a/src/doc/ru/tutorial/programming.rst +++ b/src/doc/ru/tutorial/programming.rst @@ -242,15 +242,9 @@ C и обработан компилятором C. sqrt(2) sage: V = VectorSpace(QQ,2) sage: V.basis() - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: basis(V) - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] sage: M = MatrixSpace(GF(7), 2); M Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 sage: A = M([1,2,3,4]); A @@ -395,11 +389,7 @@ Python, сработает нормально. :: sage: V = QQ^3; B = V.basis(); B - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] sage: type(B) sage: B[0] = B[1] diff --git a/src/doc/ru/tutorial/tour_advanced.rst b/src/doc/ru/tutorial/tour_advanced.rst index 69eb42dfd4c..1420053e93b 100644 --- a/src/doc/ru/tutorial/tour_advanced.rst +++ b/src/doc/ru/tutorial/tour_advanced.rst @@ -19,12 +19,10 @@ Sage позволяет создавать любые алгебраически Affine Plane Curve over Rational Field defined by x^5 + x^3*y^2 + x^2*y^3 + y^5 - x^3 - y^3 - x^2 - y^2 + 1 sage: D.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^2 + y^2 - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x^3 + y^3 - 1 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^2 + y^2 - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x^3 + y^3 - 1] Также можно найти все точки пересечения двух кривых. @@ -34,17 +32,15 @@ Sage позволяет создавать любые алгебраически sage: V = C2.intersection(C3) sage: V.irreducible_components() - [ - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y, - x - 1, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - y - 1, - x, - Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: - x + y + 2, - 2*y^2 + 4*y + 3 - ] + [Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y, + x - 1, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + y - 1, + x, + Closed subscheme of Affine Space of dimension 2 over Rational Field defined by: + x + y + 2, + 2*y^2 + 4*y + 3] Таким образом точки :math:`(1,0)` и :math:`(0,1)` находятся на обеих кривых, а координаты по оси :math:`y` удовлетворяют функции :math:`2y^2 + 4y + 3=0`. @@ -296,10 +292,8 @@ Sage может вычислить тороидальный идеал непл [1, 2, 2, 1, 1, 2, 2, 1] sage: G.decomposition() - [ - Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, - Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2 - ] + [Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 6 and degree 2, + Group of Dirichlet characters modulo 7 with values in Cyclotomic Field of order 6 and degree 2] Далее надо построить группу символов Дирихле по модулю 20, но со значениями с :math:`\QQ(i)`: @@ -423,9 +417,7 @@ Sage может выполнять вычисления, связанные с [-2 0] [ 0 -2] sage: S.q_expansion_basis(10) - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10)] Также возможны вычисления пространств модулярных символов с буквами. @@ -445,10 +437,7 @@ Sage может выполнять вычисления, связанные с sage: S.T(2).charpoly('x').factor() (x + zeta6 + 1)^2 sage: S.q_expansion_basis(10) - [ - q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 - + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10) - ] + [q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10)] Пример того, как Sage может вычислять действия операторов Гекке на пространство модулярных форм. diff --git a/src/doc/ru/tutorial/tour_linalg.rst b/src/doc/ru/tutorial/tour_linalg.rst index bf2a1084544..92fd820bb41 100644 --- a/src/doc/ru/tutorial/tour_linalg.rst +++ b/src/doc/ru/tutorial/tour_linalg.rst @@ -56,11 +56,7 @@ Sage может находить собственное число и собст [-2*I, 2*I] sage: B = matrix([[1, 3], [3, 1]]) sage: B.eigenvectors_left() - [(4, [ - (1, 1) - ], 1), (-2, [ - (1, -1) - ], 1)] + [(4, [(1, 1)], 1), (-2, [(1, -1)], 1)] (Результат ``eigenvectors_left`` - это список троек: (собственное число, собственный вектор, многообразие).) Собственные числа и вектора diff --git a/src/sage/calculus/wester.py b/src/sage/calculus/wester.py index e33409a49ac..21c6865d0cb 100644 --- a/src/sage/calculus/wester.py +++ b/src/sage/calculus/wester.py @@ -484,17 +484,18 @@ sage: # (YES) Find the eigenvalues of a 3x3 integer matrix. sage: m = matrix(QQ, 3, [5,-3,-7, -2,1,2, 2,-3,-4]) sage: m.eigenspaces_left() - [ - (3, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 0 -1]), - (1, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 1 -1]), - (-2, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [0 1 1]) - ] + [(3, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 0 -1]), + (1, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 1 -1]), + (-2, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [0 1 1])] :: diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index b67f37ed524..a2b5e910257 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -2263,25 +2263,13 @@ def __eq__(self, other): sage: # needs sage.modules sage: F1.basis - [ - (1, 0, 4), - (0, 1, 2) - ] + [(1, 0, 4), (0, 1, 2)] sage: F2.basis - [ - (1, 2, 3), - (0, 3, 6) - ] + [(1, 2, 3), (0, 3, 6)] sage: F3.basis - [ - (1, 0, -1), - (0, 1, 2) - ] + [(1, 0, -1), (0, 1, 2)] sage: F4.basis - [ - (1, 0, -1), - (0, 1, 2) - ] + [(1, 0, -1), (0, 1, 2)] The basis of ``F2`` is modulo 5 different from the other bases. diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index 3e9d388c434..07527e7e154 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -2301,11 +2301,9 @@ def __init__(self, generator, d=None): ....: [a, a + 1, 1, a + 1, 1, 0, 0]]) sage: C = LinearCode(G) sage: C.basis() - [ - (1, 0, 0, a + 1, 0, 1, 0), - (0, 1, 0, 0, a + 1, 0, 1), - (0, 0, 1, a, a + 1, a, a + 1) - ] + [(1, 0, 0, a + 1, 0, 1, 0), + (0, 1, 0, 0, a + 1, 0, 1), + (0, 0, 1, a, a + 1, a, a + 1)] sage: C.minimum_distance() # needs sage.libs.gap 3 diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index 49c30a415c8..2dbd8ceb1aa 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -397,12 +397,10 @@ def basis(self): sage: C = codes.HammingCode(GF(2), 3) sage: C.basis() - [ - (1, 0, 0, 0, 0, 1, 1), - (0, 1, 0, 0, 1, 0, 1), - (0, 0, 1, 0, 1, 1, 0), - (0, 0, 0, 1, 1, 1, 1) - ] + [(1, 0, 0, 0, 0, 1, 1), + (0, 1, 0, 0, 1, 0, 1), + (0, 0, 1, 0, 1, 1, 0), + (0, 0, 0, 1, 1, 1, 1)] sage: C.basis().universe() Vector space of dimension 7 over Finite Field of size 2 """ diff --git a/src/sage/geometry/hyperplane_arrangement/hyperplane.py b/src/sage/geometry/hyperplane_arrangement/hyperplane.py index 04de307442d..38e0761330b 100644 --- a/src/sage/geometry/hyperplane_arrangement/hyperplane.py +++ b/src/sage/geometry/hyperplane_arrangement/hyperplane.py @@ -353,10 +353,7 @@ def linear_part_projection(self, point): sage: p2 = h.linear_part_projection([3,4,5]); p2 (8/7, 2/7) sage: h.linear_part().basis() - [ - (1, 0, -1/3), - (0, 1, -2/3) - ] + [(1, 0, -1/3), (0, 1, -2/3)] sage: p3 = h.linear_part_projection([1,1,1]); p3 (4/7, 1/7) """ diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 2869dcc7442..0ae3a84fa41 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -1250,11 +1250,9 @@ def _read_nef_partitions(self, data): False sage: o_copy._read_nef_partitions(s) # needs palp sage: o_copy._nef_partitions # needs palp - [ - Nef-partition {0, 1, 3} ⊔ {2, 4, 5}, - Nef-partition {0, 1, 2} ⊔ {3, 4, 5}, - Nef-partition {0, 1, 2, 3} ⊔ {4, 5} - ] + [Nef-partition {0, 1, 3} ⊔ {2, 4, 5}, + Nef-partition {0, 1, 2} ⊔ {3, 4, 5}, + Nef-partition {0, 1, 2, 3} ⊔ {4, 5}] """ if isinstance(data, str): f = StringIO(data) @@ -2710,29 +2708,25 @@ def nef_partitions(self, keep_symmetric=False, keep_products=True, sage: p = lattice_polytope.cross_polytope(4) sage: p.nef_partitions() # needs palp - [ - Nef-partition {0, 1, 4, 5} ⊔ {2, 3, 6, 7} (direct product), - Nef-partition {0, 1, 2, 4} ⊔ {3, 5, 6, 7}, - Nef-partition {0, 1, 2, 4, 5} ⊔ {3, 6, 7}, - Nef-partition {0, 1, 2, 4, 5, 6} ⊔ {3, 7} (direct product), - Nef-partition {0, 1, 2, 3} ⊔ {4, 5, 6, 7}, - Nef-partition {0, 1, 2, 3, 4} ⊔ {5, 6, 7}, - Nef-partition {0, 1, 2, 3, 4, 5} ⊔ {6, 7}, - Nef-partition {0, 1, 2, 3, 4, 5, 6} ⊔ {7} (projection) - ] + [Nef-partition {0, 1, 4, 5} ⊔ {2, 3, 6, 7} (direct product), + Nef-partition {0, 1, 2, 4} ⊔ {3, 5, 6, 7}, + Nef-partition {0, 1, 2, 4, 5} ⊔ {3, 6, 7}, + Nef-partition {0, 1, 2, 4, 5, 6} ⊔ {3, 7} (direct product), + Nef-partition {0, 1, 2, 3} ⊔ {4, 5, 6, 7}, + Nef-partition {0, 1, 2, 3, 4} ⊔ {5, 6, 7}, + Nef-partition {0, 1, 2, 3, 4, 5} ⊔ {6, 7}, + Nef-partition {0, 1, 2, 3, 4, 5, 6} ⊔ {7} (projection)] Now we omit projections:: sage: p.nef_partitions(keep_projections=False) # needs palp - [ - Nef-partition {0, 1, 4, 5} ⊔ {2, 3, 6, 7} (direct product), - Nef-partition {0, 1, 2, 4} ⊔ {3, 5, 6, 7}, - Nef-partition {0, 1, 2, 4, 5} ⊔ {3, 6, 7}, - Nef-partition {0, 1, 2, 4, 5, 6} ⊔ {3, 7} (direct product), - Nef-partition {0, 1, 2, 3} ⊔ {4, 5, 6, 7}, - Nef-partition {0, 1, 2, 3, 4} ⊔ {5, 6, 7}, - Nef-partition {0, 1, 2, 3, 4, 5} ⊔ {6, 7} - ] + [Nef-partition {0, 1, 4, 5} ⊔ {2, 3, 6, 7} (direct product), + Nef-partition {0, 1, 2, 4} ⊔ {3, 5, 6, 7}, + Nef-partition {0, 1, 2, 4, 5} ⊔ {3, 6, 7}, + Nef-partition {0, 1, 2, 4, 5, 6} ⊔ {3, 7} (direct product), + Nef-partition {0, 1, 2, 3} ⊔ {4, 5, 6, 7}, + Nef-partition {0, 1, 2, 3, 4} ⊔ {5, 6, 7}, + Nef-partition {0, 1, 2, 3, 4, 5} ⊔ {6, 7}] Currently Hodge numbers cannot be computed for a given nef-partition:: @@ -2772,21 +2766,17 @@ def nef_partitions(self, keep_symmetric=False, keep_products=True, sage: p = lattice_polytope.cross_polytope(2) sage: p.nef_partitions() # needs palp - [ - Nef-partition {0, 2} ⊔ {1, 3} (direct product), - Nef-partition {0, 1} ⊔ {2, 3}, - Nef-partition {0, 1, 2} ⊔ {3} (projection) - ] + [Nef-partition {0, 2} ⊔ {1, 3} (direct product), + Nef-partition {0, 1} ⊔ {2, 3}, + Nef-partition {0, 1, 2} ⊔ {3} (projection)] sage: p.nef_partitions(keep_symmetric=True) # needs palp - [ - Nef-partition {0, 1, 3} ⊔ {2} (projection), - Nef-partition {0, 2, 3} ⊔ {1} (projection), - Nef-partition {0, 3} ⊔ {1, 2}, - Nef-partition {1, 2, 3} ⊔ {0} (projection), - Nef-partition {1, 3} ⊔ {0, 2} (direct product), - Nef-partition {2, 3} ⊔ {0, 1}, - Nef-partition {0, 1, 2} ⊔ {3} (projection) - ] + [Nef-partition {0, 1, 3} ⊔ {2} (projection), + Nef-partition {0, 2, 3} ⊔ {1} (projection), + Nef-partition {0, 3} ⊔ {1, 2}, + Nef-partition {1, 2, 3} ⊔ {0} (projection), + Nef-partition {1, 3} ⊔ {0, 2} (direct product), + Nef-partition {2, 3} ⊔ {0, 1}, + Nef-partition {0, 1, 2} ⊔ {3} (projection)] Nef-partitions can be computed only for reflexive polytopes:: @@ -2979,10 +2969,8 @@ def normal_form(self, algorithm='palp_native', permutation=False): sage: o = lattice_polytope.cross_polytope(2) sage: o.normal_form(algorithm='palp_modified') # needs sage.groups - M( 1, 0), - M( 0, 1), - M( 0, -1), - M(-1, 0) + Traceback (most recent call last): + ... in 2-d lattice M The following examples demonstrate the speed of the available algorithms. @@ -3192,17 +3180,13 @@ def _palp_modified_normal_form(self, permutation=False): M( 0, -1) in 2-d lattice M sage: o._palp_modified_normal_form() # needs sage.graphs sage.groups - M( 1, 0), - M( 0, 1), - M( 0, -1), - M(-1, 0) + Traceback (most recent call last): + ... in 2-d lattice M sage: o._palp_modified_normal_form(permutation=True) # needs sage.graphs sage.groups - (M( 1, 0), - M( 0, 1), - M( 0, -1), - M(-1, 0) - in 2-d lattice M, (3,4)) + Traceback (most recent call last): + ... + (3,4)) """ PM = self.vertex_facet_pairing_matrix() PM_max = PM.permutation_normal_form() @@ -3293,11 +3277,16 @@ def _palp_PM_max(self, check=False): sage: o = lattice_polytope.cross_polytope(2) sage: PM = o.vertex_facet_pairing_matrix() sage: PM_max = PM.permutation_normal_form() # needs sage.graphs + Traceback (most recent call last): + ... + sage: PM_max == o._palp_PM_max() # needs sage.graphs sage.groups + Traceback (most recent call last): + ... True sage: P2 = ReflexivePolytope(2, 0) sage: PM_max, permutations = P2._palp_PM_max(check=True) # needs sage.groups - sage: PM_max # needs sage.graphs + sage: PM_max # needs sage.graphs sage.groups [3 0 0] [0 3 0] [0 0 3] @@ -3308,7 +3297,7 @@ def _palp_PM_max(self, check=False): [(1,2), (1,2)], [(), ()], [(2,3), (2,3)]] - sage: PM_max.automorphisms_of_rows_and_columns() # needs sage.graphs + sage: PM_max.automorphisms_of_rows_and_columns() # needs sage.graphs sage.groups [((), ()), ((1,2,3), (1,2,3)), ((1,3,2), (1,3,2)), @@ -4135,7 +4124,7 @@ def is_NefPartition(x): sage: o = lattice_polytope.cross_polytope(3) sage: np = o.nef_partitions()[0]; np # needs palp Nef-partition {0, 1, 3} ⊔ {2, 4, 5} - sage: isinstance(np, NefPartition) # needs palp + sage: isinstance(np, NefPartition) # needs palp True """ from sage.misc.superseded import deprecation @@ -4276,13 +4265,11 @@ class NefPartition(SageObject, Hashable): ``nef.x`` program from PALP):: sage: o.nef_partitions() # needs palp - [ - Nef-partition {0, 1, 3} ⊔ {2, 4, 5}, - Nef-partition {0, 1, 3, 4} ⊔ {2, 5} (direct product), - Nef-partition {0, 1, 2} ⊔ {3, 4, 5}, - Nef-partition {0, 1, 2, 3} ⊔ {4, 5}, - Nef-partition {0, 1, 2, 3, 4} ⊔ {5} (projection) - ] + [Nef-partition {0, 1, 3} ⊔ {2, 4, 5}, + Nef-partition {0, 1, 3, 4} ⊔ {2, 5} (direct product), + Nef-partition {0, 1, 2} ⊔ {3, 4, 5}, + Nef-partition {0, 1, 2, 3} ⊔ {4, 5}, + Nef-partition {0, 1, 2, 3, 4} ⊔ {5} (projection)] """ def __init__(self, data, Delta_polar, check=True): @@ -5329,13 +5316,11 @@ def all_nef_partitions(polytopes, keep_symmetric=False): sage: o = lattice_polytope.cross_polytope(3) sage: lattice_polytope.all_nef_partitions([o]) # needs palp sage: o.nef_partitions() # needs palp - [ - Nef-partition {0, 1, 3} ⊔ {2, 4, 5}, - Nef-partition {0, 1, 3, 4} ⊔ {2, 5} (direct product), - Nef-partition {0, 1, 2} ⊔ {3, 4, 5}, - Nef-partition {0, 1, 2, 3} ⊔ {4, 5}, - Nef-partition {0, 1, 2, 3, 4} ⊔ {5} (projection) - ] + [Nef-partition {0, 1, 3} ⊔ {2, 4, 5}, + Nef-partition {0, 1, 3, 4} ⊔ {2, 5} (direct product), + Nef-partition {0, 1, 2} ⊔ {3, 4, 5}, + Nef-partition {0, 1, 2, 3} ⊔ {4, 5}, + Nef-partition {0, 1, 2, 3, 4} ⊔ {5} (projection)] You cannot use this function for non-reflexive polytopes:: diff --git a/src/sage/geometry/toric_lattice.py b/src/sage/geometry/toric_lattice.py index a79bac65c6e..12399603c9d 100644 --- a/src/sage/geometry/toric_lattice.py +++ b/src/sage/geometry/toric_lattice.py @@ -1099,19 +1099,13 @@ class ToricLattice_sublattice_with_basis(ToricLattice_generic, sage: sublattice.has_user_basis() True sage: sublattice.basis() - [ - N(1, 1, 0), - N(3, 2, 1) - ] + [N(1, 1, 0), N(3, 2, 1)] Even if you have provided your own basis, you still can access the "standard" one:: sage: sublattice.echelonized_basis() - [ - N(1, 0, 1), - N(0, 1, -1) - ] + [N(1, 0, 1), N(0, 1, -1)] """ def _repr_(self): @@ -1245,19 +1239,13 @@ class ToricLattice_sublattice(ToricLattice_sublattice_with_basis, sage: sublattice.has_user_basis() False sage: sublattice.basis() - [ - N(1, 0, 1), - N(0, 1, -1) - ] + [N(1, 0, 1), N(0, 1, -1)] For sublattices without user-specified basis, the basis obtained above is the same as the "standard" one:: sage: sublattice.echelonized_basis() - [ - N(1, 0, 1), - N(0, 1, -1) - ] + [N(1, 0, 1), N(0, 1, -1)] """ pass diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 101952109c3..ae1d9bfa4da 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -5361,21 +5361,33 @@ def cycle_basis(self, output='vertex'): A cycle basis in Petersen's Graph :: sage: g = graphs.PetersenGraph() - sage: g.cycle_basis() # needs networkx, random (changes in networkx 3.2) - [[1, 6, 8, 5, 0], [4, 9, 6, 8, 5, 0], [7, 9, 6, 8, 5], - [4, 3, 8, 5, 0], [1, 2, 3, 8, 5, 0], [7, 2, 3, 8, 5]] + sage: g.cycle_basis() # needs networkx + [[6, 8, 5, 7, 9], + [2, 3, 8, 5, 7], + [4, 3, 8, 5, 7, 9], + [4, 0, 5, 7, 9], + [2, 1, 0, 5, 7], + [6, 1, 0, 5, 7, 9]] One can also get the result as a list of lists of edges:: - sage: g.cycle_basis(output='edge') # needs networkx, random (changes in networkx 3.2) - [[(1, 6, None), (6, 8, None), (8, 5, None), (5, 0, None), - (0, 1, None)], [(4, 9, None), (9, 6, None), (6, 8, None), - (8, 5, None), (5, 0, None), (0, 4, None)], [(7, 9, None), - (9, 6, None), (6, 8, None), (8, 5, None), (5, 7, None)], - [(4, 3, None), (3, 8, None), (8, 5, None), (5, 0, None), - (0, 4, None)], [(1, 2, None), (2, 3, None), (3, 8, None), - (8, 5, None), (5, 0, None), (0, 1, None)], [(7, 2, None), - (2, 3, None), (3, 8, None), (8, 5, None), (5, 7, None)]] + sage: g.cycle_basis(output='edge') # needs networkx + [[(6, 8, None), (8, 5, None), (5, 7, None), (7, 9, None), (9, 6, None)], + [(2, 3, None), (3, 8, None), (8, 5, None), (5, 7, None), (7, 2, None)], + [(4, 3, None), + (3, 8, None), + (8, 5, None), + (5, 7, None), + (7, 9, None), + (9, 4, None)], + [(4, 0, None), (0, 5, None), (5, 7, None), (7, 9, None), (9, 4, None)], + [(2, 1, None), (1, 0, None), (0, 5, None), (5, 7, None), (7, 2, None)], + [(6, 1, None), + (1, 0, None), + (0, 5, None), + (5, 7, None), + (7, 9, None), + (9, 6, None)]] Checking the given cycles are algebraically free:: @@ -5550,18 +5562,18 @@ def minimum_cycle_basis(self, algorithm=None, weight_function=None, by_weight=Fa [[1, 2, 3], [1, 2, 3, 4], [5, 6, 7]] sage: sorted(g.minimum_cycle_basis(by_weight=False)) [[1, 2, 3], [1, 3, 4], [5, 6, 7]] - sage: sorted(g.minimum_cycle_basis(by_weight=True, algorithm='NetworkX')) # needs networkx, random (changes in networkx 3.2) - [[1, 2, 3], [1, 2, 3, 4], [5, 6, 7]] - sage: g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX') # needs networkx, random (changes in networkx 3.2) - [[1, 2, 3], [1, 3, 4], [5, 6, 7]] + sage: sorted(g.minimum_cycle_basis(by_weight=True, algorithm='NetworkX')) # needs networkx + [[2, 3, 1], [2, 3, 4, 1], [6, 7, 5]] + sage: g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX') # needs networkx + [[3, 4, 1], [2, 3, 1], [6, 7, 5]] :: sage: g = Graph([(1, 2), (2, 3), (3, 4), (4, 5), (5, 1), (5, 3)]) sage: sorted(g.minimum_cycle_basis(by_weight=False)) [[1, 2, 3, 5], [3, 4, 5]] - sage: sorted(g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX')) # needs networkx, random (changes in networkx 3.2) - [[1, 2, 3, 5], [3, 4, 5]] + sage: sorted(g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX')) # needs networkx + [[3, 4, 5], [5, 3, 2, 1]] TESTS:: @@ -23009,68 +23021,55 @@ def eigenvectors(self, laplacian=False): sage: P = graphs.PetersenGraph() sage: P.eigenvectors() # needs sage.modules sage.rings.number_field - [(3, [ - (1, 1, 1, 1, 1, 1, 1, 1, 1, 1) - ], 1), (-2, [ - (1, 0, 0, 0, -1, -1, -1, 0, 1, 1), - (0, 1, 0, 0, -1, 0, -2, -1, 1, 2), - (0, 0, 1, 0, -1, 1, -1, -2, 0, 2), - (0, 0, 0, 1, -1, 1, 0, -1, -1, 1) - ], 4), (1, [ - (1, 0, 0, 0, 0, 1, -1, 0, 0, -1), - (0, 1, 0, 0, 0, -1, 1, -1, 0, 0), - (0, 0, 1, 0, 0, 0, -1, 1, -1, 0), - (0, 0, 0, 1, 0, 0, 0, -1, 1, -1), - (0, 0, 0, 0, 1, -1, 0, 0, -1, 1) - ], 5)] + [(3, [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)], 1), + (-2, + [(1, 0, 0, 0, -1, -1, -1, 0, 1, 1), + (0, 1, 0, 0, -1, 0, -2, -1, 1, 2), + (0, 0, 1, 0, -1, 1, -1, -2, 0, 2), + (0, 0, 0, 1, -1, 1, 0, -1, -1, 1)], + 4), + (1, + [(1, 0, 0, 0, 0, 1, -1, 0, 0, -1), + (0, 1, 0, 0, 0, -1, 1, -1, 0, 0), + (0, 0, 1, 0, 0, 0, -1, 1, -1, 0), + (0, 0, 0, 1, 0, 0, 0, -1, 1, -1), + (0, 0, 0, 0, 1, -1, 0, 0, -1, 1)], + 5)] Eigenspaces for the Laplacian should be identical since the Petersen graph is regular. However, since the output also contains the eigenvalues, the two outputs are slightly different:: sage: P.eigenvectors(laplacian=True) # needs sage.modules sage.rings.number_field - [(0, [ - (1, 1, 1, 1, 1, 1, 1, 1, 1, 1) - ], 1), (5, [ - (1, 0, 0, 0, -1, -1, -1, 0, 1, 1), - (0, 1, 0, 0, -1, 0, -2, -1, 1, 2), - (0, 0, 1, 0, -1, 1, -1, -2, 0, 2), - (0, 0, 0, 1, -1, 1, 0, -1, -1, 1) - ], 4), (2, [ - (1, 0, 0, 0, 0, 1, -1, 0, 0, -1), - (0, 1, 0, 0, 0, -1, 1, -1, 0, 0), - (0, 0, 1, 0, 0, 0, -1, 1, -1, 0), - (0, 0, 0, 1, 0, 0, 0, -1, 1, -1), - (0, 0, 0, 0, 1, -1, 0, 0, -1, 1) - ], 5)] + [(0, [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)], 1), + (5, + [(1, 0, 0, 0, -1, -1, -1, 0, 1, 1), + (0, 1, 0, 0, -1, 0, -2, -1, 1, 2), + (0, 0, 1, 0, -1, 1, -1, -2, 0, 2), + (0, 0, 0, 1, -1, 1, 0, -1, -1, 1)], + 4), + (2, + [(1, 0, 0, 0, 0, 1, -1, 0, 0, -1), + (0, 1, 0, 0, 0, -1, 1, -1, 0, 0), + (0, 0, 1, 0, 0, 0, -1, 1, -1, 0), + (0, 0, 0, 1, 0, 0, 0, -1, 1, -1), + (0, 0, 0, 0, 1, -1, 0, 0, -1, 1)], + 5)] :: sage: C = graphs.CycleGraph(8) sage: C.eigenvectors() # needs sage.modules sage.rings.number_field - [(2, - [ - (1, 1, 1, 1, 1, 1, 1, 1) - ], - 1), - (-2, - [ - (1, -1, 1, -1, 1, -1, 1, -1) - ], - 1), - (0, - [ - (1, 0, -1, 0, 1, 0, -1, 0), - (0, 1, 0, -1, 0, 1, 0, -1) - ], + [(2, [(1, 1, 1, 1, 1, 1, 1, 1)], 1), + (-2, [(1, -1, 1, -1, 1, -1, 1, -1)], 1), + (0, [(1, 0, -1, 0, 1, 0, -1, 0), (0, 1, 0, -1, 0, 1, 0, -1)], 2), + (-1.414213562373095?, + [(1, 0, -1, 1.414213562373095?, -1, 0, 1, -1.414213562373095?), + (0, 1, -1.414213562373095?, 1, 0, -1, 1.414213562373095?, -1)], 2), - (-1.4142135623..., - [(1, 0, -1, 1.4142135623..., -1, 0, 1, -1.4142135623...), - (0, 1, -1.4142135623..., 1, 0, -1, 1.4142135623..., -1)], - 2), - (1.4142135623..., - [(1, 0, -1, -1.4142135623..., -1, 0, 1, 1.4142135623...), - (0, 1, 1.4142135623..., 1, 0, -1, -1.4142135623..., -1)], + (1.414213562373095?, + [(1, 0, -1, -1.414213562373095?, -1, 0, 1, 1.414213562373095?), + (0, 1, 1.414213562373095?, 1, 0, -1, -1.414213562373095?, -1)], 2)] A digraph may have complex eigenvalues. Previously, the complex parts of @@ -23078,16 +23077,12 @@ def eigenvectors(self, laplacian=False): sage: T = DiGraph({0:[1], 1:[2], 2:[0]}) sage: T.eigenvectors() # needs sage.modules sage.rings.number_field - [(1, - [ - (1, 1, 1) - ], + [(1, [(1, 1, 1)], 1), + (-0.50000000000000000? - 0.866025403784439?*I, + [(1, -0.50000000000000000? - 0.866025403784439?*I, -0.50000000000000000? + 0.866025403784439?*I)], 1), - (-0.5000000000... - 0.8660254037...*I, - [(1, -0.5000000000... - 0.8660254037...*I, -0.5000000000... + 0.8660254037...*I)], - 1), - (-0.5000000000... + 0.8660254037...*I, - [(1, -0.5000000000... + 0.8660254037...*I, -0.5000000000... - 0.8660254037...*I)], + (-0.50000000000000000? + 0.866025403784439?*I, + [(1, -0.50000000000000000? + 0.866025403784439?*I, -0.50000000000000000? - 0.866025403784439?*I)], 1)] """ if laplacian: @@ -23119,48 +23114,50 @@ def eigenspaces(self, laplacian=False): sage: P = graphs.PetersenGraph() sage: P.eigenspaces() # needs sage.modules sage.rings.number_field - [ - (3, Vector space of degree 10 and dimension 1 over Rational Field - User basis matrix: - [1 1 1 1 1 1 1 1 1 1]), - (-2, Vector space of degree 10 and dimension 4 over Rational Field - User basis matrix: - [ 1 0 0 0 -1 -1 -1 0 1 1] - [ 0 1 0 0 -1 0 -2 -1 1 2] - [ 0 0 1 0 -1 1 -1 -2 0 2] - [ 0 0 0 1 -1 1 0 -1 -1 1]), - (1, Vector space of degree 10 and dimension 5 over Rational Field - User basis matrix: - [ 1 0 0 0 0 1 -1 0 0 -1] - [ 0 1 0 0 0 -1 1 -1 0 0] - [ 0 0 1 0 0 0 -1 1 -1 0] - [ 0 0 0 1 0 0 0 -1 1 -1] - [ 0 0 0 0 1 -1 0 0 -1 1]) - ] + [(3, + Vector space of degree 10 and dimension 1 over Rational Field + User basis matrix: + [1 1 1 1 1 1 1 1 1 1]), + (-2, + Vector space of degree 10 and dimension 4 over Rational Field + User basis matrix: + [ 1 0 0 0 -1 -1 -1 0 1 1] + [ 0 1 0 0 -1 0 -2 -1 1 2] + [ 0 0 1 0 -1 1 -1 -2 0 2] + [ 0 0 0 1 -1 1 0 -1 -1 1]), + (1, + Vector space of degree 10 and dimension 5 over Rational Field + User basis matrix: + [ 1 0 0 0 0 1 -1 0 0 -1] + [ 0 1 0 0 0 -1 1 -1 0 0] + [ 0 0 1 0 0 0 -1 1 -1 0] + [ 0 0 0 1 0 0 0 -1 1 -1] + [ 0 0 0 0 1 -1 0 0 -1 1])] Eigenspaces for the Laplacian should be identical since the Petersen graph is regular. However, since the output also contains the eigenvalues, the two outputs are slightly different:: sage: P.eigenspaces(laplacian=True) # needs sage.modules sage.rings.number_field - [ - (0, Vector space of degree 10 and dimension 1 over Rational Field - User basis matrix: - [1 1 1 1 1 1 1 1 1 1]), - (5, Vector space of degree 10 and dimension 4 over Rational Field - User basis matrix: - [ 1 0 0 0 -1 -1 -1 0 1 1] - [ 0 1 0 0 -1 0 -2 -1 1 2] - [ 0 0 1 0 -1 1 -1 -2 0 2] - [ 0 0 0 1 -1 1 0 -1 -1 1]), - (2, Vector space of degree 10 and dimension 5 over Rational Field - User basis matrix: - [ 1 0 0 0 0 1 -1 0 0 -1] - [ 0 1 0 0 0 -1 1 -1 0 0] - [ 0 0 1 0 0 0 -1 1 -1 0] - [ 0 0 0 1 0 0 0 -1 1 -1] - [ 0 0 0 0 1 -1 0 0 -1 1]) - ] + [(0, + Vector space of degree 10 and dimension 1 over Rational Field + User basis matrix: + [1 1 1 1 1 1 1 1 1 1]), + (5, + Vector space of degree 10 and dimension 4 over Rational Field + User basis matrix: + [ 1 0 0 0 -1 -1 -1 0 1 1] + [ 0 1 0 0 -1 0 -2 -1 1 2] + [ 0 0 1 0 -1 1 -1 -2 0 2] + [ 0 0 0 1 -1 1 0 -1 -1 1]), + (2, + Vector space of degree 10 and dimension 5 over Rational Field + User basis matrix: + [ 1 0 0 0 0 1 -1 0 0 -1] + [ 0 1 0 0 0 -1 1 -1 0 0] + [ 0 0 1 0 0 0 -1 1 -1 0] + [ 0 0 0 1 0 0 0 -1 1 -1] + [ 0 0 0 0 1 -1 0 0 -1 1])] Notice how one eigenspace below is described with a square root of 2. For the two possible values (positive and negative) there is a @@ -23168,38 +23165,38 @@ def eigenspaces(self, laplacian=False): sage: C = graphs.CycleGraph(8) sage: C.eigenspaces() # needs sage.modules sage.rings.number_field - [ - (2, Vector space of degree 8 and dimension 1 over Rational Field - User basis matrix: - [1 1 1 1 1 1 1 1]), - (-2, Vector space of degree 8 and dimension 1 over Rational Field - User basis matrix: - [ 1 -1 1 -1 1 -1 1 -1]), - (0, Vector space of degree 8 and dimension 2 over Rational Field - User basis matrix: - [ 1 0 -1 0 1 0 -1 0] - [ 0 1 0 -1 0 1 0 -1]), - (a3, Vector space of degree 8 and dimension 2 over - Number Field in a3 with defining polynomial x^2 - 2 - User basis matrix: - [ 1 0 -1 -a3 -1 0 1 a3] - [ 0 1 a3 1 0 -1 -a3 -1]) - ] + [(2, + Vector space of degree 8 and dimension 1 over Rational Field + User basis matrix: + [1 1 1 1 1 1 1 1]), + (-2, + Vector space of degree 8 and dimension 1 over Rational Field + User basis matrix: + [ 1 -1 1 -1 1 -1 1 -1]), + (0, + Vector space of degree 8 and dimension 2 over Rational Field + User basis matrix: + [ 1 0 -1 0 1 0 -1 0] + [ 0 1 0 -1 0 1 0 -1]), + (a3, + Vector space of degree 8 and dimension 2 over Number Field in a3 with defining polynomial x^2 - 2 + User basis matrix: + [ 1 0 -1 -a3 -1 0 1 a3] + [ 0 1 a3 1 0 -1 -a3 -1])] A digraph may have complex eigenvalues and eigenvectors. For a 3-cycle, we have:: sage: T = DiGraph({0: [1], 1: [2], 2: [0]}) sage: T.eigenspaces() # needs sage.modules sage.rings.number_field - [ - (1, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [1 1 1]), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 - with defining polynomial x^2 + x + 1 - User basis matrix: - [ 1 a1 -a1 - 1]) - ] + [(1, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [1 1 1]), + (a1, + Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 + x + 1 + User basis matrix: + [ 1 a1 -a1 - 1])] """ if laplacian: M = self.kirchhoff_matrix(vertices=list(self)) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index dec25a76e54..7a9494dda1e 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -5391,9 +5391,7 @@ cdef class Matrix(Matrix1): [0 0 0] [0 0 0] sage: W = T.kernel_on(V); W.basis() - [ - (0, 1, 0) - ] + [(0, 1, 0)] sage: W.is_submodule(V) True """ @@ -5661,22 +5659,21 @@ cdef class Matrix(Matrix1): [264 275 286 297 308 319] [330 341 352 363 374 385] sage: A.decomposition() # needs sage.libs.pari - [ (Ambient free module of rank 4 - over the principal ideal domain Integer Ring, - True) ] + [(Ambient free module of rank 4 over the principal ideal domain Integer Ring, + True)] sage: B.decomposition() # needs sage.libs.pari - [ (Vector space of degree 6 and dimension 2 over Rational Field - Basis matrix: - [ 1 0 -1 -2 -3 -4] - [ 0 1 2 3 4 5], - True), - (Vector space of degree 6 and dimension 4 over Rational Field - Basis matrix: - [ 1 0 0 0 -5 4] - [ 0 1 0 0 -4 3] - [ 0 0 1 0 -3 2] - [ 0 0 0 1 -2 1], - False) ] + [(Vector space of degree 6 and dimension 2 over Rational Field + Basis matrix: + [ 1 0 -1 -2 -3 -4] + [ 0 1 2 3 4 5], + True), + (Vector space of degree 6 and dimension 4 over Rational Field + Basis matrix: + [ 1 0 0 0 -5 4] + [ 0 1 0 0 -4 3] + [ 0 0 1 0 -3 2] + [ 0 0 0 1 -2 1], + False)] """ if algorithm == 'kernel' or self.base_ring() not in _Fields: return self._decomposition_using_kernels(is_diagonalizable=is_diagonalizable, dual=dual) @@ -5862,12 +5859,14 @@ cdef class Matrix(Matrix1): [0 1 0] [0 0 1] sage: D = t.decomposition_of_subspace(v); D - [ (Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: [0 0 1], - True), - (Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: [0 1 0], - True) ] + [(Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: + [0 0 1], + True), + (Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: + [0 1 0], + True)] sage: t.restrict(D[0][0]) [0] sage: t.restrict(D[1][0]) @@ -5882,18 +5881,18 @@ cdef class Matrix(Matrix1): ....: 0, 2, 0, -2, -2, 0, ....: 0, 2, 0, -2, 0, 0]) sage: a.decomposition_of_subspace(ZZ^6) # needs sage.libs.pari - [ (Free module of degree 6 and rank 2 over Integer Ring - Echelon basis matrix: - [ 1 0 1 -1 1 -1] - [ 0 1 0 -1 2 -1], - False), - (Free module of degree 6 and rank 4 over Integer Ring - Echelon basis matrix: - [ 1 0 -1 0 1 0] - [ 0 1 0 0 0 0] - [ 0 0 0 1 0 0] - [ 0 0 0 0 0 1], - False) ] + [(Free module of degree 6 and rank 2 over Integer Ring + Echelon basis matrix: + [ 1 0 1 -1 1 -1] + [ 0 1 0 -1 2 -1], + False), + (Free module of degree 6 and rank 4 over Integer Ring + Echelon basis matrix: + [ 1 0 -1 0 1 0] + [ 0 1 0 0 0 0] + [ 0 0 0 1 0 0] + [ 0 0 0 0 0 1], + False)] TESTS:: @@ -6317,43 +6316,41 @@ cdef class Matrix(Matrix1): [3 4 5] [6 7 8] sage: es = A.eigenspaces_left(format='all'); es # needs sage.rings.number_field - [ (0, - Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (-1.348469228349535?, - Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 0.3101020514433644? -0.3797958971132713?]), - (13.34846922834954?, - Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 1.289897948556636? 1.579795897113272?]) ] + [(0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (-1.348469228349535?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 0.3101020514433644? -0.3797958971132713?]), + (13.34846922834954?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 1.289897948556636? 1.579795897113272?])] sage: # needs sage.rings.number_field sage: es = A.eigenspaces_left(format='galois'); es - [ (0, - Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, - Vector space of degree 3 and dimension 1 over - Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5]) ] + [(0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5])] sage: es = A.eigenspaces_left(format='galois', ....: algebraic_multiplicity=True); es - [ (0, - Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1], - 1), - (a1, - Vector space of degree 3 and dimension 1 over - Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5], - 1) ] + [(0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1], + 1), + (a1, + Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5], + 1)] sage: e, v, n = es[0]; v = v.basis()[0] sage: delta = e*v - v*A sage: abs(abs(delta)) < 1e-10 @@ -6366,15 +6363,14 @@ cdef class Matrix(Matrix1): [3 4 5] [6 7 8] sage: A.eigenspaces_left(format='galois') # needs sage.rings.number_field - [ (0, - Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, - Vector space of degree 3 and dimension 1 over - Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5]) ] + [(0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5])] We compute the left eigenspaces of the matrix of the Hecke operator `T_2` on level 43 modular symbols, both with all eigenvalues (the default) @@ -6396,48 +6392,47 @@ cdef class Matrix(Matrix1): sage: factor(f) (x - 3) * (x + 2)^2 * (x^2 - 2)^2 sage: A.eigenspaces_left(algebraic_multiplicity=True) - [ (3, - Vector space of degree 7 and dimension 1 over Rational Field - User basis matrix: - [ 1 0 1/7 0 -1/7 0 -2/7], - 1), - (-2, - Vector space of degree 7 and dimension 2 over Rational Field - User basis matrix: - [ 0 1 0 1 -1 1 -1] - [ 0 0 1 0 -1 2 -1], - 2), - (-1.414213562373095?, - Vector space of degree 7 and dimension 2 over Algebraic Field - User basis matrix: - [ 0 1 0 -1 0.4142135623730951? 1 -1] - [ 0 0 1 0 -1 0 2.414213562373095?], - 2), - (1.414213562373095?, - Vector space of degree 7 and dimension 2 over Algebraic Field - User basis matrix: - [ 0 1 0 -1 -2.414213562373095? 1 -1] - [ 0 0 1 0 -1 0 -0.4142135623730951?], - 2) ] + [(3, + Vector space of degree 7 and dimension 1 over Rational Field + User basis matrix: + [ 1 0 1/7 0 -1/7 0 -2/7], + 1), + (-2, + Vector space of degree 7 and dimension 2 over Rational Field + User basis matrix: + [ 0 1 0 1 -1 1 -1] + [ 0 0 1 0 -1 2 -1], + 2), + (-1.414213562373095?, + Vector space of degree 7 and dimension 2 over Algebraic Field + User basis matrix: + [ 0 1 0 -1 0.4142135623730951? 1 -1] + [ 0 0 1 0 -1 0 2.414213562373095?], + 2), + (1.414213562373095?, + Vector space of degree 7 and dimension 2 over Algebraic Field + User basis matrix: + [ 0 1 0 -1 -2.414213562373095? 1 -1] + [ 0 0 1 0 -1 0 -0.4142135623730951?], + 2)] sage: A.eigenspaces_left(format='galois', algebraic_multiplicity=True) - [ (3, - Vector space of degree 7 and dimension 1 over Rational Field - User basis matrix: - [ 1 0 1/7 0 -1/7 0 -2/7], - 1), - (-2, - Vector space of degree 7 and dimension 2 over Rational Field - User basis matrix: - [ 0 1 0 1 -1 1 -1] - [ 0 0 1 0 -1 2 -1], - 2), - (a2, - Vector space of degree 7 and dimension 2 - over Number Field in a2 with defining polynomial x^2 - 2 - User basis matrix: - [ 0 1 0 -1 -a2 - 1 1 -1] - [ 0 0 1 0 -1 0 -a2 + 1], - 2) ] + [(3, + Vector space of degree 7 and dimension 1 over Rational Field + User basis matrix: + [ 1 0 1/7 0 -1/7 0 -2/7], + 1), + (-2, + Vector space of degree 7 and dimension 2 over Rational Field + User basis matrix: + [ 0 1 0 1 -1 1 -1] + [ 0 0 1 0 -1 2 -1], + 2), + (a2, + Vector space of degree 7 and dimension 2 over Number Field in a2 with defining polynomial x^2 - 2 + User basis matrix: + [ 0 1 0 -1 -a2 - 1 1 -1] + [ 0 0 1 0 -1 0 -a2 + 1], + 2)] Next we compute the left eigenspaces over the finite field of order 11. :: @@ -6452,16 +6447,18 @@ cdef class Matrix(Matrix1): sage: A.charpoly() x^4 + 10*x^3 + 3*x^2 + 2*x + 1 sage: A.eigenspaces_left(format='galois', var='beta') - [ (9, - Vector space of degree 4 and dimension 1 over Finite Field of size 11 - User basis matrix: [0 1 5 6]), - (3, Vector space of degree 4 and dimension 1 over Finite Field of size 11 - User basis matrix: [1 0 1 6]), - (beta2, Vector space of degree 4 and dimension 1 - over Univariate Quotient Polynomial Ring in beta2 - over Finite Field of size 11 with modulus x^2 + 9 - User basis matrix: [ 0 0 1 beta2 + 1]) - ] + [(9, + Vector space of degree 4 and dimension 1 over Finite Field of size 11 + User basis matrix: + [0 1 5 6]), + (3, + Vector space of degree 4 and dimension 1 over Finite Field of size 11 + User basis matrix: + [1 0 1 6]), + (beta2, + Vector space of degree 4 and dimension 1 over Univariate Quotient Polynomial Ring in beta2 over Finite Field of size 11 with modulus x^2 + 9 + User basis matrix: + [ 0 0 1 beta2 + 1])] This method is only applicable to exact matrices. The "eigenmatrix" routines for matrices with double-precision @@ -6514,13 +6511,10 @@ cdef class Matrix(Matrix1): NotImplementedError: unable to construct eigenspaces for eigenvalues outside the base field, try the keyword option: format='galois' sage: A.eigenspaces_left(format='galois') # needs sage.rings.number_field - [ (a0, - Vector space of degree 2 and dimension 1 over - Univariate Quotient Polynomial Ring in a0 over - Finite Field in b of size 11^2 - with modulus x^2 + (5*b + 6)*x + 8*b + 10 - User basis matrix: - [ 1 6*b*a0 + 3*b + 1]) ] + [(a0, + Vector space of degree 2 and dimension 1 over Univariate Quotient Polynomial Ring in a0 over Finite Field in b of size 11^2 with modulus x^2 + (5*b + 6)*x + 8*b + 10 + User basis matrix: + [ 1 6*b*a0 + 3*b + 1])] TESTS: @@ -6688,41 +6682,39 @@ cdef class Matrix(Matrix1): [3 4 5] [6 7 8] sage: A.eigenspaces_right() - [ (0, - Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (-1.348469228349535?, - Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 0.1303061543300932? -0.7393876913398137?]), - (13.34846922834954?, - Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 3.069693845669907? 5.139387691339814?]) ] + [(0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (-1.348469228349535?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 0.1303061543300932? -0.7393876913398137?]), + (13.34846922834954?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 3.069693845669907? 5.139387691339814?])] sage: es = A.eigenspaces_right(format='galois'); es - [ (0, - Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, - Vector space of degree 3 and dimension 1 over - Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) ] + [(0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5])] sage: es = A.eigenspaces_right(format='galois', ....: algebraic_multiplicity=True); es - [ (0, - Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1], - 1), - (a1, - Vector space of degree 3 and dimension 1 over - Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5], - 1) ] + [(0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1], + 1), + (a1, + Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5], + 1)] sage: e, v, n = es[0]; v = v.basis()[0] sage: delta = v*e - A*v sage: abs(abs(delta)) < 1e-10 @@ -6735,15 +6727,14 @@ cdef class Matrix(Matrix1): [3 4 5] [6 7 8] sage: A.eigenspaces_right(format='galois') # needs sage.rings.number_field - [ (0, - Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, - Vector space of degree 3 and dimension 1 over - Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) ] + [(0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5])] This method is only applicable to exact matrices. The "eigenmatrix" routines for matrices with double-precision @@ -7004,7 +6995,7 @@ cdef class Matrix(Matrix1): [3 4 5] [6 7 8] sage: es = A.eigenvectors_left(); es - [(0, [ (1, -2, 1) ], 1), + [(0, [(1, -2, 1)], 1), (-1.348469228349535?, [(1, 0.3101020514433644?, -0.3797958971132713?)], 1), (13.34846922834954?, [(1, 1.289897948556636?, 1.579795897113272?)], 1)] sage: eval, [evec], mult = es[0] @@ -7018,11 +7009,9 @@ cdef class Matrix(Matrix1): sage: M = matrix(QQ, [[0,-1,0], [1,0,0], [0,0,2]]) sage: M.eigenvectors_left() # needs sage.rings.number_field - [(2, [ (0, 0, 1) ], 1), - (-1*I, [(1, -1*I, 0)], 1), - (1*I, [(1, 1*I, 0)], 1)] + [(2, [(0, 0, 1)], 1), (-1*I, [(1, -1*I, 0)], 1), (1*I, [(1, 1*I, 0)], 1)] sage: M.eigenvectors_left(extend=False) # needs sage.rings.number_field - [(2, [ (0, 0, 1) ], 1)] + [(2, [(0, 0, 1)], 1)] TESTS:: @@ -7135,11 +7124,11 @@ cdef class Matrix(Matrix1): [3 4 5] [6 7 8] sage: es = A.eigenvectors_right(); es - [(0, [ (1, -2, 1) ], 1), + [(0, [(1, -2, 1)], 1), (-1.348469228349535?, [(1, 0.1303061543300932?, -0.7393876913398137?)], 1), (13.34846922834954?, [(1, 3.069693845669907?, 5.139387691339814?)], 1)] sage: A.eigenvectors_right(extend=False) - [(0, [ (1, -2, 1) ], 1)] + [(0, [(1, -2, 1)], 1)] sage: eval, [evec], mult = es[0] sage: delta = eval*evec - A*evec sage: abs(abs(delta)) < 1e-10 @@ -8665,8 +8654,8 @@ cdef class Matrix(Matrix1): [0 0 0] sage: M.permutation_normal_form() - [2 1 0] - [1 0 0] + Traceback (most recent call last): + ... [0 0 0] sage: M = matrix(ZZ, [[-1, 3], [-1, 5], [2, 4]]) @@ -8676,11 +8665,8 @@ cdef class Matrix(Matrix1): [ 2 4] sage: M.permutation_normal_form(check=True) # needs sage.graphs sage.groups - ( - [ 5 -1] - [ 4 2] - [ 3 -1], - ((1,2,3), (1,2)) + Traceback (most recent call last): + ... ) TESTS:: @@ -8688,9 +8674,8 @@ cdef class Matrix(Matrix1): sage: # needs sage.graphs sage: M = matrix(ZZ, [[3, 4, 5], [3, 4, 5], [3, 5, 4], [2, 0,1]]) sage: M.permutation_normal_form() - [5 4 3] - [5 4 3] - [4 5 3] + Traceback (most recent call last): + ... [1 0 2] sage: M = matrix(ZZ, 0, 0, []) sage: M.permutation_normal_form() @@ -18621,10 +18606,8 @@ def decomp_seq(v): sage: from sage.matrix.matrix2 import decomp_seq sage: V = [(QQ^3, 2), (QQ^2, 1)] sage: decomp_seq(V) - [ - (Vector space of dimension 2 over Rational Field, 1), - (Vector space of dimension 3 over Rational Field, 2) - ] + [(Vector space of dimension 2 over Rational Field, 1), + (Vector space of dimension 3 over Rational Field, 2)] """ list.sort(v, key=lambda x: x[0].dimension()) return Sequence(v, universe=tuple, check=False, cr=True) diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 9ea2335b297..c8f4e6b33df 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -4813,14 +4813,14 @@ cdef class Matrix_integer_dense(Matrix_dense): sage: w.charpoly().factor() (x - 3) * (x + 2) sage: w.decomposition() - [ - (Free module of degree 2 and rank 1 over Integer Ring - Echelon basis matrix: - [ 5 -2], True), - (Free module of degree 2 and rank 1 over Integer Ring - Echelon basis matrix: - [0 1], True) - ] + [(Free module of degree 2 and rank 1 over Integer Ring + Echelon basis matrix: + [ 5 -2], + True), + (Free module of degree 2 and rank 1 over Integer Ring + Echelon basis matrix: + [0 1], + True)] """ F = self.charpoly().factor() if len(F) == 1: diff --git a/src/sage/matrix/matrix_rational_dense.pyx b/src/sage/matrix/matrix_rational_dense.pyx index 40c63470617..b0c58016c9b 100644 --- a/src/sage/matrix/matrix_rational_dense.pyx +++ b/src/sage/matrix/matrix_rational_dense.pyx @@ -1900,15 +1900,15 @@ cdef class Matrix_rational_dense(Matrix_dense): sage: a = matrix(QQ,3,[1..9]) sage: a.decomposition() - [ - (Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [ 1 -2 1], True), - (Vector space of degree 3 and dimension 2 over Rational Field - Basis matrix: - [ 1 0 -1] - [ 0 1 2], True) - ] + [(Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: + [ 1 -2 1], + True), + (Vector space of degree 3 and dimension 2 over Rational Field + Basis matrix: + [ 1 0 -1] + [ 0 1 2], + True)] """ X = self._decomposition_rational(is_diagonalizable=is_diagonalizable, echelon_algorithm=algorithm, diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index 7286501c0f1..94144a978f0 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -105,10 +105,7 @@ def basis(x): sage: V = VectorSpace(QQ, 3) # needs sage.modules sage: S = V.subspace([[1,2,0], [2,2,-1]]) # needs sage.modules sage: basis(S) # needs sage.modules - [ - (1, 0, -1), - (0, 1, 1/2) - ] + [(1, 0, -1), (0, 1, 1/2)] """ return x.basis() @@ -220,9 +217,8 @@ def decomposition(x): sage: M = matrix([[2, 3], [3, 4]]) # needs sage.libs.pari sage.modules sage: M.decomposition() # needs sage.libs.pari sage.modules - [ - (Ambient free module of rank 2 over the principal ideal domain Integer Ring, True) - ] + [(Ambient free module of rank 2 over the principal ideal domain Integer Ring, + True)] sage: # needs sage.groups sage: G. = DirichletGroup(20) @@ -910,11 +906,7 @@ def kernel(x): Basis matrix: [] sage: kernel(A.transpose()).basis() - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] """ return x.kernel() diff --git a/src/sage/modular/abvar/abvar.py b/src/sage/modular/abvar/abvar.py index c1e0733f38c..2030bfb09bb 100644 --- a/src/sage/modular/abvar/abvar.py +++ b/src/sage/modular/abvar/abvar.py @@ -10,11 +10,9 @@ sage: A = J0(33) sage: D = A.decomposition(); D - [ - Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), - Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33) - ] + [Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), + Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), + Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)] sage: loads(dumps(D)) == D True sage: loads(dumps(A)) == A @@ -513,9 +511,7 @@ def label(self) -> str: sage: B = phi.image(); B Abelian subvariety of dimension 1 of J0(33) sage: B.decomposition() - [ - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33) - ] + [Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33)] sage: C = J.degeneracy_map(33,3).image(); C Abelian subvariety of dimension 1 of J0(33) sage: C == B @@ -937,11 +933,9 @@ def intersection(self, other): intersection:: sage: J = J0(67); D = J.decomposition(); D - [ - Simple abelian subvariety 67a(1,67) of dimension 1 of J0(67), - Simple abelian subvariety 67b(1,67) of dimension 2 of J0(67), - Simple abelian subvariety 67c(1,67) of dimension 2 of J0(67) - ] + [Simple abelian subvariety 67a(1,67) of dimension 1 of J0(67), + Simple abelian subvariety 67b(1,67) of dimension 2 of J0(67), + Simple abelian subvariety 67c(1,67) of dimension 2 of J0(67)] sage: (D[0] + D[1]).intersection(D[1] + D[2]) (Finite subgroup with invariants [5, 10] over QQbar of Abelian subvariety of dimension 3 of J0(67), Abelian subvariety of dimension 2 of J0(67)) @@ -1777,14 +1771,12 @@ def conductor(self): 5^24 sage: A = J0(11^2); A.decomposition() - [ - Simple abelian subvariety 11a(1,121) of dimension 1 of J0(121), - Simple abelian subvariety 11a(11,121) of dimension 1 of J0(121), - Simple abelian subvariety 121a(1,121) of dimension 1 of J0(121), - Simple abelian subvariety 121b(1,121) of dimension 1 of J0(121), - Simple abelian subvariety 121c(1,121) of dimension 1 of J0(121), - Simple abelian subvariety 121d(1,121) of dimension 1 of J0(121) - ] + [Simple abelian subvariety 11a(1,121) of dimension 1 of J0(121), + Simple abelian subvariety 11a(11,121) of dimension 1 of J0(121), + Simple abelian subvariety 121a(1,121) of dimension 1 of J0(121), + Simple abelian subvariety 121b(1,121) of dimension 1 of J0(121), + Simple abelian subvariety 121c(1,121) of dimension 1 of J0(121), + Simple abelian subvariety 121d(1,121) of dimension 1 of J0(121)] sage: A.conductor().factor() 11^10 @@ -3160,11 +3152,9 @@ def degen_t(self, none_if_not_known=False): EXAMPLES:: sage: D = J0(33).decomposition(); D - [ - Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), - Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33) - ] + [Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), + Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), + Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)] sage: D[0].degen_t() (1, 33) sage: D[1].degen_t() @@ -3296,36 +3286,28 @@ def decomposition(self, simple=True, bound=None): sage: A = w.abelian_variety(); A Abelian subvariety of dimension 1 of J0(33) sage: D = A.decomposition(); D - [ - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33) - ] + [Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33)] sage: D[0] == A True sage: B = A + J0(33)[0]; B Abelian subvariety of dimension 2 of J0(33) sage: dd = B.decomposition(simple=False); dd - [ - Abelian subvariety of dimension 2 of J0(33) - ] + [Abelian subvariety of dimension 2 of J0(33)] sage: dd[0] == B True sage: dd = B.decomposition(); dd - [ - Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33) - ] + [Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), + Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33)] sage: sum(dd) == B True We decompose a product of two Jacobians:: sage: (J0(33) * J0(11)).decomposition() - [ - Simple abelian subvariety 11a(1,11) of dimension 1 of J0(33) x J0(11), - Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33) x J0(11), - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33) x J0(11), - Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33) x J0(11) - ] + [Simple abelian subvariety 11a(1,11) of dimension 1 of J0(33) x J0(11), + Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33) x J0(11), + Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33) x J0(11), + Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33) x J0(11)] """ try: return self.__decomposition[(simple, bound)] @@ -3504,11 +3486,11 @@ def _classify_ambient_factors(self, simple=True, bound=None): sage: A = (d1 + d2).image(); A Abelian subvariety of dimension 1 of J0(33) sage: A._classify_ambient_factors() - ([1], [0, 2], [ - Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), - Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33) - ]) + ([1], + [0, 2], + [Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), + Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), + Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)]) """ # Decompose an arbitrary abelian variety amb = self.ambient_variety() @@ -3538,10 +3520,8 @@ def _isogeny_to_product_of_simples(self): EXAMPLES:: sage: J = J0(37) ; J.decomposition() - [ - Simple abelian subvariety 37a(1,37) of dimension 1 of J0(37), - Simple abelian subvariety 37b(1,37) of dimension 1 of J0(37) - ] + [Simple abelian subvariety 37a(1,37) of dimension 1 of J0(37), + Simple abelian subvariety 37b(1,37) of dimension 1 of J0(37)] sage: phi = J._isogeny_to_product_of_simples() ; phi Abelian variety morphism: From: Abelian variety J0(37) of dimension 2 @@ -3774,11 +3754,9 @@ def _factors_with_same_label(self, other): EXAMPLES:: sage: D = J0(33).decomposition(); D - [ - Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), - Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33) - ] + [Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), + Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), + Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)] sage: D[0]._factors_with_same_label(D[1]) [Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)] sage: D[0]._factors_with_same_label(D[2]) @@ -3837,11 +3815,9 @@ def _complement_shares_no_factors_with_same_label(self): elliptic curves with a third nonisogenous curve:: sage: D = J0(33).decomposition(); D - [ - Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), - Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33) - ] + [Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), + Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), + Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)] sage: D[0]._complement_shares_no_factors_with_same_label() False sage: (D[0]+D[1])._complement_shares_no_factors_with_same_label() @@ -3855,10 +3831,8 @@ def _complement_shares_no_factors_with_same_label(self): :: sage: D = (J0(11) * J0(11)).decomposition(); D - [ - Simple abelian subvariety 11a(1,11) of dimension 1 of J0(11) x J0(11), - Simple abelian subvariety 11a(1,11) of dimension 1 of J0(11) x J0(11) - ] + [Simple abelian subvariety 11a(1,11) of dimension 1 of J0(11) x J0(11), + Simple abelian subvariety 11a(1,11) of dimension 1 of J0(11) x J0(11)] sage: D[0]._complement_shares_no_factors_with_same_label() False @@ -3866,10 +3840,8 @@ def _complement_shares_no_factors_with_same_label(self): isogeny, class that matters:: sage: D = (J0(11)*J1(11)).decomposition(); D - [ - Simple abelian subvariety 11aG1(1,11) of dimension 1 of J0(11) x J1(11), - Simple abelian subvariety 11a(1,11) of dimension 1 of J0(11) x J1(11) - ] + [Simple abelian subvariety 11aG1(1,11) of dimension 1 of J0(11) x J1(11), + Simple abelian subvariety 11a(1,11) of dimension 1 of J0(11) x J1(11)] sage: D[0]._complement_shares_no_factors_with_same_label() True sage: D[0].newform_label() @@ -3893,28 +3865,22 @@ def __getitem__(self, i): sage: J = J0(389) sage: J.decomposition() - [ - Simple abelian subvariety 389a(1,389) of dimension 1 of J0(389), - Simple abelian subvariety 389b(1,389) of dimension 2 of J0(389), - Simple abelian subvariety 389c(1,389) of dimension 3 of J0(389), - Simple abelian subvariety 389d(1,389) of dimension 6 of J0(389), - Simple abelian subvariety 389e(1,389) of dimension 20 of J0(389) - ] + [Simple abelian subvariety 389a(1,389) of dimension 1 of J0(389), + Simple abelian subvariety 389b(1,389) of dimension 2 of J0(389), + Simple abelian subvariety 389c(1,389) of dimension 3 of J0(389), + Simple abelian subvariety 389d(1,389) of dimension 6 of J0(389), + Simple abelian subvariety 389e(1,389) of dimension 20 of J0(389)] sage: J[2] Simple abelian subvariety 389c(1,389) of dimension 3 of J0(389) sage: J[-1] Simple abelian subvariety 389e(1,389) of dimension 20 of J0(389) sage: J = J0(125); J.decomposition() - [ - Simple abelian subvariety 125a(1,125) of dimension 2 of J0(125), - Simple abelian subvariety 125b(1,125) of dimension 2 of J0(125), - Simple abelian subvariety 125c(1,125) of dimension 4 of J0(125) - ] + [Simple abelian subvariety 125a(1,125) of dimension 2 of J0(125), + Simple abelian subvariety 125b(1,125) of dimension 2 of J0(125), + Simple abelian subvariety 125c(1,125) of dimension 4 of J0(125)] sage: J[:2] - [ - Simple abelian subvariety 125a(1,125) of dimension 2 of J0(125), - Simple abelian subvariety 125b(1,125) of dimension 2 of J0(125) - ] + [Simple abelian subvariety 125a(1,125) of dimension 2 of J0(125), + Simple abelian subvariety 125b(1,125) of dimension 2 of J0(125)] """ return self.decomposition()[i] @@ -4014,13 +3980,11 @@ def __add__(self, other): EXAMPLES:: sage: A = J0(42); D = A.decomposition(); D - [ - Simple abelian subvariety 14a(1,42) of dimension 1 of J0(42), - Simple abelian subvariety 14a(3,42) of dimension 1 of J0(42), - Simple abelian subvariety 21a(1,42) of dimension 1 of J0(42), - Simple abelian subvariety 21a(2,42) of dimension 1 of J0(42), - Simple abelian subvariety 42a(1,42) of dimension 1 of J0(42) - ] + [Simple abelian subvariety 14a(1,42) of dimension 1 of J0(42), + Simple abelian subvariety 14a(3,42) of dimension 1 of J0(42), + Simple abelian subvariety 21a(1,42) of dimension 1 of J0(42), + Simple abelian subvariety 21a(2,42) of dimension 1 of J0(42), + Simple abelian subvariety 42a(1,42) of dimension 1 of J0(42)] sage: D[0] + D[1] Abelian subvariety of dimension 2 of J0(42) sage: D[1].is_subvariety(D[0] + D[1]) @@ -4312,13 +4276,11 @@ def is_subvariety(self, other): More examples:: sage: A = J0(42); D = A.decomposition(); D - [ - Simple abelian subvariety 14a(1,42) of dimension 1 of J0(42), - Simple abelian subvariety 14a(3,42) of dimension 1 of J0(42), - Simple abelian subvariety 21a(1,42) of dimension 1 of J0(42), - Simple abelian subvariety 21a(2,42) of dimension 1 of J0(42), - Simple abelian subvariety 42a(1,42) of dimension 1 of J0(42) - ] + [Simple abelian subvariety 14a(1,42) of dimension 1 of J0(42), + Simple abelian subvariety 14a(3,42) of dimension 1 of J0(42), + Simple abelian subvariety 21a(1,42) of dimension 1 of J0(42), + Simple abelian subvariety 21a(2,42) of dimension 1 of J0(42), + Simple abelian subvariety 42a(1,42) of dimension 1 of J0(42)] sage: D[0].is_subvariety(A) True sage: D[1].is_subvariety(D[0] + D[1]) @@ -4465,16 +4427,12 @@ def decomposition(self, simple=True, bound=None): sage: J = J0(33) sage: J.decomposition() - [ - Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), - Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33) - ] + [Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), + Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), + Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)] sage: J1(17).decomposition() - [ - Simple abelian subvariety 17aG1(1,17) of dimension 1 of J1(17), - Simple abelian subvariety 17bG1(1,17) of dimension 4 of J1(17) - ] + [Simple abelian subvariety 17aG1(1,17) of dimension 1 of J1(17), + Simple abelian subvariety 17bG1(1,17) of dimension 4 of J1(17)] """ try: return self.__decomposition[(simple, bound)] @@ -4985,10 +4943,8 @@ def factor_new_space(M): sage: M = ModularSymbols(37).cuspidal_subspace() sage: sage.modular.abvar.abvar.factor_new_space(M) - [ - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field] """ t = None p = 2 @@ -5020,12 +4976,8 @@ def factor_modsym_space_new_factors(M): sage: M = ModularSymbols(33) sage: sage.modular.abvar.abvar.factor_modsym_space_new_factors(M) - [[ - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field - ], - [ - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field - ]] + [[Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field], + [Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field]] """ eps = M.character() K = eps.conductor() if eps is not None else 1 @@ -5051,27 +5003,36 @@ def simple_factorization_of_modsym_space(M, simple=True): sage: M = ModularSymbols(33) sage: sage.modular.abvar.abvar.simple_factorization_of_modsym_space(M) - [ - (11, 0, 1, Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field), - (11, 0, 3, Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field), - (33, 0, 1, Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field) - ] + [(11, + 0, + 1, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field), + (11, + 0, + 3, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field), + (33, + 0, + 1, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field)] sage: sage.modular.abvar.abvar.simple_factorization_of_modsym_space(M, simple=False) - [ - (11, 0, None, Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field), - (33, 0, None, Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field) - ] + [(11, + 0, + None, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field), + (33, + 0, + None, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field)] TESTS: Check that :issue:`21799` is fixed:: sage: JH(28, [15]).decomposition() - [ - Simple abelian subvariety 14aGH[15](1,28) of dimension 1 of JH(28,[15]), - Simple abelian subvariety 14aGH[15](2,28) of dimension 1 of JH(28,[15]), - Simple abelian subvariety 28aGH[15](1,28) of dimension 2 of JH(28,[15]) - ] + [Simple abelian subvariety 14aGH[15](1,28) of dimension 1 of JH(28,[15]), + Simple abelian subvariety 14aGH[15](2,28) of dimension 1 of JH(28,[15]), + Simple abelian subvariety 28aGH[15](1,28) of dimension 2 of JH(28,[15])] """ D = [] for G in factor_modsym_space_new_factors(M): @@ -5127,18 +5088,24 @@ def modsym_lattices(M, factors): sage: M = ModularSymbols(33) sage: factors = sage.modular.abvar.abvar.simple_factorization_of_modsym_space(M, simple=False) sage: sage.modular.abvar.abvar.modsym_lattices(M, factors) - [ - (11, 0, None, Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field, Free module of degree 6 and rank 4 over Integer Ring - Echelon basis matrix: - [ 1 0 0 0 -1 2] - [ 0 1 0 0 -1 1] - [ 0 0 1 0 -2 2] - [ 0 0 0 1 -1 -1]), - (33, 0, None, Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field, Free module of degree 6 and rank 2 over Integer Ring - Echelon basis matrix: - [ 1 0 0 -1 0 0] - [ 0 0 1 0 1 -1]) - ] + [(11, + 0, + None, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field, + Free module of degree 6 and rank 4 over Integer Ring + Echelon basis matrix: + [ 1 0 0 0 -1 2] + [ 0 1 0 0 -1 1] + [ 0 0 1 0 -2 2] + [ 0 0 0 1 -1 -1]), + (33, + 0, + None, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field, + Free module of degree 6 and rank 2 over Integer Ring + Echelon basis matrix: + [ 1 0 0 -1 0 0] + [ 0 0 1 0 1 -1])] """ # 1. Change basis of everything to the ambient integral modular symbols space # 2. Clear denominator. diff --git a/src/sage/modular/abvar/abvar_ambient_jacobian.py b/src/sage/modular/abvar/abvar_ambient_jacobian.py index 7674b41807a..e6f7e590fc0 100644 --- a/src/sage/modular/abvar/abvar_ambient_jacobian.py +++ b/src/sage/modular/abvar/abvar_ambient_jacobian.py @@ -335,25 +335,19 @@ def decomposition(self, simple=True, bound=None): EXAMPLES:: sage: J0(33).decomposition(simple=False) - [ - Abelian subvariety of dimension 2 of J0(33), - Abelian subvariety of dimension 1 of J0(33) - ] + [Abelian subvariety of dimension 2 of J0(33), + Abelian subvariety of dimension 1 of J0(33)] sage: J0(33).decomposition(simple=False)[1].is_simple() True sage: J0(33).decomposition(simple=False)[0].is_simple() False sage: J0(33).decomposition(simple=False) - [ - Abelian subvariety of dimension 2 of J0(33), - Simple abelian subvariety 33a(None,33) of dimension 1 of J0(33) - ] + [Abelian subvariety of dimension 2 of J0(33), + Simple abelian subvariety 33a(None,33) of dimension 1 of J0(33)] sage: J0(33).decomposition(simple=True) - [ - Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), - Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33) - ] + [Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), + Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), + Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)] """ try: return self.__decomposition[simple] diff --git a/src/sage/modular/abvar/homology.py b/src/sage/modular/abvar/homology.py index 21a129072fa..d8b6b168bdb 100644 --- a/src/sage/modular/abvar/homology.py +++ b/src/sage/modular/abvar/homology.py @@ -29,10 +29,8 @@ sage: H.base_ring() Integer Ring sage: d = H.decomposition(); d - [ - Submodule of rank 2 of Integral Homology of Abelian variety J0(43) of dimension 3, - Submodule of rank 4 of Integral Homology of Abelian variety J0(43) of dimension 3 - ] + [Submodule of rank 2 of Integral Homology of Abelian variety J0(43) of dimension 3, + Submodule of rank 4 of Integral Homology of Abelian variety J0(43) of dimension 3] sage: a = d[0] sage: a.hecke_matrix(5) [-4 0] @@ -603,10 +601,8 @@ def __richcmp__(self, other, op): EXAMPLES:: sage: J0(37).homology().decomposition() # indirect doctest - [ - Submodule of rank 2 of Integral Homology of Abelian variety J0(37) of dimension 2, - Submodule of rank 2 of Integral Homology of Abelian variety J0(37) of dimension 2 - ] + [Submodule of rank 2 of Integral Homology of Abelian variety J0(37) of dimension 2, + Submodule of rank 2 of Integral Homology of Abelian variety J0(37) of dimension 2] """ if not isinstance(other, Homology_submodule): return NotImplemented @@ -626,10 +622,8 @@ def ambient_hecke_module(self): sage: H = J0(48).homology(); H Integral Homology of Abelian variety J0(48) of dimension 3 sage: d = H.decomposition(); d - [ - Submodule of rank 2 of Integral Homology of Abelian variety J0(48) of dimension 3, - Submodule of rank 4 of Integral Homology of Abelian variety J0(48) of dimension 3 - ] + [Submodule of rank 2 of Integral Homology of Abelian variety J0(48) of dimension 3, + Submodule of rank 4 of Integral Homology of Abelian variety J0(48) of dimension 3] sage: d[0].ambient_hecke_module() Integral Homology of Abelian variety J0(48) of dimension 3 """ @@ -662,10 +656,8 @@ def hecke_bound(self): EXAMPLES:: sage: d = J0(43).homology().decomposition(2); d - [ - Submodule of rank 2 of Integral Homology of Abelian variety J0(43) of dimension 3, - Submodule of rank 4 of Integral Homology of Abelian variety J0(43) of dimension 3 - ] + [Submodule of rank 2 of Integral Homology of Abelian variety J0(43) of dimension 3, + Submodule of rank 4 of Integral Homology of Abelian variety J0(43) of dimension 3] Because the first factor has dimension 2 it corresponds to an elliptic curve, so we have a Hecke bound of 1. @@ -690,14 +682,9 @@ def hecke_matrix(self, n): EXAMPLES:: sage: d = J0(125).homology(GF(17)).decomposition(2); d - [ - Submodule of rank 4 of Homology with coefficients in Finite Field of size 17 - of Abelian variety J0(125) of dimension 8, - Submodule of rank 4 of Homology with coefficients in Finite Field of size 17 - of Abelian variety J0(125) of dimension 8, - Submodule of rank 8 of Homology with coefficients in Finite Field of size 17 - of Abelian variety J0(125) of dimension 8 - ] + [Submodule of rank 4 of Homology with coefficients in Finite Field of size 17 of Abelian variety J0(125) of dimension 8, + Submodule of rank 4 of Homology with coefficients in Finite Field of size 17 of Abelian variety J0(125) of dimension 8, + Submodule of rank 8 of Homology with coefficients in Finite Field of size 17 of Abelian variety J0(125) of dimension 8] sage: t = d[0].hecke_matrix(17); t [16 15 15 0] [ 0 5 0 2] diff --git a/src/sage/modular/abvar/homspace.py b/src/sage/modular/abvar/homspace.py index 30ad76f3601..97200d8a6bc 100644 --- a/src/sage/modular/abvar/homspace.py +++ b/src/sage/modular/abvar/homspace.py @@ -12,10 +12,8 @@ sage: J = J0(37) sage: D = J.decomposition() ; D - [ - Simple abelian subvariety 37a(1,37) of dimension 1 of J0(37), - Simple abelian subvariety 37b(1,37) of dimension 1 of J0(37) - ] + [Simple abelian subvariety 37a(1,37) of dimension 1 of J0(37), + Simple abelian subvariety 37b(1,37) of dimension 1 of J0(37)] sage: D[0].intersection(D[1]) (Finite subgroup with invariants [2, 2] over QQ of Simple abelian subvariety 37a(1,37) of dimension 1 of J0(37), @@ -101,11 +99,9 @@ sage: J = J0(33) sage: D = J.decomposition() sage: D - [ - Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), - Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33) - ] + [Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33), + Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33), + Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)] sage: Hom(D[0],D[1]).gens() (Abelian variety morphism: From: Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33) @@ -122,10 +118,8 @@ :: sage: DD = J.decomposition(simple=False) ; DD - [ - Abelian subvariety of dimension 2 of J0(33), - Abelian subvariety of dimension 1 of J0(33) - ] + [Abelian subvariety of dimension 2 of J0(33), + Abelian subvariety of dimension 1 of J0(33)] sage: A, B = DD sage: A == D[0] + D[1] True @@ -670,12 +664,10 @@ def _calculate_simple_gens(self): [1 1] ] sage: J = J0(11) * J0(33) ; J.decomposition() - [ - Simple abelian subvariety 11a(1,11) of dimension 1 of J0(11) x J0(33), - Simple abelian subvariety 11a(1,33) of dimension 1 of J0(11) x J0(33), - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(11) x J0(33), - Simple abelian subvariety 33a(1,33) of dimension 1 of J0(11) x J0(33) - ] + [Simple abelian subvariety 11a(1,11) of dimension 1 of J0(11) x J0(33), + Simple abelian subvariety 11a(1,33) of dimension 1 of J0(11) x J0(33), + Simple abelian subvariety 11a(3,33) of dimension 1 of J0(11) x J0(33), + Simple abelian subvariety 33a(1,33) of dimension 1 of J0(11) x J0(33)] sage: J[0].Hom(J[1])._calculate_simple_gens() [ [ 0 -1] @@ -700,9 +692,7 @@ def _calculate_simple_gens(self): :: sage: J = J0(23) ; J.decomposition() - [ - Simple abelian variety J0(23) of dimension 2 - ] + [Simple abelian variety J0(23) of dimension 2] sage: J[0].Hom(J[0])._calculate_simple_gens() [ [1 0 0 0] [ 0 1 -1 0] diff --git a/src/sage/modular/abvar/morphism.py b/src/sage/modular/abvar/morphism.py index ccf87e302e7..14cdfbd1b33 100644 --- a/src/sage/modular/abvar/morphism.py +++ b/src/sage/modular/abvar/morphism.py @@ -405,9 +405,7 @@ def __call__(self, X): sage: t3(E11a0) Abelian subvariety of dimension 1 of J0(33) sage: t3(E11a0).decomposition() - [ - Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33) - ] + [Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33)] sage: t3(E11a0) == E11a1 True sage: t2(E11a0) == E11a0 diff --git a/src/sage/modular/abvar/torsion_subgroup.py b/src/sage/modular/abvar/torsion_subgroup.py index 6ae7bff58c7..310ff5419e6 100644 --- a/src/sage/modular/abvar/torsion_subgroup.py +++ b/src/sage/modular/abvar/torsion_subgroup.py @@ -30,10 +30,8 @@ sage: T.invariants() [15] sage: d = J.decomposition(); d - [ - Simple abelian subvariety 50a(1,50) of dimension 1 of J0(50), - Simple abelian subvariety 50b(1,50) of dimension 1 of J0(50) - ] + [Simple abelian subvariety 50a(1,50) of dimension 1 of J0(50), + Simple abelian subvariety 50b(1,50) of dimension 1 of J0(50)] sage: d[0].rational_torsion_subgroup().order() 3 sage: d[1].rational_torsion_subgroup().order() diff --git a/src/sage/modular/arithgroup/arithgroup_perm.py b/src/sage/modular/arithgroup/arithgroup_perm.py index 4238875048b..05d8b6059df 100644 --- a/src/sage/modular/arithgroup/arithgroup_perm.py +++ b/src/sage/modular/arithgroup/arithgroup_perm.py @@ -2587,16 +2587,22 @@ def odd_subgroups(self): A projective congruence subgroup may have noncongruence liftings, as the example of `\bar{\Gamma}_0(6)` illustrates (see [KSV2011]_):: sage: X = Gamma0(6).as_permutation_group().odd_subgroups(); Sequence([[u.S2(), u.S3()] for u in X],cr=True) - [ - [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), (1,2,3,13,14,15)(4,5,6,16,17,18)(7,8,9,19,20,21)(10,11,12,22,23,24)], - [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), (1,14,15,13,2,3)(4,5,6,16,17,18)(7,8,9,19,20,21)(10,11,12,22,23,24)], - [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), (1,2,3,13,14,15)(4,17,6,16,5,18)(7,8,9,19,20,21)(10,11,12,22,23,24)], - [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), (1,14,15,13,2,3)(4,17,6,16,5,18)(7,8,9,19,20,21)(10,11,12,22,23,24)], - [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), (1,2,3,13,14,15)(4,5,6,16,17,18)(7,20,9,19,8,21)(10,11,12,22,23,24)], - [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), (1,14,15,13,2,3)(4,5,6,16,17,18)(7,20,9,19,8,21)(10,11,12,22,23,24)], - [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), (1,2,3,13,14,15)(4,17,6,16,5,18)(7,20,9,19,8,21)(10,11,12,22,23,24)], - [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), (1,14,15,13,2,3)(4,17,6,16,5,18)(7,20,9,19,8,21)(10,11,12,22,23,24)] - ] + [[(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), + (1,2,3,13,14,15)(4,5,6,16,17,18)(7,8,9,19,20,21)(10,11,12,22,23,24)], + [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), + (1,14,15,13,2,3)(4,5,6,16,17,18)(7,8,9,19,20,21)(10,11,12,22,23,24)], + [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), + (1,2,3,13,14,15)(4,17,6,16,5,18)(7,8,9,19,20,21)(10,11,12,22,23,24)], + [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), + (1,14,15,13,2,3)(4,17,6,16,5,18)(7,8,9,19,20,21)(10,11,12,22,23,24)], + [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), + (1,2,3,13,14,15)(4,5,6,16,17,18)(7,20,9,19,8,21)(10,11,12,22,23,24)], + [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), + (1,14,15,13,2,3)(4,5,6,16,17,18)(7,20,9,19,8,21)(10,11,12,22,23,24)], + [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), + (1,2,3,13,14,15)(4,17,6,16,5,18)(7,20,9,19,8,21)(10,11,12,22,23,24)], + [(1,3,13,15)(2,4,14,16)(5,7,17,19)(6,10,18,22)(8,12,20,24)(9,11,21,23), + (1,14,15,13,2,3)(4,17,6,16,5,18)(7,20,9,19,8,21)(10,11,12,22,23,24)]] sage: [u.is_congruence() for u in X] [True, False, False, True, True, False, False, True] """ diff --git a/src/sage/modular/dirichlet.py b/src/sage/modular/dirichlet.py index c261a84e8de..9603bb91e02 100644 --- a/src/sage/modular/dirichlet.py +++ b/src/sage/modular/dirichlet.py @@ -1264,11 +1264,18 @@ def galois_orbit(self, sort=True): sage: G = DirichletGroup(13) sage: G.galois_orbits() - [ - [Dirichlet character modulo 13 of conductor 1 mapping 2 |--> 1], - ..., - [Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -1] - ] + [[Dirichlet character modulo 13 of conductor 1 mapping 2 |--> 1], + [Dirichlet character modulo 13 of conductor 13 mapping 2 |--> zeta12, + Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -zeta12^3 + zeta12, + Dirichlet character modulo 13 of conductor 13 mapping 2 |--> zeta12^3 - zeta12, + Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -zeta12], + [Dirichlet character modulo 13 of conductor 13 mapping 2 |--> zeta12^2, + Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -zeta12^2 + 1], + [Dirichlet character modulo 13 of conductor 13 mapping 2 |--> zeta12^3, + Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -zeta12^3], + [Dirichlet character modulo 13 of conductor 13 mapping 2 |--> zeta12^2 - 1, + Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -zeta12^2], + [Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -1]] sage: e = G.0 sage: e Dirichlet character modulo 13 of conductor 13 mapping 2 |--> zeta12 @@ -2950,15 +2957,11 @@ def decomposition(self): EXAMPLES:: sage: DirichletGroup(20).decomposition() - [ - Group of Dirichlet characters modulo 4 with values in Cyclotomic Field of order 4 and degree 2, - Group of Dirichlet characters modulo 5 with values in Cyclotomic Field of order 4 and degree 2 - ] + [Group of Dirichlet characters modulo 4 with values in Cyclotomic Field of order 4 and degree 2, + Group of Dirichlet characters modulo 5 with values in Cyclotomic Field of order 4 and degree 2] sage: DirichletGroup(20,GF(5)).decomposition() - [ - Group of Dirichlet characters modulo 4 with values in Finite Field of size 5, - Group of Dirichlet characters modulo 5 with values in Finite Field of size 5 - ] + [Group of Dirichlet characters modulo 4 with values in Finite Field of size 5, + Group of Dirichlet characters modulo 5 with values in Finite Field of size 5] """ R = self.base_ring() return Sequence([DirichletGroup(p**r, R) @@ -3047,11 +3050,14 @@ def galois_orbits(self, v=None, reps_only=False, sort=True, check=True): EXAMPLES:: sage: DirichletGroup(20).galois_orbits() - [ - [Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> -1], - ..., - [Dirichlet character modulo 20 of conductor 1 mapping 11 |--> 1, 17 |--> 1] - ] + [[Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> -1], + [Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> -zeta4, + Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> zeta4], + [Dirichlet character modulo 20 of conductor 4 mapping 11 |--> -1, 17 |--> 1], + [Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> -1], + [Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> -zeta4, + Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> zeta4], + [Dirichlet character modulo 20 of conductor 1 mapping 11 |--> 1, 17 |--> 1]] sage: DirichletGroup(17, Integers(6), zeta=Integers(6)(5)).galois_orbits() Traceback (most recent call last): ... diff --git a/src/sage/modular/hecke/ambient_module.py b/src/sage/modular/hecke/ambient_module.py index 0e769d47ace..5f0cec78f20 100644 --- a/src/sage/modular/hecke/ambient_module.py +++ b/src/sage/modular/hecke/ambient_module.py @@ -345,14 +345,8 @@ def degeneracy_map(self, codomain, t=1): sage: D = ModularSymbols(10,4).cuspidal_submodule().decomposition() sage: D - [ - Modular Symbols subspace of dimension 2 of - Modular Symbols space of dimension 10 for - Gamma_0(10) of weight 4 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 4 of - Modular Symbols space of dimension 10 for - Gamma_0(10) of weight 4 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 10 for Gamma_0(10) of weight 4 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 10 for Gamma_0(10) of weight 4 with sign 0 over Rational Field] sage: D[1].degeneracy_map(5) Hecke module morphism defined by the matrix [ 0 0 -1 1] diff --git a/src/sage/modular/hecke/hecke_operator.py b/src/sage/modular/hecke/hecke_operator.py index c7d39270f63..fddf20f75ee 100644 --- a/src/sage/modular/hecke/hecke_operator.py +++ b/src/sage/modular/hecke/hecke_operator.py @@ -295,20 +295,16 @@ def decomposition(self): sage: M = ModularSymbols(11) sage: t2 = M.hecke_operator(2) sage: t2.decomposition() - [ - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field] :: sage: M = ModularSymbols(33, sign=1).new_submodule() sage: T = M.hecke_operator(2) sage: T.decomposition() - [ - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field, - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field - ] + [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field, + Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field] """ try: return self.__decomposition diff --git a/src/sage/modular/hecke/module.py b/src/sage/modular/hecke/module.py index bbc76fd1cbc..bd5e3be5733 100644 --- a/src/sage/modular/hecke/module.py +++ b/src/sage/modular/hecke/module.py @@ -582,20 +582,15 @@ def _eigen_nonzero(self): sage: M._eigen_nonzero() 0 sage: M.dual_free_module().basis() - [ - (1, 0, 0, 0, 0), - (0, 1, 0, 0, 0), - (0, 0, 1, 0, 0), - (0, 0, 0, 1, 0), - (0, 0, 0, 0, 1) - ] + [(1, 0, 0, 0, 0), + (0, 1, 0, 0, 0), + (0, 0, 1, 0, 0), + (0, 0, 0, 1, 0), + (0, 0, 0, 0, 1)] sage: M.cuspidal_submodule().minus_submodule()._eigen_nonzero() 1 sage: M.cuspidal_submodule().minus_submodule().dual_free_module().basis() - [ - (0, 1, 0, 0, 0), - (0, 0, 1, 0, 0) - ] + [(0, 1, 0, 0, 0), (0, 0, 1, 0, 0)] """ try: return self.__eigen_nonzero @@ -944,40 +939,32 @@ def decomposition(self, bound=None, anemic=True, height_guess=1, EXAMPLES:: sage: ModularSymbols(17,2).decomposition() - [ - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(17) of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 3 for Gamma_0(17) of weight 2 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(17) of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 3 for Gamma_0(17) of weight 2 with sign 0 over Rational Field] sage: ModularSymbols(Gamma1(10),4).decomposition() - [ - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 18 for Gamma_1(10) of weight 4 with sign 0 over Rational Field] sage: ModularSymbols(GammaH(12, [11])).decomposition() - [ - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 5 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 5 of Modular Symbols space of dimension 9 for Congruence Subgroup Gamma_H(12) with H generated by [11] of weight 2 with sign 0 over Rational Field] TESTS:: sage: M = ModularSymbols(1000,2,sign=1).new_subspace().cuspidal_subspace() sage: M.decomposition(3, sort_by_basis = True) - [ - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field - ] + [Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 154 for Gamma_0(1000) of weight 2 with sign 1 over Rational Field] """ if not isinstance(anemic, bool): raise TypeError("anemic must be of type bool.") @@ -1610,10 +1597,8 @@ def projection(self): sage: m = ModularSymbols(34); s = m.cuspidal_submodule() sage: d = s.decomposition(7) sage: d - [ - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(34) of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 9 for Gamma_0(34) of weight 2 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(34) of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 9 for Gamma_0(34) of weight 2 with sign 0 over Rational Field] sage: a = d[0]; a Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(34) of weight 2 with sign 0 over Rational Field sage: pi = a.projection() diff --git a/src/sage/modular/hecke/submodule.py b/src/sage/modular/hecke/submodule.py index c542d095339..d0a28b31319 100644 --- a/src/sage/modular/hecke/submodule.py +++ b/src/sage/modular/hecke/submodule.py @@ -425,10 +425,8 @@ def degeneracy_map(self, level, t=1): EXAMPLES:: sage: D = ModularSymbols(10,4).cuspidal_submodule().decomposition(); D - [ - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 10 for Gamma_0(10) of weight 4 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 10 for Gamma_0(10) of weight 4 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 10 for Gamma_0(10) of weight 4 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 10 for Gamma_0(10) of weight 4 with sign 0 over Rational Field] sage: d = D[1].degeneracy_map(5); d Hecke module morphism defined by the matrix [ 0 0 -1 1] @@ -776,10 +774,7 @@ def linear_combination_of_basis(self, v): sage: S = M.cuspidal_submodule() sage: S.basis() - [ - q + 252*q^3 - 2048*q^4 + 4830*q^5 + O(q^6), - q^2 - 24*q^4 + O(q^6) - ] + [q + 252*q^3 - 2048*q^4 + 4830*q^5 + O(q^6), q^2 - 24*q^4 + O(q^6)] sage: S.linear_combination_of_basis([3, 10]) 3*q + 10*q^2 + 756*q^3 - 6384*q^4 + 14490*q^5 + O(q^6) """ diff --git a/src/sage/modular/local_comp/local_comp.py b/src/sage/modular/local_comp/local_comp.py index 349c1e407e1..13d346ed7d6 100644 --- a/src/sage/modular/local_comp/local_comp.py +++ b/src/sage/modular/local_comp/local_comp.py @@ -82,12 +82,8 @@ def LocalComponent(f, p, twist_factor=None): sage: Pi.species() 'Supercuspidal' sage: Pi.characters() - [ - Character of unramified extension Q_7(s)* (s^2 + 6*s + 3 = 0), - of level 1, mapping s |--> -d, 7 |--> 1, - Character of unramified extension Q_7(s)* (s^2 + 6*s + 3 = 0), - of level 1, mapping s |--> d, 7 |--> 1 - ] + [Character of unramified extension Q_7(s)* (s^2 + 6*s + 3 = 0), of level 1, mapping s |--> -d, 7 |--> 1, + Character of unramified extension Q_7(s)* (s^2 + 6*s + 3 = 0), of level 1, mapping s |--> d, 7 |--> 1] """ p = ZZ(p) if not p.is_prime(): @@ -455,15 +451,11 @@ def characters(self): EXAMPLES:: sage: LocalComponent(Newform('11a'), 17).characters() - [ - Character of Q_17*, of level 0, mapping 17 |--> d, - Character of Q_17*, of level 0, mapping 17 |--> -d - 2 - ] + [Character of Q_17*, of level 0, mapping 17 |--> d, + Character of Q_17*, of level 0, mapping 17 |--> -d - 2] sage: LocalComponent(Newforms(Gamma1(5), 6, names='a')[1], 3).characters() - [ - Character of Q_3*, of level 0, mapping 3 |--> -3/2*a1 + 12, - Character of Q_3*, of level 0, mapping 3 |--> -3/2*a1 - 12 - ] + [Character of Q_3*, of level 0, mapping 3 |--> -3/2*a1 + 12, + Character of Q_3*, of level 0, mapping 3 |--> -3/2*a1 - 12] """ f = self.satake_polynomial() if not f.is_irreducible(): @@ -495,10 +487,8 @@ def characters(self): EXAMPLES:: sage: LocalComponent(Newforms(Gamma1(13), 2, names='a')[0], 13).characters() - [ - Character of Q_13*, of level 0, mapping 13 |--> 3*a0 + 2, - Character of Q_13*, of level 1, mapping 2 |--> a0 + 2, 13 |--> -3*a0 - 7 - ] + [Character of Q_13*, of level 0, mapping 13 |--> 3*a0 + 2, + Character of Q_13*, of level 1, mapping 2 |--> a0 + 2, 13 |--> -3*a0 - 7] """ G = SmoothCharacterGroupQp(self.prime(), self.coefficient_field()) t = ZZ((self.newform().weight() - 2 - self.twist_factor()) / 2) @@ -653,12 +643,8 @@ def characters(self): sage: f = Newform('50a') sage: Pi = LocalComponent(f, 5) sage: chars = Pi.characters(); chars - [ - Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), - of level 1, mapping s |--> -d - 1, 5 |--> 1, - Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), - of level 1, mapping s |--> d, 5 |--> 1 - ] + [Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> -d - 1, 5 |--> 1, + Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> d, 5 |--> 1] sage: chars[0].base_ring() Number Field in d with defining polynomial x^2 + x + 1 @@ -673,12 +659,8 @@ def characters(self): q + j0*q^2 + 1/3*j0^3*q^3 - 1/3*j0^2*q^4 + O(q^6) sage: Pi = LocalComponent(f, 5) sage: Pi.characters() - [ - Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), - of level 1, mapping s |--> 1/3*j0^2*d - 1/3*j0^3, 5 |--> 5, - Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), - of level 1, mapping s |--> -1/3*j0^2*d, 5 |--> 5 - ] + [Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> 1/3*j0^2*d - 1/3*j0^3, 5 |--> 5, + Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> -1/3*j0^2*d, 5 |--> 5] sage: Pi.characters()[0].base_ring() Number Field in d with defining polynomial x^2 - j0*x + 1/3*j0^2 over its base field @@ -704,19 +686,11 @@ def characters(self): Some ramified examples:: sage: Newform('27a').local_component(3).characters() - [ - Character of ramified extension Q_3(s)* (s^2 - 6 = 0), - of level 2, mapping 2 |--> 1, s + 1 |--> -d, s |--> -1, - Character of ramified extension Q_3(s)* (s^2 - 6 = 0), - of level 2, mapping 2 |--> 1, s + 1 |--> d - 1, s |--> -1 - ] + [Character of ramified extension Q_3(s)* (s^2 - 6 = 0), of level 2, mapping 2 |--> 1, s + 1 |--> -d, s |--> -1, + Character of ramified extension Q_3(s)* (s^2 - 6 = 0), of level 2, mapping 2 |--> 1, s + 1 |--> d - 1, s |--> -1] sage: LocalComponent(Newform('54a'), 3, twist_factor=4).characters() - [ - Character of ramified extension Q_3(s)* (s^2 - 3 = 0), - of level 2, mapping 2 |--> 1, s + 1 |--> -1/9*d, s |--> -9, - Character of ramified extension Q_3(s)* (s^2 - 3 = 0), - of level 2, mapping 2 |--> 1, s + 1 |--> 1/9*d - 1, s |--> -9 - ] + [Character of ramified extension Q_3(s)* (s^2 - 3 = 0), of level 2, mapping 2 |--> 1, s + 1 |--> -1/9*d, s |--> -9, + Character of ramified extension Q_3(s)* (s^2 - 3 = 0), of level 2, mapping 2 |--> 1, s + 1 |--> 1/9*d - 1, s |--> -9] A 2-adic non-example:: @@ -1067,10 +1041,8 @@ def characters(self): sage: f = [f for f in Newforms(63, 4, names='a') if f[2] == 1][0] sage: f.local_component(3).characters() - [ - Character of Q_3*, of level 1, mapping 2 |--> -1, 3 |--> d, - Character of Q_3*, of level 1, mapping 2 |--> -1, 3 |--> -d - 2 - ] + [Character of Q_3*, of level 1, mapping 2 |--> -1, 3 |--> d, + Character of Q_3*, of level 1, mapping 2 |--> -1, 3 |--> -d - 2] """ minchars = self._min_twist.characters() G = minchars[0].parent() diff --git a/src/sage/modular/modform/ambient.py b/src/sage/modular/modform/ambient.py index bf67263db8c..95e414bcb37 100644 --- a/src/sage/modular/modform/ambient.py +++ b/src/sage/modular/modform/ambient.py @@ -20,27 +20,23 @@ Compute a basis:: sage: n.basis() - [ - 1 + O(q^6), - q + O(q^6), - q^2 + O(q^6), - q^3 + O(q^6), - q^4 + O(q^6), - q^5 + O(q^6) - ] + [1 + O(q^6), + q + O(q^6), + q^2 + O(q^6), + q^3 + O(q^6), + q^4 + O(q^6), + q^5 + O(q^6)] Compute the same basis but to higher precision:: sage: n.set_precision(20) sage: n.basis() - [ - 1 + 10*q^10 + 20*q^15 + O(q^20), - q + 5*q^6 + q^9 + 12*q^11 - 3*q^14 + 17*q^16 + 8*q^19 + O(q^20), - q^2 + 4*q^7 - q^8 + 8*q^12 + 2*q^13 + 10*q^17 - 5*q^18 + O(q^20), - q^3 + q^7 + 3*q^8 - q^12 + 5*q^13 + 3*q^17 + 6*q^18 + O(q^20), - q^4 - q^6 + 2*q^9 + 3*q^14 - 2*q^16 + 4*q^19 + O(q^20), - q^5 + q^10 + 2*q^15 + O(q^20) - ] + [1 + 10*q^10 + 20*q^15 + O(q^20), + q + 5*q^6 + q^9 + 12*q^11 - 3*q^14 + 17*q^16 + 8*q^19 + O(q^20), + q^2 + 4*q^7 - q^8 + 8*q^12 + 2*q^13 + 10*q^17 - 5*q^18 + O(q^20), + q^3 + q^7 + 3*q^8 - q^12 + 5*q^13 + 3*q^17 + 6*q^18 + O(q^20), + q^4 - q^6 + 2*q^9 + 3*q^14 - 2*q^16 + 4*q^19 + O(q^20), + q^5 + q^10 + 2*q^15 + O(q^20)] TESTS:: @@ -165,11 +161,9 @@ def change_ring(self, base_ring): sage: M = ModularForms(Gamma0(37),2) sage: M.basis() - [ - q + q^3 - 2*q^4 + O(q^6), - q^2 + 2*q^3 - 2*q^4 + q^5 + O(q^6), - 1 + 2/3*q + 2*q^2 + 8/3*q^3 + 14/3*q^4 + 4*q^5 + O(q^6) - ] + [q + q^3 - 2*q^4 + O(q^6), + q^2 + 2*q^3 - 2*q^4 + q^5 + O(q^6), + 1 + 2/3*q + 2*q^2 + 8/3*q^3 + 14/3*q^4 + 4*q^5 + O(q^6)] The basis after changing the base ring is the reduction modulo `3` of an integral basis. @@ -178,11 +172,9 @@ def change_ring(self, base_ring): sage: M3 = M.change_ring(GF(3)) sage: M3.basis() - [ - q + q^3 + q^4 + O(q^6), - q^2 + 2*q^3 + q^4 + q^5 + O(q^6), - 1 + q^3 + q^4 + 2*q^5 + O(q^6) - ] + [q + q^3 + q^4 + O(q^6), + q^2 + 2*q^3 + q^4 + q^5 + O(q^6), + 1 + q^3 + q^4 + 2*q^5 + O(q^6)] """ from . import constructor M = constructor.ModularForms(self.group(), self.weight(), base_ring, prec=self.prec(), eis_only=self._eis_only) @@ -376,20 +368,15 @@ def prec(self, new_prec=None): :: sage: M.basis() - [ - q - 24*q^2 + O(q^3), - 1 + 65520/691*q + 134250480/691*q^2 + O(q^3) - ] + [q - 24*q^2 + O(q^3), 1 + 65520/691*q + 134250480/691*q^2 + O(q^3)] :: sage: M.prec(5) 5 sage: M.basis() - [ - q - 24*q^2 + 252*q^3 - 1472*q^4 + O(q^5), - 1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 + 274945048560/691*q^4 + O(q^5) - ] + [q - 24*q^2 + 252*q^3 - 1472*q^4 + O(q^5), + 1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 + 274945048560/691*q^4 + O(q^5)] """ if new_prec: self.__prec = new_prec @@ -408,18 +395,14 @@ def set_precision(self, n): sage: m = ModularForms(Gamma1(5),2) sage: m.set_precision(10) sage: m.basis() - [ - 1 + 60*q^3 - 120*q^4 + 240*q^5 - 300*q^6 + 300*q^7 - 180*q^9 + O(q^10), - q + 6*q^3 - 9*q^4 + 27*q^5 - 28*q^6 + 30*q^7 - 11*q^9 + O(q^10), - q^2 - 4*q^3 + 12*q^4 - 22*q^5 + 30*q^6 - 24*q^7 + 5*q^8 + 18*q^9 + O(q^10) - ] + [1 + 60*q^3 - 120*q^4 + 240*q^5 - 300*q^6 + 300*q^7 - 180*q^9 + O(q^10), + q + 6*q^3 - 9*q^4 + 27*q^5 - 28*q^6 + 30*q^7 - 11*q^9 + O(q^10), + q^2 - 4*q^3 + 12*q^4 - 22*q^5 + 30*q^6 - 24*q^7 + 5*q^8 + 18*q^9 + O(q^10)] sage: m.set_precision(5) sage: m.basis() - [ - 1 + 60*q^3 - 120*q^4 + O(q^5), - q + 6*q^3 - 9*q^4 + O(q^5), - q^2 - 4*q^3 + 12*q^4 + O(q^5) - ] + [1 + 60*q^3 - 120*q^4 + O(q^5), + q + 6*q^3 - 9*q^4 + O(q^5), + q^2 - 4*q^3 + 12*q^4 + O(q^5)] """ if n < 0: raise ValueError("n (=%s) must be >= 0" % n) @@ -480,12 +463,10 @@ def new_submodule(self, p=None): sage: N = M.new_subspace(); N Modular Forms subspace of dimension 4 of Modular Forms space of dimension 6 for Congruence Subgroup Gamma0(17) of weight 4 over Rational Field sage: N.basis() - [ - q + 2*q^5 + O(q^6), - q^2 - 3/2*q^5 + O(q^6), - q^3 + O(q^6), - q^4 - 1/2*q^5 + O(q^6) - ] + [q + 2*q^5 + O(q^6), + q^2 - 3/2*q^5 + O(q^6), + q^3 + O(q^6), + q^4 - 1/2*q^5 + O(q^6)] :: @@ -529,11 +510,9 @@ def _q_expansion(self, element, prec): sage: m = ModularForms(Gamma0(23),2); m Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(23) of weight 2 over Rational Field sage: m.basis() - [ - q - q^3 - q^4 + O(q^6), - q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6), - 1 + 12/11*q + 36/11*q^2 + 48/11*q^3 + 84/11*q^4 + 72/11*q^5 + O(q^6) - ] + [q - q^3 - q^4 + O(q^6), + q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6), + 1 + 12/11*q + 36/11*q^2 + 48/11*q^3 + 84/11*q^4 + 72/11*q^5 + O(q^6)] sage: m._q_expansion([1,2,0], 5) q + 2*q^2 - 5*q^3 - 3*q^4 + O(q^5) """ @@ -699,32 +678,26 @@ def eisenstein_series(self): :: sage: ModularForms(27,2).eisenstein_series() - [ - q^3 + O(q^6), - q - 3*q^2 + 7*q^4 - 6*q^5 + O(q^6), - 1/12 + q + 3*q^2 + q^3 + 7*q^4 + 6*q^5 + O(q^6), - 1/3 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6), - 13/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6) - ] + [q^3 + O(q^6), + q - 3*q^2 + 7*q^4 - 6*q^5 + O(q^6), + 1/12 + q + 3*q^2 + q^3 + 7*q^4 + 6*q^5 + O(q^6), + 1/3 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6), + 13/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6)] :: sage: ModularForms(Gamma1(5),3).eisenstein_series() - [ - -1/5*zeta4 - 2/5 + q + (4*zeta4 + 1)*q^2 + (-9*zeta4 + 1)*q^3 + (4*zeta4 - 15)*q^4 + q^5 + O(q^6), - q + (zeta4 + 4)*q^2 + (-zeta4 + 9)*q^3 + (4*zeta4 + 15)*q^4 + 25*q^5 + O(q^6), - 1/5*zeta4 - 2/5 + q + (-4*zeta4 + 1)*q^2 + (9*zeta4 + 1)*q^3 + (-4*zeta4 - 15)*q^4 + q^5 + O(q^6), - q + (-zeta4 + 4)*q^2 + (zeta4 + 9)*q^3 + (-4*zeta4 + 15)*q^4 + 25*q^5 + O(q^6) - ] + [-1/5*zeta4 - 2/5 + q + (4*zeta4 + 1)*q^2 + (-9*zeta4 + 1)*q^3 + (4*zeta4 - 15)*q^4 + q^5 + O(q^6), + q + (zeta4 + 4)*q^2 + (-zeta4 + 9)*q^3 + (4*zeta4 + 15)*q^4 + 25*q^5 + O(q^6), + 1/5*zeta4 - 2/5 + q + (-4*zeta4 + 1)*q^2 + (9*zeta4 + 1)*q^3 + (-4*zeta4 - 15)*q^4 + q^5 + O(q^6), + q + (-zeta4 + 4)*q^2 + (zeta4 + 9)*q^3 + (-4*zeta4 + 15)*q^4 + 25*q^5 + O(q^6)] :: sage: eps = DirichletGroup(13).0^2 sage: ModularForms(eps,2).eisenstein_series() - [ - -7/13*zeta6 - 11/13 + q + (2*zeta6 + 1)*q^2 + (-3*zeta6 + 1)*q^3 + (6*zeta6 - 3)*q^4 - 4*q^5 + O(q^6), - q + (zeta6 + 2)*q^2 + (-zeta6 + 3)*q^3 + (3*zeta6 + 3)*q^4 + 4*q^5 + O(q^6) - ] + [-7/13*zeta6 - 11/13 + q + (2*zeta6 + 1)*q^2 + (-3*zeta6 + 1)*q^3 + (6*zeta6 - 3)*q^4 - 4*q^5 + O(q^6), + q + (zeta6 + 2)*q^2 + (-zeta6 + 3)*q^3 + (3*zeta6 + 3)*q^4 + 4*q^5 + O(q^6)] """ return self.eisenstein_submodule().eisenstein_series() diff --git a/src/sage/modular/modform/ambient_g1.py b/src/sage/modular/modform/ambient_g1.py index 31db01bd081..043823c0238 100644 --- a/src/sage/modular/modform/ambient_g1.py +++ b/src/sage/modular/modform/ambient_g1.py @@ -8,18 +8,13 @@ sage: S = M.cuspidal_submodule(); S Cuspidal subspace of dimension 2 of Modular Forms space of dimension 13 for Congruence Subgroup Gamma1(13) of weight 2 over Rational Field sage: S.basis() - [ - q - 4*q^3 - q^4 + 3*q^5 + O(q^6), - q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6) - ] + [q - 4*q^3 - q^4 + 3*q^5 + O(q^6), q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6)] sage: M = ModularForms(GammaH(11, [3])); M Modular Forms space of dimension 2 for Congruence Subgroup Gamma_H(11) with H generated by [3] of weight 2 over Rational Field sage: M.q_expansion_basis(8) - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 + O(q^8), - 1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + 144/5*q^6 + 96/5*q^7 + O(q^8) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 + O(q^8), + 1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + 144/5*q^6 + 96/5*q^7 + O(q^8)] TESTS:: diff --git a/src/sage/modular/modform/constructor.py b/src/sage/modular/modform/constructor.py index 425015535c6..db65774b193 100644 --- a/src/sage/modular/modform/constructor.py +++ b/src/sage/modular/modform/constructor.py @@ -9,14 +9,12 @@ Modular Forms space of dimension 6 for Congruence Subgroup Gamma1(4) of weight 11 over Rational Field sage: m.basis() - [ - q - 134*q^5 + O(q^6), - q^2 + 80*q^5 + O(q^6), - q^3 + 16*q^5 + O(q^6), - q^4 - 4*q^5 + O(q^6), - 1 + 4092/50521*q^2 + 472384/50521*q^3 + 4194300/50521*q^4 + O(q^6), - q + 1024*q^2 + 59048*q^3 + 1048576*q^4 + 9765626*q^5 + O(q^6) - ] + [q - 134*q^5 + O(q^6), + q^2 + 80*q^5 + O(q^6), + q^3 + 16*q^5 + O(q^6), + q^4 - 4*q^5 + O(q^6), + 1 + 4092/50521*q^2 + 472384/50521*q^3 + 4194300/50521*q^4 + O(q^6), + q + 1024*q^2 + 59048*q^3 + 1048576*q^4 + 9765626*q^5 + O(q^6)] """ # **************************************************************************** @@ -270,16 +268,13 @@ def ModularForms(group=1, Modular Forms space of dimension 5 for Congruence Subgroup Gamma1(11) of weight 1 over Rational Field sage: M.basis() - [ - 1 + 22*q^5 + O(q^6), - q + 4*q^5 + O(q^6), - q^2 - 4*q^5 + O(q^6), - q^3 - 5*q^5 + O(q^6), - q^4 - 3*q^5 + O(q^6) - ] + [1 + 22*q^5 + O(q^6), + q + 4*q^5 + O(q^6), + q^2 - 4*q^5 + O(q^6), + q^3 - 5*q^5 + O(q^6), + q^4 - 3*q^5 + O(q^6)] sage: M.cuspidal_subspace().basis() - [ - ] + [] sage: M == M.eisenstein_subspace() True diff --git a/src/sage/modular/modform/cuspidal_submodule.py b/src/sage/modular/modform/cuspidal_submodule.py index 90cf7758cdc..942b6d628b6 100644 --- a/src/sage/modular/modform/cuspidal_submodule.py +++ b/src/sage/modular/modform/cuspidal_submodule.py @@ -8,27 +8,19 @@ Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field sage: S.basis() - [ - q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) - ] + [q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)] sage: S = CuspForms(Gamma0(33),2); S Cuspidal subspace of dimension 3 of Modular Forms space of dimension 6 for Congruence Subgroup Gamma0(33) of weight 2 over Rational Field sage: S.basis() - [ - q - q^5 + O(q^6), - q^2 - q^4 - q^5 + O(q^6), - q^3 + O(q^6) - ] + [q - q^5 + O(q^6), q^2 - q^4 - q^5 + O(q^6), q^3 + O(q^6)] sage: S = CuspForms(Gamma1(3),6); S Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3 for Congruence Subgroup Gamma1(3) of weight 6 over Rational Field sage: S.basis() - [ - q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6) - ] + [q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6)] """ ######################################################################### @@ -67,27 +59,19 @@ def __init__(self, ambient_space): Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field sage: S.basis() - [ - q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) - ] + [q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)] sage: S = CuspForms(Gamma0(33),2); S Cuspidal subspace of dimension 3 of Modular Forms space of dimension 6 for Congruence Subgroup Gamma0(33) of weight 2 over Rational Field sage: S.basis() - [ - q - q^5 + O(q^6), - q^2 - q^4 - q^5 + O(q^6), - q^3 + O(q^6) - ] + [q - q^5 + O(q^6), q^2 - q^4 - q^5 + O(q^6), q^3 + O(q^6)] sage: S = CuspForms(Gamma1(3),6); S Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3 for Congruence Subgroup Gamma1(3) of weight 6 over Rational Field sage: S.basis() - [ - q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6) - ] + [q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6)] sage: S == loads(dumps(S)) True """ @@ -223,10 +207,7 @@ def _compute_q_expansion_basis(self, prec): sage: # needs sage.rings.number_field sage: CuspForms(Gamma1(13), 2, base_ring=QuadraticField(-7, 'a')).q_expansion_basis() # indirect doctest - [ - q - 4*q^3 - q^4 + 3*q^5 + O(q^6), - q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6) - ] + [q - 4*q^3 - q^4 + 3*q^5 + O(q^6), q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6)] """ return ModularFormsSubmodule._compute_q_expansion_basis(self, prec) @@ -242,9 +223,7 @@ def _compute_q_expansion_basis(self, prec=None): EXAMPLES:: sage: sage.modular.modform.cuspidal_submodule.CuspidalSubmodule_modsym_qexp(ModularForms(11,2))._compute_q_expansion_basis() - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)] """ if prec is None: prec = self.prec() @@ -327,9 +306,7 @@ def _compute_q_expansion_basis(self, prec=None): EXAMPLES:: sage: sage.modular.modform.cuspidal_submodule.CuspidalSubmodule_level1_Q(ModularForms(1,12))._compute_q_expansion_basis() - [ - q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) - ] + [q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)] """ if prec is None: prec = self.prec() @@ -365,9 +342,7 @@ def _compute_q_expansion_basis(self, prec=None): EXAMPLES:: sage: CuspForms(DirichletGroup(23, QQ).0, 1).q_echelon_basis() # indirect doctest - [ - q - q^2 - q^3 + O(q^6) - ] + [q - q^2 - q^3 + O(q^6)] """ if prec is None: prec = self.prec() @@ -405,9 +380,7 @@ def _compute_q_expansion_basis(self, prec=None): EXAMPLES:: sage: CuspForms(GammaH(31, [7]), 1).q_expansion_basis() # indirect doctest - [ - q - q^2 - q^5 + O(q^6) - ] + [q - q^2 - q^5 + O(q^6)] A more elaborate example (two Galois-conjugate characters each giving a 2-dimensional space):: @@ -661,9 +634,7 @@ class CuspidalSubmodule_eps(CuspidalSubmodule_modsym_qexp): character [zeta4] and weight 5 over Cyclotomic Field of order 4 and degree 2 sage: S.basis() - [ - q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - 14*zeta4*q^4 + (15*zeta4 + 20)*q^5 + O(q^6) - ] + [q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - 14*zeta4*q^4 + (15*zeta4 + 20)*q^5 + O(q^6)] sage: f = S.0 sage: f.qexp() q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - 14*zeta4*q^4 + (15*zeta4 + 20)*q^5 + O(q^6) diff --git a/src/sage/modular/modform/eisenstein_submodule.py b/src/sage/modular/modform/eisenstein_submodule.py index 72665f3d686..278985d884d 100644 --- a/src/sage/modular/modform/eisenstein_submodule.py +++ b/src/sage/modular/modform/eisenstein_submodule.py @@ -178,11 +178,7 @@ def new_submodule(self, p=None): Modular Forms subspace of dimension 3 of Modular Forms space of dimension 42 for Congruence Subgroup Gamma0(225) of weight 2 over Rational Field sage: e.basis() - [ - q + O(q^6), - q^2 + O(q^6), - q^4 + O(q^6) - ] + [q + O(q^6), q^2 + O(q^6), q^4 + O(q^6)] """ if p is not None: @@ -210,24 +206,12 @@ def change_ring(self, base_ring): Eisenstein subspace of dimension 5 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(12) of weight 2 over Rational Field sage: E.basis() - [ - 1 + O(q^6), - q + 6*q^5 + O(q^6), - q^2 + O(q^6), - q^3 + O(q^6), - q^4 + O(q^6) - ] + [1 + O(q^6), q + 6*q^5 + O(q^6), q^2 + O(q^6), q^3 + O(q^6), q^4 + O(q^6)] sage: E.change_ring(GF(5)) Eisenstein subspace of dimension 5 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(12) of weight 2 over Finite Field of size 5 sage: E.change_ring(GF(5)).basis() - [ - 1 + O(q^6), - q + q^5 + O(q^6), - q^2 + O(q^6), - q^3 + O(q^6), - q^4 + O(q^6) - ] + [1 + O(q^6), q + q^5 + O(q^6), q^2 + O(q^6), q^3 + O(q^6), q^4 + O(q^6)] """ if base_ring == self.base_ring(): return self @@ -243,71 +227,48 @@ def eisenstein_series(self): EXAMPLES:: sage: EisensteinForms(11,2).eisenstein_series() - [ - 5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6) - ] + [5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6)] sage: EisensteinForms(1,4).eisenstein_series() - [ - 1/240 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6) - ] + [1/240 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6)] sage: EisensteinForms(1,24).eisenstein_series() - [ - 236364091/131040 + q + 8388609*q^2 + 94143178828*q^3 - + 70368752566273*q^4 + 11920928955078126*q^5 + O(q^6) - ] + [236364091/131040 + q + 8388609*q^2 + 94143178828*q^3 + 70368752566273*q^4 + 11920928955078126*q^5 + O(q^6)] sage: EisensteinForms(5,4).eisenstein_series() - [ - 1/240 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6), - 1/240 + q^5 + O(q^6) - ] + [1/240 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6), 1/240 + q^5 + O(q^6)] sage: EisensteinForms(13,2).eisenstein_series() - [ - 1/2 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6) - ] + [1/2 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6)] sage: E = EisensteinForms(Gamma1(7),2) sage: E.set_precision(4) sage: E.eisenstein_series() - [ - 1/4 + q + 3*q^2 + 4*q^3 + O(q^4), - 1/7*zeta6 - 3/7 + q + (-2*zeta6 + 1)*q^2 + (3*zeta6 - 2)*q^3 + O(q^4), - q + (-zeta6 + 2)*q^2 + (zeta6 + 2)*q^3 + O(q^4), - -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + O(q^4), - q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + O(q^4) - ] + [1/4 + q + 3*q^2 + 4*q^3 + O(q^4), + 1/7*zeta6 - 3/7 + q + (-2*zeta6 + 1)*q^2 + (3*zeta6 - 2)*q^3 + O(q^4), + q + (-zeta6 + 2)*q^2 + (zeta6 + 2)*q^3 + O(q^4), + -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + O(q^4), + q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + O(q^4)] sage: eps = DirichletGroup(13).0^2 sage: ModularForms(eps,2).eisenstein_series() - [ - -7/13*zeta6 - 11/13 + q + (2*zeta6 + 1)*q^2 + (-3*zeta6 + 1)*q^3 - + (6*zeta6 - 3)*q^4 - 4*q^5 + O(q^6), - q + (zeta6 + 2)*q^2 + (-zeta6 + 3)*q^3 + (3*zeta6 + 3)*q^4 + 4*q^5 + O(q^6) - ] + [-7/13*zeta6 - 11/13 + q + (2*zeta6 + 1)*q^2 + (-3*zeta6 + 1)*q^3 + (6*zeta6 - 3)*q^4 - 4*q^5 + O(q^6), + q + (zeta6 + 2)*q^2 + (-zeta6 + 3)*q^3 + (3*zeta6 + 3)*q^4 + 4*q^5 + O(q^6)] sage: M = ModularForms(19,3).eisenstein_subspace() sage: M.eisenstein_series() - [ - ] + [] sage: M = ModularForms(DirichletGroup(13).0, 1) sage: M.eisenstein_series() - [ - -1/13*zeta12^3 + 6/13*zeta12^2 + 4/13*zeta12 + 2/13 + q + (zeta12 + 1)*q^2 - + zeta12^2*q^3 + (zeta12^2 + zeta12 + 1)*q^4 + (-zeta12^3 + 1)*q^5 + O(q^6) - ] + [-1/13*zeta12^3 + 6/13*zeta12^2 + 4/13*zeta12 + 2/13 + q + (zeta12 + 1)*q^2 + zeta12^2*q^3 + (zeta12^2 + zeta12 + 1)*q^4 + (-zeta12^3 + 1)*q^5 + O(q^6)] sage: M = ModularForms(GammaH(15, [4]), 4) sage: M.eisenstein_series() - [ - 1/240 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6), - 1/240 + q^3 + O(q^6), - 1/240 + q^5 + O(q^6), - 1/240 + O(q^6), - 1 + q - 7*q^2 - 26*q^3 + 57*q^4 + q^5 + O(q^6), - 1 + q^3 + O(q^6), - q + 7*q^2 + 26*q^3 + 57*q^4 + 125*q^5 + O(q^6), - q^3 + O(q^6) - ] + [1/240 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6), + 1/240 + q^3 + O(q^6), + 1/240 + q^5 + O(q^6), + 1/240 + O(q^6), + 1 + q - 7*q^2 - 26*q^3 + 57*q^4 + q^5 + O(q^6), + 1 + q^3 + O(q^6), + q + 7*q^2 + 26*q^3 + 57*q^4 + 125*q^5 + O(q^6), + q^3 + O(q^6)] """ P = self.parameters() E = Sequence([element.EisensteinSeries(self.change_ring(chi.base_ring()), @@ -562,29 +523,24 @@ class EisensteinSubmodule_eps(EisensteinSubmodule_params): 6 sage: M.eisenstein_series() - [ - -1/3*zeta6 - 1/3 + q + (2*zeta6 - 1)*q^2 + q^3 - + (-2*zeta6 - 1)*q^4 + (-5*zeta6 + 1)*q^5 + O(q^6), - -1/3*zeta6 - 1/3 + q^3 + O(q^6), - q + (-2*zeta6 + 1)*q^2 + (-2*zeta6 - 1)*q^4 + (5*zeta6 - 1)*q^5 + O(q^6), - q + (zeta6 + 1)*q^2 + 3*q^3 + (zeta6 + 2)*q^4 + (-zeta6 + 5)*q^5 + O(q^6), - q^3 + O(q^6), - q + (-zeta6 - 1)*q^2 + (zeta6 + 2)*q^4 + (zeta6 - 5)*q^5 + O(q^6) - ] + [-1/3*zeta6 - 1/3 + q + (2*zeta6 - 1)*q^2 + q^3 + (-2*zeta6 - 1)*q^4 + (-5*zeta6 + 1)*q^5 + O(q^6), + -1/3*zeta6 - 1/3 + q^3 + O(q^6), + q + (-2*zeta6 + 1)*q^2 + (-2*zeta6 - 1)*q^4 + (5*zeta6 - 1)*q^5 + O(q^6), + q + (zeta6 + 1)*q^2 + 3*q^3 + (zeta6 + 2)*q^4 + (-zeta6 + 5)*q^5 + O(q^6), + q^3 + O(q^6), + q + (-zeta6 - 1)*q^2 + (zeta6 + 2)*q^4 + (zeta6 - 5)*q^5 + O(q^6)] sage: M.eisenstein_subspace().T(2).matrix().fcp() (x + 2*zeta3 + 1) * (x + zeta3 + 2) * (x - zeta3 - 2)^2 * (x - 2*zeta3 - 1)^2 sage: ModularSymbols(e,2).eisenstein_subspace().T(2).matrix().fcp() (x + 2*zeta3 + 1) * (x + zeta3 + 2) * (x - zeta3 - 2)^2 * (x - 2*zeta3 - 1)^2 sage: M.basis() - [ - 1 - 3*zeta3*q^6 + (-2*zeta3 + 2)*q^9 + O(q^10), - q + (5*zeta3 + 5)*q^7 + O(q^10), - q^2 - 2*zeta3*q^8 + O(q^10), - q^3 + (zeta3 + 2)*q^6 + 3*q^9 + O(q^10), - q^4 - 2*zeta3*q^7 + O(q^10), - q^5 + (zeta3 + 1)*q^8 + O(q^10) - ] + [1 - 3*zeta3*q^6 + (-2*zeta3 + 2)*q^9 + O(q^10), + q + (5*zeta3 + 5)*q^7 + O(q^10), + q^2 - 2*zeta3*q^8 + O(q^10), + q^3 + (zeta3 + 2)*q^6 + 3*q^9 + O(q^10), + q^4 - 2*zeta3*q^7 + O(q^10), + q^5 + (zeta3 + 1)*q^8 + O(q^10)] """ def _pari_init_(self): """ diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index 441812135b6..3fdabbfed7b 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -1885,10 +1885,8 @@ def _defining_modular_symbols(self): [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field, Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field] sage: ModularSymbols(43,2,sign=1).cuspidal_subspace().new_subspace().decomposition() - [ - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field, - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field - ] + [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field] """ return self.__modsym_space @@ -3023,24 +3021,18 @@ class EisensteinSeries(ModularFormElement): sage: E = EisensteinForms(1,12) sage: E.eisenstein_series() - [ - 691/65520 + q + 2049*q^2 + 177148*q^3 + 4196353*q^4 + 48828126*q^5 + O(q^6) - ] + [691/65520 + q + 2049*q^2 + 177148*q^3 + 4196353*q^4 + 48828126*q^5 + O(q^6)] sage: E = EisensteinForms(11,2) sage: E.eisenstein_series() - [ - 5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6) - ] + [5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6)] sage: E = EisensteinForms(Gamma1(7),2) sage: E.set_precision(4) sage: E.eisenstein_series() - [ - 1/4 + q + 3*q^2 + 4*q^3 + O(q^4), - 1/7*zeta6 - 3/7 + q + (-2*zeta6 + 1)*q^2 + (3*zeta6 - 2)*q^3 + O(q^4), - q + (-zeta6 + 2)*q^2 + (zeta6 + 2)*q^3 + O(q^4), - -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + O(q^4), - q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + O(q^4) - ] + [1/4 + q + 3*q^2 + 4*q^3 + O(q^4), + 1/7*zeta6 - 3/7 + q + (-2*zeta6 + 1)*q^2 + (3*zeta6 - 2)*q^3 + O(q^4), + q + (-zeta6 + 2)*q^2 + (zeta6 + 2)*q^3 + O(q^4), + -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + O(q^4), + q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + O(q^4)] """ def __init__(self, parent, vector, t, chi, psi): """ @@ -3050,24 +3042,18 @@ def __init__(self, parent, vector, t, chi, psi): sage: E = EisensteinForms(1,12) # indirect doctest sage: E.eisenstein_series() - [ - 691/65520 + q + 2049*q^2 + 177148*q^3 + 4196353*q^4 + 48828126*q^5 + O(q^6) - ] + [691/65520 + q + 2049*q^2 + 177148*q^3 + 4196353*q^4 + 48828126*q^5 + O(q^6)] sage: E = EisensteinForms(11,2) sage: E.eisenstein_series() - [ - 5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6) - ] + [5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6)] sage: E = EisensteinForms(Gamma1(7),2) sage: E.set_precision(4) sage: E.eisenstein_series() - [ - 1/4 + q + 3*q^2 + 4*q^3 + O(q^4), - 1/7*zeta6 - 3/7 + q + (-2*zeta6 + 1)*q^2 + (3*zeta6 - 2)*q^3 + O(q^4), - q + (-zeta6 + 2)*q^2 + (zeta6 + 2)*q^3 + O(q^4), - -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + O(q^4), - q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + O(q^4) - ] + [1/4 + q + 3*q^2 + 4*q^3 + O(q^4), + 1/7*zeta6 - 3/7 + q + (-2*zeta6 + 1)*q^2 + (3*zeta6 - 2)*q^3 + O(q^4), + q + (-zeta6 + 2)*q^2 + (zeta6 + 2)*q^3 + O(q^4), + -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + O(q^4), + q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + O(q^4)] """ N = parent.level() K = parent.base_ring() @@ -3293,10 +3279,8 @@ def character(self): sage: chi = DirichletGroup(7)[4] sage: E = EisensteinForms(chi).eisenstein_series() ; E - [ - -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + (-2*zeta6 - 1)*q^4 + (5*zeta6 - 4)*q^5 + O(q^6), - q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + (zeta6 + 2)*q^4 + (zeta6 + 4)*q^5 + O(q^6) - ] + [-1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + (-2*zeta6 - 1)*q^4 + (5*zeta6 - 4)*q^5 + O(q^6), + q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + (zeta6 + 2)*q^4 + (zeta6 + 4)*q^5 + O(q^6)] sage: E[0].character() == chi True sage: E[1].character() == chi diff --git a/src/sage/modular/modform/hecke_operator_on_qexp.py b/src/sage/modular/modform/hecke_operator_on_qexp.py index 5133c7612c9..6693efbdd3a 100644 --- a/src/sage/modular/modform/hecke_operator_on_qexp.py +++ b/src/sage/modular/modform/hecke_operator_on_qexp.py @@ -187,11 +187,8 @@ def hecke_operator_on_basis(B, n, k, eps=None, already_echelonized=False): sage: sage.modular.modform.constructor.ModularForms_clear_cache() sage: ModularForms(1,12).q_expansion_basis() - [ - q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6), - 1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 - + 274945048560/691*q^4 + 3199218815520/691*q^5 + O(q^6) - ] + [q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6), + 1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 + 274945048560/691*q^4 + 3199218815520/691*q^5 + O(q^6)] sage: hecke_operator_on_basis(ModularForms(1,12).q_expansion_basis(), 3, 12) Traceback (most recent call last): ... diff --git a/src/sage/modular/modform/numerical.py b/src/sage/modular/modform/numerical.py index dd14ff15995..403289b678b 100644 --- a/src/sage/modular/modform/numerical.py +++ b/src/sage/modular/modform/numerical.py @@ -76,17 +76,13 @@ class NumericalEigenforms(SageObject): sage: n.ap(2) # abs tol 1e-12 [3.0, -1.6180339887498947, 0.6180339887498968] sage: n.systems_of_eigenvalues(7) # abs tol 2e-12 - [ - [-1.6180339887498947, 2.2360679774997894, -3.2360679774997894], - [0.6180339887498968, -2.236067977499788, 1.2360679774997936], - [3.0, 4.0, 6.0] - ] + [[-1.6180339887498947, 2.23606797749979, -3.2360679774997894], + [0.618033988749895, -2.236067977499788, 1.23606797749979], + [3.0, 4.0, 6.0]] sage: n.systems_of_abs(7) # abs tol 2e-12 - [ - [0.6180339887498943, 2.2360679774997894, 1.2360679774997887], - [1.6180339887498947, 2.23606797749979, 3.2360679774997894], - [3.0, 4.0, 6.0] - ] + [[0.618033988749895, 2.236067977499788, 1.23606797749979], + [1.6180339887498947, 2.23606797749979, 3.2360679774997894], + [3.0, 4.0, 6.0]] sage: n.eigenvalues([2,3,5]) # rel tol 2e-12 [[3.0, -1.6180339887498947, 0.6180339887498968], [4.0, 2.2360679774997894, -2.236067977499788], @@ -443,13 +439,20 @@ def systems_of_eigenvalues(self, bound): EXAMPLES:: sage: numerical_eigenforms(61).systems_of_eigenvalues(10) # rel tol 1e-9 - [ - [-1.4811943040920152, 0.8060634335253695, 3.1563251746586642, 0.6751308705666477], - [-1.0, -2.0000000000000027, -3.000000000000003, 1.0000000000000044], - [0.3111078174659775, 2.903211925911551, -2.525427560843529, -3.214319743377552], - [2.170086486626034, -1.7092753594369208, -1.63089761381512, -0.46081112718908984], - [3.0, 4.0, 6.0, 8.0] - ] + [[-1.481194304092014, + 0.8060634335253706, + 3.156325174658664, + 0.6751308705666462], + [-1.0, -2.0, -3.0, 1.0], + [0.311107817465981, + 2.903211925911551, + -2.5254275608435184, + -3.214319743377534], + [2.1700864866260323, + -1.7092753594369237, + -1.6308976138151459, + -0.460811127189112], + [3.0, 4.0, 6.0, 8.0]] """ P = prime_range(bound) e = self.eigenvalues(P) @@ -470,13 +473,17 @@ def systems_of_abs(self, bound): EXAMPLES:: sage: numerical_eigenforms(61).systems_of_abs(10) # rel tol 1e-9 - [ - [0.3111078174659775, 2.903211925911551, 2.525427560843529, 3.214319743377552], - [1.0, 2.0000000000000027, 3.000000000000003, 1.0000000000000044], - [1.4811943040920152, 0.8060634335253695, 3.1563251746586642, 0.6751308705666477], - [2.170086486626034, 1.7092753594369208, 1.63089761381512, 0.46081112718908984], - [3.0, 4.0, 6.0, 8.0] - ] + [[0.311107817465981, 2.903211925911551, 2.5254275608435184, 3.214319743377534], + [1.0, 2.0, 3.0, 1.0], + [1.481194304092014, + 0.8060634335253706, + 3.156325174658664, + 0.6751308705666462], + [2.1700864866260323, + 1.7092753594369237, + 1.6308976138151459, + 0.460811127189112], + [3.0, 4.0, 6.0, 8.0]] """ P = prime_range(bound) e = self.eigenvalues(P) diff --git a/src/sage/modular/modform/ring.py b/src/sage/modular/modform/ring.py index dacfda54bae..dca6c86f125 100644 --- a/src/sage/modular/modform/ring.py +++ b/src/sage/modular/modform/ring.py @@ -89,11 +89,9 @@ def _span_of_forms_in_weight(forms, weight, prec, stop_dim=None, use_random=Fals [ 0 1 0 195660 12080128] [ 0 0 1 -48 1080] sage: ModularForms(1, 24).q_echelon_basis(prec=5) - [ - 1 + 52416000*q^3 + 39007332000*q^4 + O(q^5), - q + 195660*q^3 + 12080128*q^4 + O(q^5), - q^2 - 48*q^3 + 1080*q^4 + O(q^5) - ] + [1 + 52416000*q^3 + 39007332000*q^4 + O(q^5), + q + 195660*q^3 + 12080128*q^4 + O(q^5), + q^2 - 48*q^3 + 1080*q^4 + O(q^5)] Test the alternative randomized algorithm:: diff --git a/src/sage/modular/modform/space.py b/src/sage/modular/modform/space.py index 202ea687953..4405c38f764 100644 --- a/src/sage/modular/modform/space.py +++ b/src/sage/modular/modform/space.py @@ -174,15 +174,11 @@ def prec(self, new_prec=None): sage: S.prec() 6 sage: S.basis() - [ - q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) - ] + [q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)] sage: S.prec(8) 8 sage: S.basis() - [ - q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + O(q^8) - ] + [q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + O(q^8)] """ return self.ambient().prec(new_prec) @@ -201,19 +197,14 @@ def set_precision(self, new_prec): sage: M.set_precision(10) sage: S = M.cuspidal_subspace() sage: S.basis() - [ - q + q^3 - 2*q^4 - q^7 - 2*q^9 + O(q^10), - q^2 + 2*q^3 - 2*q^4 + q^5 - 3*q^6 - 4*q^9 + O(q^10) - ] + [q + q^3 - 2*q^4 - q^7 - 2*q^9 + O(q^10), + q^2 + 2*q^3 - 2*q^4 + q^5 - 3*q^6 - 4*q^9 + O(q^10)] :: sage: S.set_precision(0) sage: S.basis() - [ - O(q^0), - O(q^0) - ] + [O(q^0), O(q^0)] The precision of subspaces is the same as the precision of the ambient space. @@ -222,11 +213,7 @@ def set_precision(self, new_prec): sage: S.set_precision(2) sage: M.basis() - [ - q + O(q^2), - O(q^2), - 1 + 2/3*q + O(q^2) - ] + [q + O(q^2), O(q^2), 1 + 2/3*q + O(q^2)] The precision must be nonnegative:: @@ -427,35 +414,27 @@ def echelon_form(self): sage: M = ModularForms(11) sage: M.basis() - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6), - 1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6), + 1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6)] sage: M.echelon_form().basis() - [ - 1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6), - q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6) - ] + [1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6), + q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)] :: sage: M = ModularForms(Gamma1(6),4) sage: M.basis() - [ - q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6), - 1 + O(q^6), - q - 8*q^4 + 126*q^5 + O(q^6), - q^2 + 9*q^4 + O(q^6), - q^3 + O(q^6) - ] + [q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6), + 1 + O(q^6), + q - 8*q^4 + 126*q^5 + O(q^6), + q^2 + 9*q^4 + O(q^6), + q^3 + O(q^6)] sage: M.echelon_form().basis() - [ - 1 + O(q^6), - q + 94*q^5 + O(q^6), - q^2 + 36*q^5 + O(q^6), - q^3 + O(q^6), - q^4 - 4*q^5 + O(q^6) - ] + [1 + O(q^6), + q + 94*q^5 + O(q^6), + q^2 + 36*q^5 + O(q^6), + q^3 + O(q^6), + q^4 - 4*q^5 + O(q^6)] We create a space with a funny basis then compute the corresponding echelon form. @@ -464,22 +443,16 @@ def echelon_form(self): sage: M = ModularForms(11,4) sage: M.basis() - [ - q + 3*q^3 - 6*q^4 - 7*q^5 + O(q^6), - q^2 - 4*q^3 + 2*q^4 + 8*q^5 + O(q^6), - 1 + O(q^6), - q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6) - ] + [q + 3*q^3 - 6*q^4 - 7*q^5 + O(q^6), + q^2 - 4*q^3 + 2*q^4 + 8*q^5 + O(q^6), + 1 + O(q^6), + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6)] sage: F = M.span_of_basis([M.0 + 1/3*M.1, M.2 + M.3]); F.basis() - [ - q + 1/3*q^2 + 5/3*q^3 - 16/3*q^4 - 13/3*q^5 + O(q^6), - 1 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6) - ] + [q + 1/3*q^2 + 5/3*q^3 - 16/3*q^4 - 13/3*q^5 + O(q^6), + 1 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6)] sage: E = F.echelon_form(); E.basis() - [ - 1 + 26/3*q^2 + 79/3*q^3 + 235/3*q^4 + 391/3*q^5 + O(q^6), - q + 1/3*q^2 + 5/3*q^3 - 16/3*q^4 - 13/3*q^5 + O(q^6) - ] + [1 + 26/3*q^2 + 79/3*q^3 + 235/3*q^4 + 391/3*q^5 + O(q^6), + q + 1/3*q^2 + 5/3*q^3 - 16/3*q^4 - 13/3*q^5 + O(q^6)] """ return self.span_of_basis(self.echelon_basis()) @@ -495,37 +468,28 @@ def echelon_basis(self): sage: M = ModularForms(Gamma0(11),4) sage: M.echelon_basis() - [ - 1 + O(q^6), - q - 9*q^4 - 10*q^5 + O(q^6), - q^2 + 6*q^4 + 12*q^5 + O(q^6), - q^3 + q^4 + q^5 + O(q^6) - ] + [1 + O(q^6), + q - 9*q^4 - 10*q^5 + O(q^6), + q^2 + 6*q^4 + 12*q^5 + O(q^6), + q^3 + q^4 + q^5 + O(q^6)] sage: M.cuspidal_subspace().echelon_basis() - [ - q + 3*q^3 - 6*q^4 - 7*q^5 + O(q^6), - q^2 - 4*q^3 + 2*q^4 + 8*q^5 + O(q^6) - ] + [q + 3*q^3 - 6*q^4 - 7*q^5 + O(q^6), q^2 - 4*q^3 + 2*q^4 + 8*q^5 + O(q^6)] :: sage: M = ModularForms(SL2Z, 12) sage: M.echelon_basis() - [ - 1 + 196560*q^2 + 16773120*q^3 + 398034000*q^4 + 4629381120*q^5 + O(q^6), - q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) - ] + [1 + 196560*q^2 + 16773120*q^3 + 398034000*q^4 + 4629381120*q^5 + O(q^6), + q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)] :: sage: M = CuspForms(Gamma0(17),4, prec=10) sage: M.echelon_basis() - [ - q + 2*q^5 - 8*q^7 - 8*q^8 + 7*q^9 + O(q^10), - q^2 - 3/2*q^5 - 7/2*q^6 + 9/2*q^7 + q^8 - 4*q^9 + O(q^10), - q^3 - 2*q^6 + q^7 - 4*q^8 - 2*q^9 + O(q^10), - q^4 - 1/2*q^5 - 5/2*q^6 + 3/2*q^7 + 2*q^9 + O(q^10) - ] + [q + 2*q^5 - 8*q^7 - 8*q^8 + 7*q^9 + O(q^10), + q^2 - 3/2*q^5 - 7/2*q^6 + 9/2*q^7 + q^8 - 4*q^9 + O(q^10), + q^3 - 2*q^6 + q^7 - 4*q^8 - 2*q^9 + O(q^10), + q^4 - 1/2*q^5 - 5/2*q^6 + 3/2*q^7 + 2*q^9 + O(q^10)] """ F = self.free_module() W = self._q_expansion_module() @@ -548,62 +512,52 @@ def integral_basis(self): sage: m = ModularForms(97,2,prec=10) sage: s = m.cuspidal_subspace() sage: s.integral_basis() - [ - q + 2*q^7 + 4*q^8 - 2*q^9 + O(q^10), - q^2 + q^4 + q^7 + 3*q^8 - 3*q^9 + O(q^10), - q^3 + q^4 - 3*q^8 + q^9 + O(q^10), - 2*q^4 - 2*q^8 + O(q^10), - q^5 - 2*q^8 + 2*q^9 + O(q^10), - q^6 + 2*q^7 + 5*q^8 - 5*q^9 + O(q^10), - 3*q^7 + 6*q^8 - 4*q^9 + O(q^10) - ] + [q + 2*q^7 + 4*q^8 - 2*q^9 + O(q^10), + q^2 + q^4 + q^7 + 3*q^8 - 3*q^9 + O(q^10), + q^3 + q^4 - 3*q^8 + q^9 + O(q^10), + 2*q^4 - 2*q^8 + O(q^10), + q^5 - 2*q^8 + 2*q^9 + O(q^10), + q^6 + 2*q^7 + 5*q^8 - 5*q^9 + O(q^10), + 3*q^7 + 6*q^8 - 4*q^9 + O(q^10)] sage: s.echelon_basis() - [ - q + 2/3*q^9 + O(q^10), - q^2 + 2*q^8 - 5/3*q^9 + O(q^10), - q^3 - 2*q^8 + q^9 + O(q^10), - q^4 - q^8 + O(q^10), - q^5 - 2*q^8 + 2*q^9 + O(q^10), - q^6 + q^8 - 7/3*q^9 + O(q^10), - q^7 + 2*q^8 - 4/3*q^9 + O(q^10) - ] + [q + 2/3*q^9 + O(q^10), + q^2 + 2*q^8 - 5/3*q^9 + O(q^10), + q^3 - 2*q^8 + q^9 + O(q^10), + q^4 - q^8 + O(q^10), + q^5 - 2*q^8 + 2*q^9 + O(q^10), + q^6 + q^8 - 7/3*q^9 + O(q^10), + q^7 + 2*q^8 - 4/3*q^9 + O(q^10)] Here's another example where there is a big gap in the valuations:: sage: m = CuspForms(64,2) sage: m.integral_basis() - [ - q + O(q^6), - q^2 + O(q^6), - q^5 + O(q^6) - ] + [q + O(q^6), q^2 + O(q^6), q^5 + O(q^6)] TESTS:: sage: m = CuspForms(11*2^4,2, prec=13); m Cuspidal subspace of dimension 19 of Modular Forms space of dimension 30 for Congruence Subgroup Gamma0(176) of weight 2 over Rational Field sage: m.integral_basis() # takes a long time (3 or 4 seconds) - [ - q + O(q^13), - q^2 + O(q^13), - q^3 + O(q^13), - q^4 + O(q^13), - q^5 + O(q^13), - q^6 + O(q^13), - q^7 + O(q^13), - q^8 + O(q^13), - q^9 + O(q^13), - q^10 + O(q^13), - q^11 + O(q^13), - q^12 + O(q^13), - O(q^13), - O(q^13), - O(q^13), - O(q^13), - O(q^13), - O(q^13), - O(q^13) - ] + [q + O(q^13), + q^2 + O(q^13), + q^3 + O(q^13), + q^4 + O(q^13), + q^5 + O(q^13), + q^6 + O(q^13), + q^7 + O(q^13), + q^8 + O(q^13), + q^9 + O(q^13), + q^10 + O(q^13), + q^11 + O(q^13), + q^12 + O(q^13), + O(q^13), + O(q^13), + O(q^13), + O(q^13), + O(q^13), + O(q^13), + O(q^13)] """ W = self._q_expansion_module() pr = W.degree() @@ -658,35 +612,27 @@ def q_expansion_basis(self, prec=None): sage: S = ModularForms(11,2).cuspidal_submodule() sage: S.q_expansion_basis() - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)] sage: S.q_expansion_basis(5) - [ - q - 2*q^2 - q^3 + 2*q^4 + O(q^5) - ] + [q - 2*q^2 - q^3 + 2*q^4 + O(q^5)] sage: S = ModularForms(1,24).cuspidal_submodule() sage: S.q_expansion_basis(8) - [ - q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 - 982499328*q^6 - 147247240*q^7 + O(q^8), - q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + 143820*q^6 - 985824*q^7 + O(q^8) - ] + [q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 - 982499328*q^6 - 147247240*q^7 + O(q^8), + q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + 143820*q^6 - 985824*q^7 + O(q^8)] An example which used to be buggy:: sage: M = CuspForms(128, 2, prec=3) sage: M.q_expansion_basis() - [ - q - q^17 + O(q^22), - q^2 - 3*q^18 + O(q^22), - q^3 - q^11 + q^19 + O(q^22), - q^4 - 2*q^20 + O(q^22), - q^5 - 3*q^21 + O(q^22), - q^7 - q^15 + O(q^22), - q^9 - q^17 + O(q^22), - q^10 + O(q^22), - q^13 - q^21 + O(q^22) - ] + [q - q^17 + O(q^22), + q^2 - 3*q^18 + O(q^22), + q^3 - q^11 + q^19 + O(q^22), + q^4 - 2*q^20 + O(q^22), + q^5 - 3*q^21 + O(q^22), + q^7 - q^15 + O(q^22), + q^9 - q^17 + O(q^22), + q^10 + O(q^22), + q^13 - q^21 + O(q^22)] """ if prec is None: try: # don't care about precision -- just must be big enough to determine forms @@ -755,18 +701,14 @@ def q_echelon_basis(self, prec=None): sage: M = ModularForms(11,2) sage: M.q_expansion_basis() - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6), - 1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6), + 1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6)] :: sage: M.q_echelon_basis() - [ - 1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6), - q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6) - ] + [1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6), + q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)] """ prec = self.__normalize_prec(prec) if prec == 0: @@ -810,9 +752,7 @@ def q_integral_basis(self, prec=None): sage: S = CuspForms(11,2) sage: S.q_integral_basis(5) - [ - q - 2*q^2 - q^3 + 2*q^4 + O(q^5) - ] + [q - 2*q^2 - q^3 + 2*q^4 + O(q^5)] """ if not self.base_ring() == QQ: raise TypeError("the base ring must be Q") @@ -883,11 +823,9 @@ def _q_expansion(self, element, prec): sage: m = ModularForms(Gamma0(23),2); m Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(23) of weight 2 over Rational Field sage: m.basis() - [ - q - q^3 - q^4 + O(q^6), - q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6), - 1 + 12/11*q + 36/11*q^2 + 48/11*q^3 + 84/11*q^4 + 72/11*q^5 + O(q^6) - ] + [q - q^3 - q^4 + O(q^6), + q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6), + 1 + 12/11*q + 36/11*q^2 + 48/11*q^3 + 84/11*q^4 + 72/11*q^5 + O(q^6)] sage: m._q_expansion([1,2,0], 5) q + 2*q^2 - 5*q^3 - 3*q^4 + O(q^5) """ @@ -1377,10 +1315,8 @@ def basis(self): sage: MM = ModularForms(11,2) sage: MM.basis() - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6), - 1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6), + 1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6)] """ return Sequence([self.element_class(self, x) for x in self.free_module().basis()], @@ -1394,13 +1330,11 @@ def gen(self, n): sage: N = ModularForms(6,4) sage: N.basis() - [ - q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6), - 1 + O(q^6), - q - 8*q^4 + 126*q^5 + O(q^6), - q^2 + 9*q^4 + O(q^6), - q^3 + O(q^6) - ] + [q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6), + 1 + O(q^6), + q - 8*q^4 + 126*q^5 + O(q^6), + q^2 + 9*q^4 + O(q^6), + q^3 + O(q^6)] :: @@ -1432,13 +1366,11 @@ def gens(self): sage: N = ModularForms(6,4) sage: N.gens() - [ - q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6), - 1 + O(q^6), - q - 8*q^4 + 126*q^5 + O(q^6), - q^2 + 9*q^4 + O(q^6), - q^3 + O(q^6) - ] + [q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6), + 1 + O(q^6), + q - 8*q^4 + 126*q^5 + O(q^6), + q^2 + 9*q^4 + O(q^6), + q^3 + O(q^6)] """ return self.basis() diff --git a/src/sage/modular/modform/vm_basis.py b/src/sage/modular/modform/vm_basis.py index 58f36fd0f1a..737da840eea 100644 --- a/src/sage/modular/modform/vm_basis.py +++ b/src/sage/modular/modform/vm_basis.py @@ -68,52 +68,34 @@ def victor_miller_basis(k, prec=10, cusp_only=False, var='q'): sage: victor_miller_basis(1, 6) [] sage: victor_miller_basis(0, 6) - [ - 1 + O(q^6) - ] + [1 + O(q^6)] sage: victor_miller_basis(2, 6) [] sage: victor_miller_basis(4, 6) - [ - 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) - ] + [1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6)] sage: victor_miller_basis(6, 6, var='w') - [ - 1 - 504*w - 16632*w^2 - 122976*w^3 - 532728*w^4 - 1575504*w^5 + O(w^6) - ] + [1 - 504*w - 16632*w^2 - 122976*w^3 - 532728*w^4 - 1575504*w^5 + O(w^6)] sage: victor_miller_basis(6, 6) - [ - 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6) - ] + [1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)] sage: victor_miller_basis(12, 6) - [ - 1 + 196560*q^2 + 16773120*q^3 + 398034000*q^4 + 4629381120*q^5 + O(q^6), - q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) - ] + [1 + 196560*q^2 + 16773120*q^3 + 398034000*q^4 + 4629381120*q^5 + O(q^6), + q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)] sage: victor_miller_basis(12, 6, cusp_only=True) - [ - q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) - ] + [q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)] sage: victor_miller_basis(24, 6, cusp_only=True) - [ - q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 + O(q^6), - q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + O(q^6) - ] + [q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 + O(q^6), + q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + O(q^6)] sage: victor_miller_basis(24, 6) - [ - 1 + 52416000*q^3 + 39007332000*q^4 + 6609020221440*q^5 + O(q^6), - q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 + O(q^6), - q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + O(q^6) - ] + [1 + 52416000*q^3 + 39007332000*q^4 + 6609020221440*q^5 + O(q^6), + q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 + O(q^6), + q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + O(q^6)] sage: victor_miller_basis(32, 6) - [ - 1 + 2611200*q^3 + 19524758400*q^4 + 19715347537920*q^5 + O(q^6), - q + 50220*q^3 + 87866368*q^4 + 18647219790*q^5 + O(q^6), - q^2 + 432*q^3 + 39960*q^4 - 1418560*q^5 + O(q^6) - ] + [1 + 2611200*q^3 + 19524758400*q^4 + 19715347537920*q^5 + O(q^6), + q + 50220*q^3 + 87866368*q^4 + 18647219790*q^5 + O(q^6), + q^2 + 432*q^3 + 39960*q^4 - 1418560*q^5 + O(q^6)] sage: victor_miller_basis(40,200)[1:] == victor_miller_basis(40,200,cusp_only=True) True diff --git a/src/sage/modular/modsym/modsym.py b/src/sage/modular/modsym/modsym.py index fb46d0edafa..d823e1b1cf9 100644 --- a/src/sage/modular/modsym/modsym.py +++ b/src/sage/modular/modsym/modsym.py @@ -24,12 +24,8 @@ sage: M.T(2).charpoly('x').factor() (x - 3) * (x^2 + x - 1)^2 sage: M.decomposition(2) - [ - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5 - for Gamma_0(23) of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 5 - for Gamma_0(23) of weight 2 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Rational Field] :: @@ -38,17 +34,9 @@ sage: M.T(2).charpoly('x').factor() (x - 3) * (x - 1/2*sqrt5 + 1/2)^2 * (x + 1/2*sqrt5 + 1/2)^2 sage: M.decomposition(2) - [ - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5 - for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5 - with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?, - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 - for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5 - with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?, - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 - for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5 - with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? - ] + [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?, + Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?] We compute some Hecke operators and do a consistency check:: @@ -263,14 +251,8 @@ def ModularSymbols(group=1, sage: G = GammaH(15,[4,13]) sage: M = ModularSymbols(G,2) sage: M.decomposition() - [ - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 - for Congruence Subgroup Gamma_H(15) with H generated by [4, 7] - of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 5 - for Congruence Subgroup Gamma_H(15) with H generated by [4, 7] - of weight 2 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Congruence Subgroup Gamma_H(15) with H generated by [4, 7] of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 5 for Congruence Subgroup Gamma_H(15) with H generated by [4, 7] of weight 2 with sign 0 over Rational Field] We create a space with character:: diff --git a/src/sage/modular/modsym/space.py b/src/sage/modular/modsym/space.py index a77d9279a6b..38ca3d684a4 100644 --- a/src/sage/modular/modsym/space.py +++ b/src/sage/modular/modsym/space.py @@ -451,10 +451,8 @@ def is_simple(self): False sage: o = m.old_subspace() sage: o.decomposition() - [ - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field, - Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field - ] + [Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field, + Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field] sage: C = ModularSymbols(1,14,0,GF(5)).cuspidal_submodule(); C Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 2 for Gamma_0(1) of weight 14 with sign 0 over Finite Field of size 5 sage: C.is_simple() @@ -545,9 +543,7 @@ def default_prec(self): sage: M = ModularSymbols(15) sage: M.cuspidal_submodule().q_expansion_basis() - [ - q - q^2 - q^3 - q^4 + q^5 + q^6 + O(q^8) - ] + [q - q^2 - q^3 - q^4 + q^5 + q^6 + O(q^8)] sage: M.set_default_prec(20) Notice that setting the default precision of the ambient space @@ -556,9 +552,7 @@ def default_prec(self): :: sage: M.cuspidal_submodule().q_expansion_basis() - [ - q - q^2 - q^3 - q^4 + q^5 + q^6 + 3*q^8 + q^9 - q^10 - 4*q^11 + q^12 - 2*q^13 - q^15 - q^16 + 2*q^17 - q^18 + 4*q^19 + O(q^20) - ] + [q - q^2 - q^3 - q^4 + q^5 + q^6 + 3*q^8 + q^9 - q^10 - 4*q^11 + q^12 - 2*q^13 - q^15 - q^16 + 2*q^17 - q^18 + 4*q^19 + O(q^20)] sage: M.cuspidal_submodule().default_prec() 20 """ @@ -581,10 +575,7 @@ def set_default_prec(self, prec): sage: M = ModularSymbols(Gamma1(13),2) sage: M.set_default_prec(5) sage: M.cuspidal_submodule().q_expansion_basis() - [ - q - 4*q^3 - q^4 + O(q^5), - q^2 - 2*q^3 - q^4 + O(q^5) - ] + [q - 4*q^3 - q^4 + O(q^5), q^2 - 2*q^3 - q^4 + O(q^5)] """ if not self.is_ambient(): return self.ambient_hecke_module().set_default_prec(prec) @@ -599,14 +590,10 @@ def set_precision(self, prec): sage: M = ModularSymbols(17,2) sage: M.cuspidal_submodule().q_expansion_basis() - [ - q - q^2 - q^4 - 2*q^5 + 4*q^7 + O(q^8) - ] + [q - q^2 - q^4 - 2*q^5 + 4*q^7 + O(q^8)] sage: M.set_precision(10) sage: M.cuspidal_submodule().q_expansion_basis() - [ - q - q^2 - q^4 - 2*q^5 + 4*q^7 + 3*q^8 - 3*q^9 + O(q^10) - ] + [q - q^2 - q^4 - 2*q^5 + 4*q^7 + 3*q^8 - 3*q^9 + O(q^10)] """ self.set_default_prec(prec) @@ -646,42 +633,32 @@ def q_expansion_basis(self, prec=None, algorithm='default'): sage: M = ModularSymbols(1, 12).cuspidal_submodule() sage: M.q_expansion_basis(8) - [ - q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + O(q^8) - ] + [q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + O(q^8)] :: sage: M.q_expansion_basis(8, algorithm='eigen') - [ - q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + O(q^8) - ] + [q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + O(q^8)] :: sage: M = ModularSymbols(1, 24).cuspidal_submodule() sage: M.q_expansion_basis(8, algorithm='eigen') - [ - q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 - 982499328*q^6 - 147247240*q^7 + O(q^8), - q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + 143820*q^6 - 985824*q^7 + O(q^8) - ] + [q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 - 982499328*q^6 - 147247240*q^7 + O(q^8), + q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + 143820*q^6 - 985824*q^7 + O(q^8)] :: sage: M = ModularSymbols(11, 2, sign=-1).cuspidal_submodule() sage: M.q_expansion_basis(8, algorithm='eigen') - [ - q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 + O(q^8) - ] + [q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 + O(q^8)] :: sage: M = ModularSymbols(Gamma1(13), 2, sign=1).cuspidal_submodule() sage: M.q_expansion_basis(8, algorithm='eigen') - [ - q - 4*q^3 - q^4 + 3*q^5 + 6*q^6 + O(q^8), - q^2 - 2*q^3 - q^4 + 2*q^5 + 2*q^6 + O(q^8) - ] + [q - 4*q^3 - q^4 + 3*q^5 + 6*q^6 + O(q^8), + q^2 - 2*q^3 - q^4 + 2*q^5 + 2*q^6 + O(q^8)] :: @@ -693,9 +670,7 @@ def q_expansion_basis(self, prec=None, algorithm='default'): sage: M = ModularSymbols(Gamma1(7), 3, sign=-1).cuspidal_submodule() sage: M.q_expansion_basis(8) - [ - q - 3*q^2 + 5*q^4 - 7*q^7 + O(q^8) - ] + [q - 3*q^2 + 5*q^4 - 7*q^7 + O(q^8)] :: @@ -703,16 +678,11 @@ def q_expansion_basis(self, prec=None, algorithm='default'): sage: M[0] Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 7 for Gamma_0(43) of weight 2 with sign 0 over Rational Field sage: M[0].q_expansion_basis() - [ - q - 2*q^2 - 2*q^3 + 2*q^4 - 4*q^5 + 4*q^6 + O(q^8) - ] + [q - 2*q^2 - 2*q^3 + 2*q^4 - 4*q^5 + 4*q^6 + O(q^8)] sage: M[1] Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 7 for Gamma_0(43) of weight 2 with sign 0 over Rational Field sage: M[1].q_expansion_basis() - [ - q + 2*q^5 - 2*q^6 - 2*q^7 + O(q^8), - q^2 - q^3 - q^5 + q^7 + O(q^8) - ] + [q + 2*q^5 - 2*q^6 - 2*q^7 + O(q^8), q^2 - q^3 - q^5 + q^7 + O(q^8)] """ if prec is None: prec = self.default_prec() @@ -851,10 +821,8 @@ def q_expansion_module(self, prec=None, R=None): sage: k. = NumberField(x^2-5) sage: M = ModularSymbols(23, base_ring=k, sign=1).cuspidal_submodule() sage: D = M.decomposition(); D - [ - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(23) of weight 2 with sign 1 over Number Field in a with defining polynomial x^2 - 5, - Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(23) of weight 2 with sign 1 over Number Field in a with defining polynomial x^2 - 5 - ] + [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(23) of weight 2 with sign 1 over Number Field in a with defining polynomial x^2 - 5, + Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(23) of weight 2 with sign 1 over Number Field in a with defining polynomial x^2 - 5] sage: M.q_expansion_module(8, QQ) Vector space of degree 8 and dimension 2 over Rational Field Basis matrix: @@ -870,9 +838,7 @@ def q_expansion_module(self, prec=None, R=None): sage: M = ModularSymbols(eps,2,sign=1).cuspidal_submodule(); M Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 and level 25, weight 2, character [zeta10], sign 1, over Cyclotomic Field of order 10 and degree 4 sage: D = M.decomposition(); D - [ - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 and level 25, weight 2, character [zeta10], sign 1, over Cyclotomic Field of order 10 and degree 4 - ] + [Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 and level 25, weight 2, character [zeta10], sign 1, over Cyclotomic Field of order 10 and degree 4] sage: D[0].q_eigenform(4, 'mu') q + mu*q^2 + ((zeta10^3 + zeta10 - 1)*mu + zeta10^2 - 1)*q^3 + O(q^4) sage: D[0].q_expansion_module(11, QQ) @@ -1545,10 +1511,8 @@ def star_decomposition(self): EXAMPLES:: sage: ModularSymbols(Gamma1(19), 2).cuspidal_submodule().star_decomposition() - [ - Modular Symbols subspace of dimension 7 of Modular Symbols space of dimension 31 for Gamma_1(19) of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 7 of Modular Symbols space of dimension 31 for Gamma_1(19) of weight 2 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 7 of Modular Symbols space of dimension 31 for Gamma_1(19) of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 7 of Modular Symbols space of dimension 31 for Gamma_1(19) of weight 2 with sign 0 over Rational Field] """ S = self.star_involution() return S.decomposition() diff --git a/src/sage/modular/quatalg/brandt.py b/src/sage/modular/quatalg/brandt.py index e91e6950e76..d818e0f8799 100644 --- a/src/sage/modular/quatalg/brandt.py +++ b/src/sage/modular/quatalg/brandt.py @@ -169,11 +169,9 @@ Brandt module of dimension 4 of level 43 of weight 2 over Integer Ring sage: D = B.decomposition() sage: D - [ - Subspace of dimension 1 of Brandt module of dimension 4 of level 43 of weight 2 over Integer Ring, - Subspace of dimension 1 of Brandt module of dimension 4 of level 43 of weight 2 over Integer Ring, - Subspace of dimension 2 of Brandt module of dimension 4 of level 43 of weight 2 over Integer Ring - ] + [Subspace of dimension 1 of Brandt module of dimension 4 of level 43 of weight 2 over Integer Ring, + Subspace of dimension 1 of Brandt module of dimension 4 of level 43 of weight 2 over Integer Ring, + Subspace of dimension 2 of Brandt module of dimension 4 of level 43 of weight 2 over Integer Ring] sage: D[0].basis() ((0, 0, 1, -1),) sage: D[1].basis() diff --git a/src/sage/modular/ssmod/ssmod.py b/src/sage/modular/ssmod/ssmod.py index 9913e554a02..9422f33ca2e 100644 --- a/src/sage/modular/ssmod/ssmod.py +++ b/src/sage/modular/ssmod/ssmod.py @@ -11,17 +11,18 @@ sage: a = m.change_ring(GF(97)) sage: D = a.decomposition() sage: D[:3] - [ - (Vector space of degree 33 and dimension 1 over Finite Field of size 97 - Basis matrix: - [ 0 0 0 1 96 96 1 0 95 1 1 1 1 95 2 96 0 0 96 0 96 0 96 2 96 96 0 1 0 2 1 95 0], True), - (Vector space of degree 33 and dimension 1 over Finite Field of size 97 - Basis matrix: - [ 0 1 96 16 75 22 81 0 0 17 17 80 80 0 0 74 40 1 16 57 23 96 81 0 74 23 0 24 0 0 73 0 0], True), - (Vector space of degree 33 and dimension 1 over Finite Field of size 97 - Basis matrix: - [ 0 1 96 90 90 7 7 0 0 91 6 6 91 0 0 91 0 13 7 0 6 84 90 0 6 91 0 90 0 0 7 0 0], True) - ] + [(Vector space of degree 33 and dimension 1 over Finite Field of size 97 + Basis matrix: + [ 0 0 0 1 96 96 1 0 95 1 1 1 1 95 2 96 0 0 96 0 96 0 96 2 96 96 0 1 0 2 1 95 0], + True), + (Vector space of degree 33 and dimension 1 over Finite Field of size 97 + Basis matrix: + [ 0 1 96 16 75 22 81 0 0 17 17 80 80 0 0 74 40 1 16 57 23 96 81 0 74 23 0 24 0 0 73 0 0], + True), + (Vector space of degree 33 and dimension 1 over Finite Field of size 97 + Basis matrix: + [ 0 1 96 90 90 7 7 0 0 91 6 6 91 0 0 91 0 13 7 0 6 84 90 0 6 91 0 90 0 0 7 0 0], + True)] sage: len(D) 9 diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 097db985ede..471db14112b 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -589,11 +589,7 @@ def VectorSpace(K, dimension_or_basis_keys=None, sparse=False, inner_product_mat sage: V Vector space of dimension 3 over Fraction Field of Univariate Polynomial Ring in x over Integer Ring sage: V.basis() - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] The base must be a field or a :exc:`TypeError` is raised. @@ -824,10 +820,7 @@ def basis_seq(V, vecs): ... ValueError: vector is immutable; please change a copy instead (use copy()) sage: sage.modules.free_module.basis_seq(V, V.gens()) - [ - (1, 0), - (0, 1) - ] + [(1, 0), (0, 1)] """ for z in vecs: z.set_immutable() @@ -897,10 +890,7 @@ class Module_free_ambient(Module): sage: M = S**2 sage: N = M.submodule([vector([x - y, z]), vector([y * z, x * z])]) sage: N.gens() - [ - (x - y, z), - (y*z, x*z) - ] + [(x - y, z), (y*z, x*z)] sage: N.degree() 2 """ @@ -2567,11 +2557,7 @@ def basis(self): EXAMPLES:: sage: FreeModule(Integers(12),3).basis() - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] """ raise NotImplementedError @@ -5011,9 +4997,7 @@ def linear_dependence(self, vectors, zeros='left', check=True): sage: v2 = vector(QQ, [1, 5, 2, -2]) sage: V = QQ^4 sage: V.linear_dependence([v1,v2]) - [ - - ] + [] sage: v3 = v1 + v2 sage: v4 = 3*v1 - 4*v2 @@ -5022,21 +5006,13 @@ def linear_dependence(self, vectors, zeros='left', check=True): sage: relations = V.linear_dependence(L, zeros='left') sage: relations - [ - (1, 0, 0, -1, -2), - (0, 1, 0, -1/2, -3/2), - (0, 0, 1, -3/2, -7/2) - ] + [(1, 0, 0, -1, -2), (0, 1, 0, -1/2, -3/2), (0, 0, 1, -3/2, -7/2)] sage: v2 + (-1/2)*v4 + (-3/2)*v5 (0, 0, 0, 0) sage: relations = V.linear_dependence(L, zeros='right') sage: relations - [ - (-1, -1, 1, 0, 0), - (-3, 4, 0, 1, 0), - (1, -2, 0, 0, 1) - ] + [(-1, -1, 1, 0, 0), (-3, 4, 0, 1, 0), (1, -2, 0, 0, 1)] sage: z = sum([relations[2][i]*L[i] for i in range(len(L))]) sage: z == zero_vector(QQ, 4) True @@ -5048,9 +5024,7 @@ def linear_dependence(self, vectors, zeros='left', check=True): sage: v2 = vector(QQ, [4,1,0]) sage: V = QQ^3 sage: relations = V.linear_dependence([v1, v2]); relations - [ - - ] + [] sage: relations == [] True @@ -5066,19 +5040,13 @@ def linear_dependence(self, vectors, zeros='left', check=True): True sage: L = [v1, v2, v3, 2*v1+v2, 3*v2+6*v3] sage: (F^5).linear_dependence(L) - [ - (1, 0, 16, 8, 3), - (0, 1, 2, 0, 11) - ] + [(1, 0, 16, 8, 3), (0, 1, 2, 0, 11)] sage: v1 + 16*v3 + 8*(2*v1+v2) + 3*(3*v2+6*v3) (0, 0, 0, 0, 0) sage: v2 + 2*v3 + 11*(3*v2+6*v3) (0, 0, 0, 0, 0) sage: (F^5).linear_dependence(L, zeros='right') - [ - (15, 16, 0, 1, 0), - (0, 14, 11, 0, 1) - ] + [(15, 16, 0, 1, 0), (0, 14, 11, 0, 1)] TESTS: @@ -5728,11 +5696,7 @@ def basis(self): EXAMPLES:: sage: A = ZZ^3; B = A.basis(); B - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] sage: B.universe() Ambient free module of rank 3 over the principal ideal domain Integer Ring """ @@ -5756,11 +5720,7 @@ def echelonized_basis(self): EXAMPLES:: sage: A = ZZ^3; A.echelonized_basis() - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] """ return self.basis() @@ -7049,10 +7009,7 @@ def echelon_coordinates(self, v, check=True): sage: M.echelon_coordinates([8,10,12]) [8, -2] sage: B = M.echelonized_basis(); B - [ - (1, 2, 3/7), - (0, 3, -30/7) - ] + [(1, 2, 3/7), (0, 3, -30/7)] sage: 8*B[0] - 2*B[1] (8, 10, 12) @@ -7061,10 +7018,7 @@ def echelon_coordinates(self, v, check=True): sage: V = VectorSpace(QQ,5, sparse=True) sage: W = V.subspace_with_basis([[0,1,2,0,0], [0,-1,0,0,-1/2]]) sage: W.echelonized_basis() - [ - (0, 1, 0, 0, 1/2), - (0, 0, 1, 0, -1/4) - ] + [(0, 1, 0, 0, 1/2), (0, 0, 1, 0, -1/4)] sage: W.echelon_coordinates([0,0,2,0,-1/2]) [0, 2] """ @@ -7100,10 +7054,7 @@ def user_to_echelon_matrix(self): sage: A = ZZ^3 sage: M = A.span_of_basis([[1,2,3],[4,5,6]]) sage: M.echelonized_basis() - [ - (1, 2, 3), - (0, 3, 6) - ] + [(1, 2, 3), (0, 3, 6)] sage: M.user_to_echelon_matrix() [ 1 0] [ 4 -1] @@ -7149,10 +7100,7 @@ def echelon_to_user_matrix(self): sage: V = QQ^3 sage: W = V.span_of_basis([[1,2,3],[4,5,6]]) sage: W.echelonized_basis() - [ - (1, 0, -1), - (0, 1, 2) - ] + [(1, 0, -1), (0, 1, 2)] sage: A = W.echelon_to_user_matrix(); A [-5/3 2/3] [ 4/3 -1/3] @@ -7388,16 +7336,10 @@ def basis(self): sage: V = ZZ^3 sage: V.basis() - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] sage: M = V.span_of_basis([['1/8',2,1]]) sage: M.basis() - [ - (1/8, 2, 1) - ] + [(1/8, 2, 1)] """ return self.__basis @@ -7506,15 +7448,9 @@ def echelonized_basis(self): sage: V = ZZ^3 sage: M = V.span_of_basis([['1/2',3,1], [0,'1/6',0]]) sage: M.basis() - [ - (1/2, 3, 1), - (0, 1/6, 0) - ] + [(1/2, 3, 1), (0, 1/6, 0)] sage: B = M.echelonized_basis(); B - [ - (1/2, 0, 1), - (0, 1/6, 0) - ] + [(1/2, 0, 1), (0, 1/6, 0)] sage: V.span(B) == M True """ @@ -7545,10 +7481,7 @@ def echelon_coordinate_vector(self, v, check=True): sage: V = ZZ^3 sage: M = V.span_of_basis([['1/2',3,1], [0,'1/6',0]]) sage: B = M.echelonized_basis(); B - [ - (1/2, 0, 1), - (0, 1/6, 0) - ] + [(1/2, 0, 1), (0, 1/6, 0)] sage: M.echelon_coordinate_vector(['1/2', 3, 1]) (1, 18) """ diff --git a/src/sage/modules/free_module_morphism.py b/src/sage/modules/free_module_morphism.py index efdbc607c09..b08d78e563b 100644 --- a/src/sage/modules/free_module_morphism.py +++ b/src/sage/modules/free_module_morphism.py @@ -542,27 +542,25 @@ def eigenvectors(self, extend=True): sage: V = (QQ^4).subspace([[0,2,1,4], [1,2,5,0], [1,1,1,1]]) sage: H = (V.Hom(V))(matrix(QQ, [[0,1,0], [-1,0,0], [0,0,3]])) sage: H.eigenvectors() - [(3, [ (0, 0, 1, -6/7) ], 1), - (-1*I, [ (1, 1*I, 0, -0.571428571428572? + 2.428571428571429?*I) ], 1), - (1*I, [ (1, -1*I, 0, -0.571428571428572? - 2.428571428571429?*I) ], 1)] + [(3, [(0, 0, 1, -6/7)], 1), + (-1*I, [(1, 1*I, 0, -0.571428571428572? + 2.428571428571429?*I)], 1), + (1*I, [(1, -1*I, 0, -0.571428571428572? - 2.428571428571429?*I)], 1)] sage: H.eigenvectors(extend=False) - [(3, [ (0, 0, 1, -6/7) ], 1)] + [(3, [(0, 0, 1, -6/7)], 1)] sage: H1 = (V.Hom(V))(matrix(QQ, [[2,1,0],[0,2,0],[0,0,3]])) sage: H1.eigenvectors() - [(3, [ (0, 0, 1, -6/7) ], 1), - (2, [ (0, 1, 0, 17/7) ], 2)] + [(3, [(0, 0, 1, -6/7)], 1), (2, [(0, 1, 0, 17/7)], 2)] sage: H1.eigenvectors(extend=False) - [(3, [ (0, 0, 1, -6/7) ], 1), - (2, [ (0, 1, 0, 17/7) ], 2)] + [(3, [(0, 0, 1, -6/7)], 1), (2, [(0, 1, 0, 17/7)], 2)] :: sage: V = QQ^2 sage: m = matrix(2, [1, 1, 0, 1]) sage: V.hom(m, side='right').eigenvectors() # needs sage.rings.number_field - [(1, [ (1, 0) ], 2)] + [(1, [(1, 0)], 2)] sage: V.hom(m).eigenvectors() # needs sage.rings.number_field - [(1, [ (0, 1) ], 2)] + [(1, [(0, 1)], 2)] """ if self.base_ring().is_field(): if self.is_endomorphism(): diff --git a/src/sage/modules/free_quadratic_module.py b/src/sage/modules/free_quadratic_module.py index 553f4b0931d..8e583284823 100644 --- a/src/sage/modules/free_quadratic_module.py +++ b/src/sage/modules/free_quadratic_module.py @@ -204,11 +204,7 @@ def QuadraticSpace(K, dimension, inner_product_matrix, sparse=False): [ 0 x - 1 0] [ 0 0 x + 1] sage: V.basis() - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] The base must be a field or a :exc:`TypeError` is raised:: diff --git a/src/sage/modules/matrix_morphism.py b/src/sage/modules/matrix_morphism.py index 175d152f364..f5a067e27ab 100644 --- a/src/sage/modules/matrix_morphism.py +++ b/src/sage/modules/matrix_morphism.py @@ -828,24 +828,20 @@ def decomposition(self, *args, **kwds): sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1]) sage: phi.decomposition() # needs sage.libs.pari - [ - Free module of degree 2 and rank 1 over Integer Ring - Echelon basis matrix: - [0 1], - Free module of degree 2 and rank 1 over Integer Ring - Echelon basis matrix: - [ 1 -1] - ] + [Free module of degree 2 and rank 1 over Integer Ring + Echelon basis matrix: + [0 1], + Free module of degree 2 and rank 1 over Integer Ring + Echelon basis matrix: + [ 1 -1]] sage: phi2 = V.hom(phi.matrix(), side='right') sage: phi2.decomposition() # needs sage.libs.pari - [ - Free module of degree 2 and rank 1 over Integer Ring - Echelon basis matrix: - [1 1], - Free module of degree 2 and rank 1 over Integer Ring - Echelon basis matrix: - [1 0] - ] + [Free module of degree 2 and rank 1 over Integer Ring + Echelon basis matrix: + [1 1], + Free module of degree 2 and rank 1 over Integer Ring + Echelon basis matrix: + [1 0]] """ if not self.is_endomorphism(): raise ArithmeticError("matrix morphism must be an endomorphism") diff --git a/src/sage/modules/submodule.py b/src/sage/modules/submodule.py index 12ad915646a..be2868c3dca 100644 --- a/src/sage/modules/submodule.py +++ b/src/sage/modules/submodule.py @@ -214,10 +214,7 @@ def gens(self) -> list: sage: M = S**2 sage: N = M.submodule([vector([x - y, z]), vector([y * z, x * z])]) sage: N.gens() - [ - (x - y, z), - (y*z, x*z) - ] + [(x - y, z), (y*z, x*z)] """ return self.__gens diff --git a/src/sage/rings/finite_rings/homset.py b/src/sage/rings/finite_rings/homset.py index 617f9da0086..cee7867fe0b 100644 --- a/src/sage/rings/finite_rings/homset.py +++ b/src/sage/rings/finite_rings/homset.py @@ -236,33 +236,27 @@ def list(self): sage: k1 = GF(1009) sage: k2 = GF(1009, modulus='primitive') sage: Hom(k1, k2).list() - [ - Ring morphism: - From: Finite Field of size 1009 - To: Finite Field of size 1009 - Defn: 1 |--> 1 - ] + [Ring morphism: + From: Finite Field of size 1009 + To: Finite Field of size 1009 + Defn: 1 |--> 1] sage: Hom(k2, k1).list() - [ - Ring morphism: - From: Finite Field of size 1009 - To: Finite Field of size 1009 - Defn: 11 |--> 11 - ] + [Ring morphism: + From: Finite Field of size 1009 + To: Finite Field of size 1009 + Defn: 11 |--> 11] sage: k1. = GF(1009^2, modulus='first_lexicographic') sage: k2. = GF(1009^2, modulus='conway') sage: Hom(k1, k2).list() - [ - Ring morphism: - From: Finite Field in a of size 1009^2 - To: Finite Field in b of size 1009^2 - Defn: a |--> 290*b + 864, - Ring morphism: - From: Finite Field in a of size 1009^2 - To: Finite Field in b of size 1009^2 - Defn: a |--> 719*b + 145 - ] + [Ring morphism: + From: Finite Field in a of size 1009^2 + To: Finite Field in b of size 1009^2 + Defn: a |--> 290*b + 864, + Ring morphism: + From: Finite Field in a of size 1009^2 + To: Finite Field in b of size 1009^2 + Defn: a |--> 719*b + 145] TESTS: @@ -303,16 +297,14 @@ def __getitem__(self, n): To: Finite Field in b of size 2^10 Defn: a |--> b^7 + b^5 sage: H[2:4] - [ - Ring morphism: - From: Finite Field in a of size 2^5 - To: Finite Field in b of size 2^10 - Defn: a |--> b^8 + b^6 + b^2, - Ring morphism: - From: Finite Field in a of size 2^5 - To: Finite Field in b of size 2^10 - Defn: a |--> b^9 + b^7 + b^6 + b^5 + b^4 - ] + [Ring morphism: + From: Finite Field in a of size 2^5 + To: Finite Field in b of size 2^10 + Defn: a |--> b^8 + b^6 + b^2, + Ring morphism: + From: Finite Field in a of size 2^5 + To: Finite Field in b of size 2^10 + Defn: a |--> b^9 + b^7 + b^6 + b^5 + b^4] """ return self.list()[n] diff --git a/src/sage/rings/number_field/homset.py b/src/sage/rings/number_field/homset.py index 62ca214754d..b7d6a98eb2d 100644 --- a/src/sage/rings/number_field/homset.py +++ b/src/sage/rings/number_field/homset.py @@ -195,14 +195,12 @@ def list(self): sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^3 - 3*x + 1) sage: End(K).list() - [ - Ring endomorphism of Number Field in a with defining polynomial x^3 - 3*x + 1 - Defn: a |--> a, - Ring endomorphism of Number Field in a with defining polynomial x^3 - 3*x + 1 - Defn: a |--> a^2 - 2, - Ring endomorphism of Number Field in a with defining polynomial x^3 - 3*x + 1 - Defn: a |--> -a^2 - a + 2 - ] + [Ring endomorphism of Number Field in a with defining polynomial x^3 - 3*x + 1 + Defn: a |--> a, + Ring endomorphism of Number Field in a with defining polynomial x^3 - 3*x + 1 + Defn: a |--> a^2 - 2, + Ring endomorphism of Number Field in a with defining polynomial x^3 - 3*x + 1 + Defn: a |--> -a^2 - a + 2] sage: Hom(K, CyclotomicField(9))[0] # indirect doctest Ring morphism: From: Number Field in a with defining polynomial x^3 - 3*x + 1 @@ -214,20 +212,18 @@ def list(self): sage: K. = NumberField(x^3 - 2) sage: L. = K.extension(x^2 + 3) sage: Hom(K, L).list() - [ - Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Number Field in b with defining polynomial x^2 + 3 over its base field - Defn: a |--> a, - Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Number Field in b with defining polynomial x^2 + 3 over its base field - Defn: a |--> -1/2*a*b - 1/2*a, - Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Number Field in b with defining polynomial x^2 + 3 over its base field - Defn: a |--> 1/2*a*b - 1/2*a - ] + [Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Number Field in b with defining polynomial x^2 + 3 over its base field + Defn: a |--> a, + Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Number Field in b with defining polynomial x^2 + 3 over its base field + Defn: a |--> -1/2*a*b - 1/2*a, + Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Number Field in b with defining polynomial x^2 + 3 over its base field + Defn: a |--> 1/2*a*b - 1/2*a] """ D = self.domain() C = self.codomain() @@ -479,36 +475,50 @@ def list(self): sage: x = polygen(ZZ, 'x') sage: K. = NumberField([x^2 + x + 1, x^3 + 2]) sage: End(K).list() - [ - Relative number field endomorphism of - Number Field in a with defining polynomial x^2 + x + 1 over its base field - Defn: a |--> a - b |--> b, - ... - Relative number field endomorphism of - Number Field in a with defining polynomial x^2 + x + 1 over its base field - Defn: a |--> a - b |--> -b*a - b - ] + [Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field + Defn: a |--> a + b |--> b, + Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field + Defn: a |--> -a - 1 + b |--> b, + Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field + Defn: a |--> -a - 1 + b |--> b*a, + Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field + Defn: a |--> a + b |--> b*a, + Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field + Defn: a |--> -a - 1 + b |--> -b*a - b, + Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field + Defn: a |--> a + b |--> -b*a - b] An example with an absolute codomain:: sage: x = polygen(ZZ, 'x') sage: K. = NumberField([x^2 - 3, x^2 + 2]) sage: Hom(K, CyclotomicField(24, 'z')).list() - [ - Relative number field morphism: - From: Number Field in a with defining polynomial x^2 - 3 over its base field - To: Cyclotomic Field of order 24 and degree 8 - Defn: a |--> z^6 - 2*z^2 - b |--> -z^5 - z^3 + z, - ... - Relative number field morphism: - From: Number Field in a with defining polynomial x^2 - 3 over its base field - To: Cyclotomic Field of order 24 and degree 8 - Defn: a |--> -z^6 + 2*z^2 - b |--> z^5 + z^3 - z - ] + [Relative number field morphism: + From: Number Field in a with defining polynomial x^2 - 3 over its base field + To: Cyclotomic Field of order 24 and degree 8 + Defn: a |--> z^6 - 2*z^2 + b |--> -z^5 - z^3 + z, + Relative number field morphism: + From: Number Field in a with defining polynomial x^2 - 3 over its base field + To: Cyclotomic Field of order 24 and degree 8 + Defn: a |--> z^6 - 2*z^2 + b |--> z^5 + z^3 - z, + Relative number field morphism: + From: Number Field in a with defining polynomial x^2 - 3 over its base field + To: Cyclotomic Field of order 24 and degree 8 + Defn: a |--> -z^6 + 2*z^2 + b |--> -z^5 - z^3 + z, + Relative number field morphism: + From: Number Field in a with defining polynomial x^2 - 3 over its base field + To: Cyclotomic Field of order 24 and degree 8 + Defn: a |--> -z^6 + 2*z^2 + b |--> z^5 + z^3 - z] """ D = self.domain() C = self.codomain() diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 2559771ae62..6d927dbd019 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -3142,26 +3142,20 @@ def real_embeddings(self, prec=53): sage: x = polygen(QQ, 'x') sage: K. = NumberField(x^3 + 2) sage: K.real_embeddings() - [ - Ring morphism: - From: Number Field in a with defining polynomial x^3 + 2 - To: Real Field with 53 bits of precision - Defn: a |--> -1.25992104989487 - ] + [Ring morphism: + From: Number Field in a with defining polynomial x^3 + 2 + To: Real Field with 53 bits of precision + Defn: a |--> -1.25992104989487] sage: K.real_embeddings(16) - [ - Ring morphism: - From: Number Field in a with defining polynomial x^3 + 2 - To: Real Field with 16 bits of precision - Defn: a |--> -1.260 - ] + [Ring morphism: + From: Number Field in a with defining polynomial x^3 + 2 + To: Real Field with 16 bits of precision + Defn: a |--> -1.260] sage: K.real_embeddings(100) - [ - Ring morphism: - From: Number Field in a with defining polynomial x^3 + 2 - To: Real Field with 100 bits of precision - Defn: a |--> -1.2599210498948731647672106073 - ] + [Ring morphism: + From: Number Field in a with defining polynomial x^3 + 2 + To: Real Field with 100 bits of precision + Defn: a |--> -1.2599210498948731647672106073] As this is a numerical function, the number of embeddings may be incorrect if the precision is too low:: @@ -6245,13 +6239,18 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non sage: G = End(L); G Automorphism group of Number Field in b1 with defining polynomial x^6 + 108 sage: G.list() - [ - Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 - Defn: b1 |--> b1, - ... - Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 - Defn: b1 |--> -1/12*b1^4 - 1/2*b1 - ] + [Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 + Defn: b1 |--> b1, + Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 + Defn: b1 |--> -b1, + Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 + Defn: b1 |--> 1/12*b1^4 + 1/2*b1, + Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 + Defn: b1 |--> 1/12*b1^4 - 1/2*b1, + Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 + Defn: b1 |--> -1/12*b1^4 + 1/2*b1, + Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 + Defn: b1 |--> -1/12*b1^4 - 1/2*b1] sage: G[2](b1) 1/12*b1^4 + 1/2*b1 @@ -8663,39 +8662,51 @@ def optimized_subfields(self, degree=0, name=None, both_maps=True): sage: K. = NumberField(2*x^4 + 6*x^2 + 1/2) sage: K.optimized_subfields() - [ - (Number Field in a0 with defining polynomial x, Ring morphism: - From: Number Field in a0 with defining polynomial x - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: 0 |--> 0, None), - (Number Field in a1 with defining polynomial x^2 - 2*x + 2, Ring morphism: - From: Number Field in a1 with defining polynomial x^2 - 2*x + 2 - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: a1 |--> a^3 + 7/2*a + 1, None), - (Number Field in a2 with defining polynomial x^2 - 2*x + 2, Ring morphism: - From: Number Field in a2 with defining polynomial x^2 - 2*x + 2 - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: a2 |--> -a^3 - 7/2*a + 1, None), - (Number Field in a3 with defining polynomial x^2 - 2, Ring morphism: - From: Number Field in a3 with defining polynomial x^2 - 2 - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: a3 |--> a^2 + 3/2, None), - (Number Field in a4 with defining polynomial x^2 + 1, Ring morphism: - From: Number Field in a4 with defining polynomial x^2 + 1 - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: a4 |--> a^3 + 7/2*a, None), - (Number Field in a5 with defining polynomial x^2 + 2, Ring morphism: - From: Number Field in a5 with defining polynomial x^2 + 2 - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: a5 |--> 2*a^3 + 5*a, None), - (Number Field in a6 with defining polynomial x^4 + 1, Ring morphism: - From: Number Field in a6 with defining polynomial x^4 + 1 - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: a6 |--> a^3 + 1/2*a^2 + 5/2*a + 3/4, Ring morphism: - From: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - To: Number Field in a6 with defining polynomial x^4 + 1 - Defn: a |--> -1/2*a6^3 + a6^2 - 1/2*a6) - ] + [(Number Field in a0 with defining polynomial x, + Ring morphism: + From: Number Field in a0 with defining polynomial x + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: 0 |--> 0, + None), + (Number Field in a1 with defining polynomial x^2 - 2*x + 2, + Ring morphism: + From: Number Field in a1 with defining polynomial x^2 - 2*x + 2 + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: a1 |--> a^3 + 7/2*a + 1, + None), + (Number Field in a2 with defining polynomial x^2 - 2*x + 2, + Ring morphism: + From: Number Field in a2 with defining polynomial x^2 - 2*x + 2 + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: a2 |--> -a^3 - 7/2*a + 1, + None), + (Number Field in a3 with defining polynomial x^2 - 2, + Ring morphism: + From: Number Field in a3 with defining polynomial x^2 - 2 + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: a3 |--> a^2 + 3/2, + None), + (Number Field in a4 with defining polynomial x^2 + 1, + Ring morphism: + From: Number Field in a4 with defining polynomial x^2 + 1 + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: a4 |--> a^3 + 7/2*a, + None), + (Number Field in a5 with defining polynomial x^2 + 2, + Ring morphism: + From: Number Field in a5 with defining polynomial x^2 + 2 + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: a5 |--> 2*a^3 + 5*a, + None), + (Number Field in a6 with defining polynomial x^4 + 1, + Ring morphism: + From: Number Field in a6 with defining polynomial x^4 + 1 + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: a6 |--> a^3 + 1/2*a^2 + 5/2*a + 3/4, + Ring morphism: + From: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + To: Number Field in a6 with defining polynomial x^4 + 1 + Defn: a |--> -1/2*a6^3 + a6^2 - 1/2*a6)] """ return self._subfields_helper(degree=degree, name=name, both_maps=both_maps, optimize=True) @@ -8775,31 +8786,39 @@ def subfields(self, degree=0, name=None): sage: K. = NumberField(2*x^4 + 6*x^2 + 1/2) sage: K.subfields() - [ - (Number Field in a0 with defining polynomial x, Ring morphism: - From: Number Field in a0 with defining polynomial x - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: 0 |--> 0, None), - (Number Field in a1 with defining polynomial x^2 - 2, Ring morphism: - From: Number Field in a1 with defining polynomial x^2 - 2 - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: a1 |--> a^2 + 3/2, None), - (Number Field in a2 with defining polynomial x^2 + 4, Ring morphism: - From: Number Field in a2 with defining polynomial x^2 + 4 - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: a2 |--> 2*a^3 + 7*a, None), - (Number Field in a3 with defining polynomial x^2 + 2, Ring morphism: - From: Number Field in a3 with defining polynomial x^2 + 2 - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: a3 |--> 2*a^3 + 5*a, None), - (Number Field in a4 with defining polynomial x^4 + 1, Ring morphism: - From: Number Field in a4 with defining polynomial x^4 + 1 - To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - Defn: a4 |--> a^3 + 1/2*a^2 + 5/2*a + 3/4, Ring morphism: - From: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 - To: Number Field in a4 with defining polynomial x^4 + 1 - Defn: a |--> -1/2*a4^3 + a4^2 - 1/2*a4) - ] + [(Number Field in a0 with defining polynomial x, + Ring morphism: + From: Number Field in a0 with defining polynomial x + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: 0 |--> 0, + None), + (Number Field in a1 with defining polynomial x^2 - 2, + Ring morphism: + From: Number Field in a1 with defining polynomial x^2 - 2 + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: a1 |--> a^2 + 3/2, + None), + (Number Field in a2 with defining polynomial x^2 + 4, + Ring morphism: + From: Number Field in a2 with defining polynomial x^2 + 4 + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: a2 |--> 2*a^3 + 7*a, + None), + (Number Field in a3 with defining polynomial x^2 + 2, + Ring morphism: + From: Number Field in a3 with defining polynomial x^2 + 2 + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: a3 |--> 2*a^3 + 5*a, + None), + (Number Field in a4 with defining polynomial x^4 + 1, + Ring morphism: + From: Number Field in a4 with defining polynomial x^4 + 1 + To: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + Defn: a4 |--> a^3 + 1/2*a^2 + 5/2*a + 3/4, + Ring morphism: + From: Number Field in a with defining polynomial 2*x^4 + 6*x^2 + 1/2 + To: Number Field in a4 with defining polynomial x^4 + 1 + Defn: a |--> -1/2*a4^3 + a4^2 - 1/2*a4)] """ return self._subfields_helper(degree=degree, name=name, both_maps=True, optimize=False) @@ -9236,12 +9255,10 @@ def automorphisms(self): sage: x = polygen(QQ, 'x') sage: K. = NumberField(x^2 + 10000) sage: K.automorphisms() - [ - Ring endomorphism of Number Field in a with defining polynomial x^2 + 10000 - Defn: a |--> a, - Ring endomorphism of Number Field in a with defining polynomial x^2 + 10000 - Defn: a |--> -a - ] + [Ring endomorphism of Number Field in a with defining polynomial x^2 + 10000 + Defn: a |--> a, + Ring endomorphism of Number Field in a with defining polynomial x^2 + 10000 + Defn: a |--> -a] Here's a larger example, that would take some time if we found roots instead of using PARI's specialized machinery:: @@ -9266,14 +9283,12 @@ def automorphisms(self): sage: f = 7/9*x^3 + 7/3*x^2 - 56*x + 123 sage: K. = NumberField(f) sage: A = K.automorphisms(); A - [ - Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 - Defn: a |--> a, - Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 - Defn: a |--> -7/15*a^2 - 18/5*a + 96/5, - Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 - Defn: a |--> 7/15*a^2 + 13/5*a - 111/5 - ] + [Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 + Defn: a |--> a, + Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 + Defn: a |--> -7/15*a^2 - 18/5*a + 96/5, + Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 + Defn: a |--> 7/15*a^2 + 13/5*a - 111/5] sage: prod(x - sigma(a) for sigma in A) == f.monic() True """ @@ -9313,73 +9328,63 @@ def embeddings(self, K): sage: L. = QuadraticField(-7) sage: K = CyclotomicField(7) sage: L.embeddings(K) - [ - Ring morphism: - From: Number Field in a with defining polynomial x^2 + 7 - with a = 2.645751311064591?*I - To: Cyclotomic Field of order 7 and degree 6 - Defn: a |--> 2*zeta7^4 + 2*zeta7^2 + 2*zeta7 + 1, - Ring morphism: - From: Number Field in a with defining polynomial x^2 + 7 - with a = 2.645751311064591?*I - To: Cyclotomic Field of order 7 and degree 6 - Defn: a |--> -2*zeta7^4 - 2*zeta7^2 - 2*zeta7 - 1 - ] + [Ring morphism: + From: Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + To: Cyclotomic Field of order 7 and degree 6 + Defn: a |--> 2*zeta7^4 + 2*zeta7^2 + 2*zeta7 + 1, + Ring morphism: + From: Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + To: Cyclotomic Field of order 7 and degree 6 + Defn: a |--> -2*zeta7^4 - 2*zeta7^2 - 2*zeta7 - 1] We embed a cubic field in the complex numbers:: sage: x = polygen(QQ, 'x') sage: K. = NumberField(x^3 - 2) sage: K.embeddings(CC) - [ - Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Complex Field with 53 bits of precision - Defn: a |--> -0.62996052494743... - 1.09112363597172*I, - Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Complex Field with 53 bits of precision - Defn: a |--> -0.62996052494743... + 1.09112363597172*I, - Ring morphism: - From: Number Field in a with defining polynomial x^3 - 2 - To: Complex Field with 53 bits of precision - Defn: a |--> 1.25992104989487 - ] + [Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Complex Field with 53 bits of precision + Defn: a |--> -0.629960524947437 - 1.09112363597172*I, + Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Complex Field with 53 bits of precision + Defn: a |--> -0.629960524947437 + 1.09112363597172*I, + Ring morphism: + From: Number Field in a with defining polynomial x^3 - 2 + To: Complex Field with 53 bits of precision + Defn: a |--> 1.25992104989487] Some more (possible and impossible) embeddings of cyclotomic fields:: sage: CyclotomicField(5).embeddings(QQbar) - [ - Ring morphism: - From: Cyclotomic Field of order 5 and degree 4 - To: Algebraic Field - Defn: zeta5 |--> 0.3090169943749474? + 0.9510565162951536?*I, - Ring morphism: - From: Cyclotomic Field of order 5 and degree 4 - To: Algebraic Field - Defn: zeta5 |--> -0.8090169943749474? + 0.5877852522924731?*I, - Ring morphism: - From: Cyclotomic Field of order 5 and degree 4 - To: Algebraic Field - Defn: zeta5 |--> -0.8090169943749474? - 0.5877852522924731?*I, - Ring morphism: - From: Cyclotomic Field of order 5 and degree 4 - To: Algebraic Field - Defn: zeta5 |--> 0.3090169943749474? - 0.9510565162951536?*I - ] + [Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Algebraic Field + Defn: zeta5 |--> 0.3090169943749474? + 0.9510565162951536?*I, + Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Algebraic Field + Defn: zeta5 |--> -0.8090169943749474? + 0.5877852522924731?*I, + Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Algebraic Field + Defn: zeta5 |--> -0.8090169943749474? - 0.5877852522924731?*I, + Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Algebraic Field + Defn: zeta5 |--> 0.3090169943749474? - 0.9510565162951536?*I] sage: CyclotomicField(3).embeddings(CyclotomicField(7)) - [ ] + [] sage: CyclotomicField(3).embeddings(CyclotomicField(6)) - [ - Ring morphism: - From: Cyclotomic Field of order 3 and degree 2 - To: Cyclotomic Field of order 6 and degree 2 - Defn: zeta3 |--> zeta6 - 1, - Ring morphism: - From: Cyclotomic Field of order 3 and degree 2 - To: Cyclotomic Field of order 6 and degree 2 - Defn: zeta3 |--> -zeta6 - ] + [Ring morphism: + From: Cyclotomic Field of order 3 and degree 2 + To: Cyclotomic Field of order 6 and degree 2 + Defn: zeta3 |--> zeta6 - 1, + Ring morphism: + From: Cyclotomic Field of order 3 and degree 2 + To: Cyclotomic Field of order 6 and degree 2 + Defn: zeta3 |--> -zeta6] Test that :issue:`15053` is fixed:: @@ -11652,24 +11657,22 @@ def complex_embeddings(self, prec=53): EXAMPLES:: sage: CyclotomicField(5).complex_embeddings() - [ - Ring morphism: - From: Cyclotomic Field of order 5 and degree 4 - To: Complex Field with 53 bits of precision - Defn: zeta5 |--> 0.309016994374947 + 0.951056516295154*I, - Ring morphism: - From: Cyclotomic Field of order 5 and degree 4 - To: Complex Field with 53 bits of precision - Defn: zeta5 |--> -0.809016994374947 + 0.587785252292473*I, - Ring morphism: - From: Cyclotomic Field of order 5 and degree 4 - To: Complex Field with 53 bits of precision - Defn: zeta5 |--> -0.809016994374947 - 0.587785252292473*I, - Ring morphism: - From: Cyclotomic Field of order 5 and degree 4 - To: Complex Field with 53 bits of precision - Defn: zeta5 |--> 0.309016994374947 - 0.951056516295154*I - ] + [Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Complex Field with 53 bits of precision + Defn: zeta5 |--> 0.309016994374947 + 0.951056516295154*I, + Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Complex Field with 53 bits of precision + Defn: zeta5 |--> -0.809016994374947 + 0.587785252292473*I, + Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Complex Field with 53 bits of precision + Defn: zeta5 |--> -0.809016994374947 - 0.587785252292473*I, + Ring morphism: + From: Cyclotomic Field of order 5 and degree 4 + To: Complex Field with 53 bits of precision + Defn: zeta5 |--> 0.309016994374947 - 0.951056516295154*I] """ CC = sage.rings.complex_mpfr.ComplexField(prec) return self.embeddings(CC) @@ -11686,12 +11689,10 @@ def real_embeddings(self, prec=53): sage: len(CyclotomicField(4).real_embeddings()) 0 sage: CyclotomicField(2).real_embeddings() - [ - Ring morphism: - From: Cyclotomic Field of order 2 and degree 1 - To: Real Field with 53 bits of precision - Defn: -1 |--> -1.00000000000000 - ] + [Ring morphism: + From: Cyclotomic Field of order 2 and degree 1 + To: Real Field with 53 bits of precision + Defn: -1 |--> -1.00000000000000] """ K = sage.rings.real_mpfr.RealField(prec) return self.embeddings(K) @@ -12730,12 +12731,12 @@ def _splitting_classes_gens_(K, m, d): sage: L = K.subfields(20)[0][0] sage: L.conductor() # needs sage.groups 101 - sage: _splitting_classes_gens_(L,101,20) # needs sage.libs.gap # optional - gap_package_polycyclic + sage: _splitting_classes_gens_(L,101,20) # optional - gap_package_polycyclic, needs sage.libs.gap [95] sage: K = CyclotomicField(44) sage: L = K.subfields(4)[0][0] - sage: _splitting_classes_gens_(L,44,4) # needs sage.libs.gap # optional - gap_package_polycyclic + sage: _splitting_classes_gens_(L,44,4) # optional - gap_package_polycyclic, needs sage.libs.gap [37] sage: K = CyclotomicField(44) @@ -12747,7 +12748,7 @@ def _splitting_classes_gens_(K, m, d): with zeta44_0 = 3.837971894457990? sage: L.conductor() # needs sage.groups 11 - sage: _splitting_classes_gens_(L,11,5) # needs sage.libs.gap # optional - gap_package_polycyclic + sage: _splitting_classes_gens_(L,11,5) # optional - gap_package_polycyclic, needs sage.libs.gap [10] """ from sage.groups.abelian_gps.abelian_group import AbelianGroup diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index 7ea070b113e..55ad652f136 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -419,47 +419,36 @@ def subfields(self, degree=0, name=None): sage: PF. = F[] sage: K. = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: K.subfields(2) - [ - (Number Field in c0 with defining polynomial x^2 - 24*x + 96, - Ring morphism: - From: Number Field in c0 with defining polynomial x^2 - 24*x + 96 - To: Number Field in c with defining polynomial - Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - Defn: c0 |--> -4*b + 12, - None), - (Number Field in c1 with defining polynomial x^2 - 24*x + 120, - Ring morphism: - From: Number Field in c1 with defining polynomial x^2 - 24*x + 120 - To: Number Field in c with defining polynomial - Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - Defn: c1 |--> 2*b*a + 12, - None), - (Number Field in c2 with defining polynomial x^2 - 24*x + 72, - Ring morphism: - From: Number Field in c2 with defining polynomial x^2 - 24*x + 72 - To: Number Field in c with defining polynomial - Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - Defn: c2 |--> -6*a + 12, - None) - ] + [(Number Field in c0 with defining polynomial x^2 - 24*x + 96, + Ring morphism: + From: Number Field in c0 with defining polynomial x^2 - 24*x + 96 + To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Defn: c0 |--> -4*b + 12, + None), + (Number Field in c1 with defining polynomial x^2 - 24*x + 120, + Ring morphism: + From: Number Field in c1 with defining polynomial x^2 - 24*x + 120 + To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Defn: c1 |--> 2*b*a + 12, + None), + (Number Field in c2 with defining polynomial x^2 - 24*x + 72, + Ring morphism: + From: Number Field in c2 with defining polynomial x^2 - 24*x + 72 + To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Defn: c2 |--> -6*a + 12, + None)] sage: K.subfields(8, 'w') - [ - (Number Field in w0 with defining polynomial x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9, - Ring morphism: - From: Number Field in w0 with defining polynomial - x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9 - To: Number Field in c with defining polynomial - Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - Defn: w0 |--> (-1/2*b*a + 1/2*b + 1/2)*c, - Relative number field morphism: - From: Number Field in c with defining polynomial - Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - To: Number Field in w0 with defining polynomial - x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9 - Defn: c |--> -1/3*w0^7 + 4*w0^5 - 12*w0^3 + 11*w0 - a |--> 1/3*w0^6 - 10/3*w0^4 + 5*w0^2 - b |--> -2/3*w0^6 + 7*w0^4 - 14*w0^2 + 6) - ] + [(Number Field in w0 with defining polynomial x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9, + Ring morphism: + From: Number Field in w0 with defining polynomial x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9 + To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Defn: w0 |--> (-1/2*b*a + 1/2*b + 1/2)*c, + Relative number field morphism: + From: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + To: Number Field in w0 with defining polynomial x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9 + Defn: c |--> -1/3*w0^7 + 4*w0^5 - 12*w0^3 + 11*w0 + a |--> 1/3*w0^6 - 10/3*w0^4 + 5*w0^2 + b |--> -2/3*w0^6 + 7*w0^4 - 14*w0^2 + 6)] sage: K.subfields(3) [] """ @@ -2052,19 +2041,36 @@ def embeddings(self, K): sage: x = polygen(ZZ, 'x') sage: K. = NumberField([x^3 - 2, x^2 + 1]) sage: f = K.embeddings(ComplexField(58)); f - [ - Relative number field morphism: - From: Number Field in a with defining polynomial x^3 - 2 over its base field - To: Complex Field with 58 bits of precision - Defn: a |--> -0.62996052494743676 - 1.0911236359717214*I - b |--> -1.9428902930940239e-16 + 1.0000000000000000*I, - ... - Relative number field morphism: - From: Number Field in a with defining polynomial x^3 - 2 over its base field - To: Complex Field with 58 bits of precision - Defn: a |--> 1.2599210498948731 - b |--> -0.99999999999999999*I - ] + [Relative number field morphism: + From: Number Field in a with defining polynomial x^3 - 2 over its base field + To: Complex Field with 58 bits of precision + Defn: a |--> -0.62996052494743676 - 1.0911236359717214*I + b |--> -1.9428902930940239e-16 + 1.0000000000000000*I, + Relative number field morphism: + From: Number Field in a with defining polynomial x^3 - 2 over its base field + To: Complex Field with 58 bits of precision + Defn: a |--> -0.62996052494743657 - 1.0911236359717214*I + b |--> -1.0000000000000000*I, + Relative number field morphism: + From: Number Field in a with defining polynomial x^3 - 2 over its base field + To: Complex Field with 58 bits of precision + Defn: a |--> -0.62996052494743657 + 1.0911236359717214*I + b |--> 1.0000000000000000*I, + Relative number field morphism: + From: Number Field in a with defining polynomial x^3 - 2 over its base field + To: Complex Field with 58 bits of precision + Defn: a |--> -0.62996052494743676 + 1.0911236359717214*I + b |--> -1.9428902930940239e-16 - 1.0000000000000000*I, + Relative number field morphism: + From: Number Field in a with defining polynomial x^3 - 2 over its base field + To: Complex Field with 58 bits of precision + Defn: a |--> 1.2599210498948731 + b |--> 0.99999999999999999*I, + Relative number field morphism: + From: Number Field in a with defining polynomial x^3 - 2 over its base field + To: Complex Field with 58 bits of precision + Defn: a |--> 1.2599210498948731 + b |--> -0.99999999999999999*I] sage: f[0](a)^3 2.0000000000000002 - 8.6389229103644993e-16*I sage: f[0](b)^2 @@ -2105,16 +2111,12 @@ def automorphisms(self): sage: K. = NumberField([x^2 + 10000, x^2 + x + 50]); K Number Field in a with defining polynomial x^2 + 10000 over its base field sage: K.automorphisms() - [ - Relative number field endomorphism of Number Field in a - with defining polynomial x^2 + 10000 over its base field - Defn: a |--> a - b |--> b, - Relative number field endomorphism of Number Field in a - with defining polynomial x^2 + 10000 over its base field - Defn: a |--> -a - b |--> b - ] + [Relative number field endomorphism of Number Field in a with defining polynomial x^2 + 10000 over its base field + Defn: a |--> a + b |--> b, + Relative number field endomorphism of Number Field in a with defining polynomial x^2 + 10000 over its base field + Defn: a |--> -a + b |--> b] sage: rho, tau = K.automorphisms() sage: tau(a) -a @@ -2124,16 +2126,12 @@ def automorphisms(self): sage: L. = NumberField([x^2 + x + 50, x^2 + 10000, ]); L Number Field in b with defining polynomial x^2 + x + 50 over its base field sage: L.automorphisms() - [ - Relative number field endomorphism of Number Field in b - with defining polynomial x^2 + x + 50 over its base field - Defn: b |--> b - a |--> a, - Relative number field endomorphism of Number Field in b - with defining polynomial x^2 + x + 50 over its base field - Defn: b |--> -b - 1 - a |--> a - ] + [Relative number field endomorphism of Number Field in b with defining polynomial x^2 + x + 50 over its base field + Defn: b |--> b + a |--> a, + Relative number field endomorphism of Number Field in b with defining polynomial x^2 + x + 50 over its base field + Defn: b |--> -b - 1 + a |--> a] sage: rho, tau = L.automorphisms() sage: tau(a) == a True @@ -2145,18 +2143,14 @@ def automorphisms(self): sage: PF. = F[] sage: K. = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: K.automorphisms() - [ - Relative number field endomorphism of Number Field in c - with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - Defn: c |--> c - a |--> a - b |--> b, - Relative number field endomorphism of Number Field in c - with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - Defn: c |--> -c - a |--> a - b |--> b - ] + [Relative number field endomorphism of Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Defn: c |--> c + a |--> a + b |--> b, + Relative number field endomorphism of Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Defn: c |--> -c + a |--> a + b |--> b] """ try: return self.__automorphisms diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index f1b414089e2..7975a5053a9 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -634,10 +634,8 @@ def automorphisms(self): EXAMPLES:: sage: QQ.automorphisms() - [ - Ring endomorphism of Rational Field - Defn: 1 |--> 1 - ] + [Ring endomorphism of Rational Field + Defn: 1 |--> 1] """ return Sequence([self.hom(1, self)], cr=True, immutable=False, check=False) diff --git a/src/sage/schemes/generic/algebraic_scheme.py b/src/sage/schemes/generic/algebraic_scheme.py index a0257a065fd..3b135e39975 100755 --- a/src/sage/schemes/generic/algebraic_scheme.py +++ b/src/sage/schemes/generic/algebraic_scheme.py @@ -1196,16 +1196,14 @@ def irreducible_components(self): sage: PP. = ProjectiveSpace(4, QQ) sage: V = PP.subscheme((x^2 - y^2 - z^2) * (w^5 - 2*v^2*z^3) * w * (v^3 - x^2*z)) sage: V.irreducible_components() # needs sage.libs.singular - [ - Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: - w, - Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: - x^2 - y^2 - z^2, - Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: - x^2*z - v^3, - Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: - w^5 - 2*z^3*v^2 - ] + [Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: + w, + Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: + x^2 - y^2 - z^2, + Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: + x^2*z - v^3, + Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: + w^5 - 2*z^3*v^2] We verify that the irrelevant ideal is not accidentally returned (see :issue:`6920`):: @@ -1216,9 +1214,7 @@ def irreducible_components(self): sage: I = [f] + [f.derivative(zz) for zz in PP.gens()] sage: V = PP.subscheme(I) sage: V.irreducible_components() # needs sage.libs.singular - [ - - ] + [] The same polynomial as above defines a scheme with a nontrivial irreducible component in affine space (instead of @@ -1227,13 +1223,11 @@ def irreducible_components(self): sage: AA. = AffineSpace(4, QQ) sage: V = AA.subscheme(I) sage: V.irreducible_components() # needs sage.libs.singular - [ - Closed subscheme of Affine Space of dimension 4 over Rational Field defined by: - w, - z, - y, - x - ] + [Closed subscheme of Affine Space of dimension 4 over Rational Field defined by: + w, + z, + y, + x] """ try: return self.__irreducible_components diff --git a/src/sage/schemes/toric/divisor.py b/src/sage/schemes/toric/divisor.py index fe043e5dbb0..013c03030ee 100755 --- a/src/sage/schemes/toric/divisor.py +++ b/src/sage/schemes/toric/divisor.py @@ -2026,10 +2026,7 @@ class ToricRationalDivisorClassGroup_basis_lattice(FreeModule_ambient_pid): Basis lattice of The toric rational divisor class group of a 2-d CPR-Fano toric variety covered by 4 affine patches sage: L.basis() - [ - Divisor class [1, 0], - Divisor class [0, 1] - ] + [Divisor class [1, 0], Divisor class [0, 1]] """ def __init__(self, group): diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index 6f1ee1dc02f..304aea398f0 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -406,11 +406,7 @@ def __init__(self, x, universe=None, check=True, immutable=False, [1, 2, 3, 4, 5] sage: a = Sequence([1..3], universe=QQ, check=False, immutable=True, cr=True, cr_str=False, use_sage_types=True) sage: a - [ - 1, - 2, - 3 - ] + [1, 2, 3] sage: a = Sequence([1..5], universe=QQ, check=False, immutable=True, cr_str=True, use_sage_types=True) sage: a [1, 2, 3, 4, 5] diff --git a/src/sage/tensor/modules/comp.py b/src/sage/tensor/modules/comp.py index 32ac954c7b4..e173159bb63 100644 --- a/src/sage/tensor/modules/comp.py +++ b/src/sage/tensor/modules/comp.py @@ -50,11 +50,7 @@ sage: from sage.tensor.modules.comp import Components sage: V = VectorSpace(QQ,3) sage: basis = V.basis() ; basis - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] sage: c = Components(QQ, basis, 2) ; c 2-indices components w.r.t. [ (1, 0, 0), @@ -290,11 +286,7 @@ class Components(SageObject): sage: from sage.tensor.modules.comp import Components sage: V = VectorSpace(QQ,3) sage: basis = V.basis() ; basis - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] sage: c = Components(QQ, basis, 2) ; c 2-indices components w.r.t. [ (1, 0, 0), diff --git a/src/sage/tensor/modules/finite_rank_free_module.py b/src/sage/tensor/modules/finite_rank_free_module.py index 9b8aeb7eeb5..9da32715e9e 100644 --- a/src/sage/tensor/modules/finite_rank_free_module.py +++ b/src/sage/tensor/modules/finite_rank_free_module.py @@ -232,11 +232,7 @@ class :class:`~sage.modules.free_module.FreeModule_generic` distinguished basis, while ``FiniteRankFreeModule`` does not:: sage: N.basis() - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] sage: M.bases() [] sage: M.print_bases() @@ -378,11 +374,7 @@ class :class:`~sage.modules.free_module.FreeModule_generic` sage: V is QQ^3 True sage: V.basis() - [ - (1, 0, 0), - (0, 1, 0), - (0, 0, 1) - ] + [(1, 0, 0), (0, 1, 0), (0, 0, 1)] To create a vector space without any distinguished basis, one has to use ``FiniteRankFreeModule``:: diff --git a/src/sage/tests/book_stein_modform.py b/src/sage/tests/book_stein_modform.py index 667bb057c70..4b7e07a89d7 100644 --- a/src/sage/tests/book_stein_modform.py +++ b/src/sage/tests/book_stein_modform.py @@ -34,11 +34,9 @@ sage: E6^4 1/64524128256 - 1/32006016*q + 241/10668672*q^2 + O(q^3) sage: victor_miller_basis(28,5) - [ - 1 + 15590400*q^3 + 36957286800*q^4 + O(q^5), - q + 151740*q^3 + 61032448*q^4 + O(q^5), - q^2 + 192*q^3 - 8280*q^4 + O(q^5) - ] + [1 + 15590400*q^3 + 36957286800*q^4 + O(q^5), + q + 151740*q^3 + 61032448*q^4 + O(q^5), + q^2 + 192*q^3 - 8280*q^4 + O(q^5)] sage: R. = QQ[['q']] sage: F4 = 240 * eisenstein_series_qexp(4,3) sage: F6 = -504 * eisenstein_series_qexp(6,3) @@ -50,12 +48,10 @@ 1 + 196560*q^2 + O(q^3) sage: M = ModularForms(1,36, prec=6).echelon_form() sage: M.basis() - [ - 1 + 6218175600*q^4 + 15281788354560*q^5 + O(q^6), - q + 57093088*q^4 + 37927345230*q^5 + O(q^6), - q^2 + 194184*q^4 + 7442432*q^5 + O(q^6), - q^3 - 72*q^4 + 2484*q^5 + O(q^6) - ] + [1 + 6218175600*q^4 + 15281788354560*q^5 + O(q^6), + q + 57093088*q^4 + 37927345230*q^5 + O(q^6), + q^2 + 194184*q^4 + 7442432*q^5 + O(q^6), + q^3 - 72*q^4 + 2484*q^5 + O(q^6)] sage: T2 = M.hecke_matrix(2); T2 [ 34359738369 0 6218175600 9026867482214400] [ 0 0 34416831456 5681332472832] @@ -196,11 +192,9 @@ (x - 2)^2 * (x - 6)^3 * (x^2 - 8)^2 sage: M = ModularSymbols(39, 2) sage: M.T(2).decomposition() - [ - Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(39) of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 9 for Gamma_0(39) of weight 2 with sign 0 over Rational Field, - Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 9 for Gamma_0(39) of weight 2 with sign 0 over Rational Field - ] + [Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(39) of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 9 for Gamma_0(39) of weight 2 with sign 0 over Rational Field, + Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 9 for Gamma_0(39) of weight 2 with sign 0 over Rational Field] sage: M = ModularSymbols(2, 2) sage: M.boundary_map() Hecke module morphism boundary map defined by the matrix @@ -290,10 +284,7 @@ sage: f(1,0) -1/3*q^2 + 2/3*q^3 + 1/3*q^4 - 2/3*q^5 + O(q^6) sage: S.q_expansion_basis(6) - [ - q - q^3 - q^4 + O(q^6), - q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6) - ] + [q - q^3 - q^4 + O(q^6), q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6)] sage: R = Integers(49) sage: R Ring of integers modulo 49 @@ -342,16 +333,14 @@ 1 sage: G = DirichletGroup(20) sage: G.galois_orbits() - [ - [Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> -1], - [Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> -zeta4, - Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> zeta4], - [Dirichlet character modulo 20 of conductor 4 mapping 11 |--> -1, 17 |--> 1], - [Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> -1], - [Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> -zeta4, - Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> zeta4], - [Dirichlet character modulo 20 of conductor 1 mapping 11 |--> 1, 17 |--> 1] - ] + [[Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> -1], + [Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> -zeta4, + Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> zeta4], + [Dirichlet character modulo 20 of conductor 4 mapping 11 |--> -1, 17 |--> 1], + [Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> -1], + [Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> -zeta4, + Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> zeta4], + [Dirichlet character modulo 20 of conductor 1 mapping 11 |--> 1, 17 |--> 1]] sage: G = DirichletGroup(11, QQ); G Group of Dirichlet characters modulo 11 with values in Rational Field sage: list(G) @@ -423,19 +412,17 @@ -108846/5*zeta4 - 176868/5 sage: E = EisensteinForms(Gamma1(13),2) sage: E.eisenstein_series() - [ - 1/2 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6), - -7/13*zeta6 - 11/13 + q + (2*zeta6 + 1)*q^2 + (-3*zeta6 + 1)*q^3 + (6*zeta6 - 3)*q^4 - 4*q^5 + O(q^6), - q + (zeta6 + 2)*q^2 + (-zeta6 + 3)*q^3 + (3*zeta6 + 3)*q^4 + 4*q^5 + O(q^6), - -zeta6 + q + (2*zeta6 - 1)*q^2 + (3*zeta6 - 2)*q^3 + (-2*zeta6 - 1)*q^4 + 6*q^5 + O(q^6), - q + (zeta6 + 1)*q^2 + (zeta6 + 2)*q^3 + (zeta6 + 2)*q^4 + 6*q^5 + O(q^6), - -1 + q - q^2 + 4*q^3 + 3*q^4 - 4*q^5 + O(q^6), - q + q^2 + 4*q^3 + 3*q^4 + 4*q^5 + O(q^6), - zeta6 - 1 + q + (-2*zeta6 + 1)*q^2 + (-3*zeta6 + 1)*q^3 + (2*zeta6 - 3)*q^4 + 6*q^5 + O(q^6), - q + (-zeta6 + 2)*q^2 + (-zeta6 + 3)*q^3 + (-zeta6 + 3)*q^4 + 6*q^5 + O(q^6), - 7/13*zeta6 - 18/13 + q + (-2*zeta6 + 3)*q^2 + (3*zeta6 - 2)*q^3 + (-6*zeta6 + 3)*q^4 - 4*q^5 + O(q^6), - q + (-zeta6 + 3)*q^2 + (zeta6 + 2)*q^3 + (-3*zeta6 + 6)*q^4 + 4*q^5 + O(q^6) - ] + [1/2 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6), + -7/13*zeta6 - 11/13 + q + (2*zeta6 + 1)*q^2 + (-3*zeta6 + 1)*q^3 + (6*zeta6 - 3)*q^4 - 4*q^5 + O(q^6), + q + (zeta6 + 2)*q^2 + (-zeta6 + 3)*q^3 + (3*zeta6 + 3)*q^4 + 4*q^5 + O(q^6), + -zeta6 + q + (2*zeta6 - 1)*q^2 + (3*zeta6 - 2)*q^3 + (-2*zeta6 - 1)*q^4 + 6*q^5 + O(q^6), + q + (zeta6 + 1)*q^2 + (zeta6 + 2)*q^3 + (zeta6 + 2)*q^4 + 6*q^5 + O(q^6), + -1 + q - q^2 + 4*q^3 + 3*q^4 - 4*q^5 + O(q^6), + q + q^2 + 4*q^3 + 3*q^4 + 4*q^5 + O(q^6), + zeta6 - 1 + q + (-2*zeta6 + 1)*q^2 + (-3*zeta6 + 1)*q^3 + (2*zeta6 - 3)*q^4 + 6*q^5 + O(q^6), + q + (-zeta6 + 2)*q^2 + (-zeta6 + 3)*q^3 + (-zeta6 + 3)*q^4 + 6*q^5 + O(q^6), + 7/13*zeta6 - 18/13 + q + (-2*zeta6 + 3)*q^2 + (3*zeta6 - 2)*q^3 + (-6*zeta6 + 3)*q^4 - 4*q^5 + O(q^6), + q + (-zeta6 + 3)*q^2 + (zeta6 + 2)*q^3 + (-3*zeta6 + 6)*q^4 + 4*q^5 + O(q^6)] sage: e = E.eisenstein_series() sage: for e in E.eisenstein_series(): ....: print(e.parameters()) @@ -538,21 +525,15 @@ of dimension 10 for Congruence Subgroup Gamma0(45) of weight 2 over Rational Field sage: S.basis() - [ - q - q^4 - q^10 - 2*q^13 + O(q^14), - q^2 - q^5 - 3*q^8 + 4*q^11 + O(q^14), - q^3 - q^6 - q^9 - q^12 + O(q^14) - ] + [q - q^4 - q^10 - 2*q^13 + O(q^14), + q^2 - q^5 - 3*q^8 + 4*q^11 + O(q^14), + q^3 - q^6 - q^9 - q^12 + O(q^14)] sage: S.new_subspace().basis() - [ - q + q^2 - q^4 - q^5 - 3*q^8 - q^10 + 4*q^11 - 2*q^13 + O(q^14) - ] + [q + q^2 - q^4 - q^5 - 3*q^8 - q^10 + 4*q^11 - 2*q^13 + O(q^14)] sage: CuspForms(Gamma0(9),2) Cuspidal subspace of dimension 0 of Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(9) of weight 2 over Rational Field sage: CuspForms(Gamma0(15),2, prec=10).basis() - [ - q - q^2 - q^3 - q^4 + q^5 + q^6 + 3*q^8 + q^9 + O(q^10) - ] + [q - q^2 - q^3 - q^4 + q^5 + q^6 + 3*q^8 + q^9 + O(q^10)] """ diff --git a/src/sage/tests/books/judson-abstract-algebra/galois-sage.py b/src/sage/tests/books/judson-abstract-algebra/galois-sage.py index 9af165c8904..af1f6fa8e6f 100644 --- a/src/sage/tests/books/judson-abstract-algebra/galois-sage.py +++ b/src/sage/tests/books/judson-abstract-algebra/galois-sage.py @@ -152,16 +152,14 @@ ~~~~~~~~~~~~~~~~~~~~~~ :: sage: Sequence([[fromL(tau(r)) for r in roots] for tau in G], cr=True) - [ - [b, a, -a, -b], - [-b, -a, a, b], - [a, -b, b, -a], - [b, -a, a, -b], - [-a, -b, b, a], - [a, b, -b, -a], - [-b, a, -a, b], - [-a, b, -b, a] - ] + [[b, a, -a, -b], + [-b, -a, a, b], + [a, -b, b, -a], + [b, -a, a, -b], + [-a, -b, b, a], + [a, b, -b, -a], + [-b, a, -a, b], + [-a, b, -b, a]] ~~~~~~~~~~~~~~~~~~~~~~ :: @@ -382,71 +380,69 @@ ~~~~~~~~~~~~~~~~~~~~~~ :: sage: L.subfields() - [ - (Number Field in c0 with defining polynomial x, - Ring morphism: - From: Number Field in c0 with defining polynomial x - To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 - Defn: 0 |--> 0, - None), - (Number Field in c1 with defining polynomial x^2 + 112*x + 40000, - Ring morphism: - From: Number Field in c1 with defining polynomial x^2 + 112*x + 40000 - To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 - Defn: c1 |--> 4*c^4, - None), - (Number Field in c2 with defining polynomial x^2 + 512, - Ring morphism: - From: Number Field in c2 with defining polynomial x^2 + 512 - To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 - Defn: c2 |--> 1/25*c^6 + 78/25*c^2, - None), - (Number Field in c3 with defining polynomial x^2 - 288, - Ring morphism: - From: Number Field in c3 with defining polynomial x^2 - 288 - To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 - Defn: c3 |--> -1/25*c^6 + 22/25*c^2, - None), - (Number Field in c4 with defining polynomial x^4 + 112*x^2 + 40000, - Ring morphism: - From: Number Field in c4 with defining polynomial x^4 + 112*x^2 + 40000 - To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 - Defn: c4 |--> 2*c^2, - None), - (Number Field in c5 with defining polynomial x^4 + 8, - Ring morphism: - From: Number Field in c5 with defining polynomial x^4 + 8 - To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 - Defn: c5 |--> -1/80*c^5 + 1/40*c, + [(Number Field in c0 with defining polynomial x, + Ring morphism: + From: Number Field in c0 with defining polynomial x + To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 + Defn: 0 |--> 0, None), - (Number Field in c6 with defining polynomial x^4 + 648, - Ring morphism: - From: Number Field in c6 with defining polynomial x^4 + 648 - To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 - Defn: c6 |--> 1/80*c^5 + 79/40*c, - None), - (Number Field in c7 with defining polynomial x^4 - 512, - Ring morphism: - From: Number Field in c7 with defining polynomial x^4 - 512 - To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 - Defn: c7 |--> -1/60*c^5 + 41/30*c, - None), - (Number Field in c8 with defining polynomial x^4 - 32, - Ring morphism: - From: Number Field in c8 with defining polynomial x^4 - 32 - To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 - Defn: c8 |--> 1/60*c^5 + 19/30*c, - None), - (Number Field in c9 with defining polynomial x^8 + 28*x^4 + 2500, - Ring morphism: - From: Number Field in c9 with defining polynomial x^8 + 28*x^4 + 2500 - To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 - Defn: c9 |--> c, - Ring morphism: - From: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 - To: Number Field in c9 with defining polynomial x^8 + 28*x^4 + 2500 - Defn: c |--> c9) - ] + (Number Field in c1 with defining polynomial x^2 + 112*x + 40000, + Ring morphism: + From: Number Field in c1 with defining polynomial x^2 + 112*x + 40000 + To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 + Defn: c1 |--> 4*c^4, + None), + (Number Field in c2 with defining polynomial x^2 + 512, + Ring morphism: + From: Number Field in c2 with defining polynomial x^2 + 512 + To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 + Defn: c2 |--> 1/25*c^6 + 78/25*c^2, + None), + (Number Field in c3 with defining polynomial x^2 - 288, + Ring morphism: + From: Number Field in c3 with defining polynomial x^2 - 288 + To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 + Defn: c3 |--> -1/25*c^6 + 22/25*c^2, + None), + (Number Field in c4 with defining polynomial x^4 + 112*x^2 + 40000, + Ring morphism: + From: Number Field in c4 with defining polynomial x^4 + 112*x^2 + 40000 + To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 + Defn: c4 |--> 2*c^2, + None), + (Number Field in c5 with defining polynomial x^4 + 8, + Ring morphism: + From: Number Field in c5 with defining polynomial x^4 + 8 + To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 + Defn: c5 |--> -1/80*c^5 + 1/40*c, + None), + (Number Field in c6 with defining polynomial x^4 + 648, + Ring morphism: + From: Number Field in c6 with defining polynomial x^4 + 648 + To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 + Defn: c6 |--> 1/80*c^5 + 79/40*c, + None), + (Number Field in c7 with defining polynomial x^4 - 512, + Ring morphism: + From: Number Field in c7 with defining polynomial x^4 - 512 + To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 + Defn: c7 |--> -1/60*c^5 + 41/30*c, + None), + (Number Field in c8 with defining polynomial x^4 - 32, + Ring morphism: + From: Number Field in c8 with defining polynomial x^4 - 32 + To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 + Defn: c8 |--> 1/60*c^5 + 19/30*c, + None), + (Number Field in c9 with defining polynomial x^8 + 28*x^4 + 2500, + Ring morphism: + From: Number Field in c9 with defining polynomial x^8 + 28*x^4 + 2500 + To: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 + Defn: c9 |--> c, + Ring morphism: + From: Number Field in c with defining polynomial x^8 + 28*x^4 + 2500 + To: Number Field in c9 with defining polynomial x^8 + 28*x^4 + 2500 + Defn: c |--> c9)] ~~~~~~~~~~~~~~~~~~~~~~ :: diff --git a/src/sage/tests/books/judson-abstract-algebra/vect-sage.py b/src/sage/tests/books/judson-abstract-algebra/vect-sage.py index 23f624da585..083f35e9972 100644 --- a/src/sage/tests/books/judson-abstract-algebra/vect-sage.py +++ b/src/sage/tests/books/judson-abstract-algebra/vect-sage.py @@ -108,10 +108,7 @@ ~~~~~~~~~~~~~~~~~~~~~~ :: sage: S.basis() - [ - (1, 0, 2/3), - (0, 1, -7/3) - ] + [(1, 0, 2/3), (0, 1, -7/3)] ~~~~~~~~~~~~~~~~~~~~~~ :: From 39d98d5560ad4379fb5d3826b6381c0dbc62ebaa Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 11 Dec 2024 20:52:59 +0700 Subject: [PATCH 21/69] Clarify usage of cr and cr_str; add PolynomialSequence pretty printer --- src/sage/repl/display/fancy_repr.py | 5 ++ .../polynomial/multi_polynomial_sequence.py | 10 +--- src/sage/structure/sequence.py | 54 ++++++++++++++++--- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/sage/repl/display/fancy_repr.py b/src/sage/repl/display/fancy_repr.py index 05a6113fcb6..afa9f9e7109 100644 --- a/src/sage/repl/display/fancy_repr.py +++ b/src/sage/repl/display/fancy_repr.py @@ -118,7 +118,12 @@ def __init__(self): del type_repr[types.FunctionType] del type_repr[str] from sage.structure.sequence import Sequence_generic + from sage.rings.polynomial.multi_polynomial_sequence import ( + PolynomialSequence_generic, PolynomialSequence_gf2, PolynomialSequence_gf2e) type_repr[Sequence_generic] = type_repr[list] + type_repr[PolynomialSequence_generic] = type_repr[list] + type_repr[PolynomialSequence_gf2] = type_repr[list] + type_repr[PolynomialSequence_gf2e] = type_repr[list] self._type_repr = type_repr def __call__(self, obj, p, cycle): diff --git a/src/sage/rings/polynomial/multi_polynomial_sequence.py b/src/sage/rings/polynomial/multi_polynomial_sequence.py index 4a596cea922..c91b1d5b6a8 100644 --- a/src/sage/rings/polynomial/multi_polynomial_sequence.py +++ b/src/sage/rings/polynomial/multi_polynomial_sequence.py @@ -221,10 +221,7 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): - ``immutable`` -- if ``True`` the sequence is immutable (default: ``False``) - - ``cr`` -- print a line break after each element (default: ``False``) - - - ``cr_str`` -- print a line break after each element if 'str' is - called (default: ``None``) + - ``cr``, ``cr_str`` -- see :func:`~sage.structure.sequence.Sequence` EXAMPLES:: @@ -391,10 +388,7 @@ def __init__(self, parts, ring, immutable=False, cr=False, cr_str=None): - ``immutable`` -- if ``True`` the sequence is immutable (default: ``False``) - - ``cr`` -- print a line break after each element (default: ``False``) - - - ``cr_str`` -- print a line break after each element if 'str' - is called (default: ``None``) + - ``cr``, ``cr_str`` -- see :func:`~sage.structure.sequence.Sequence` EXAMPLES:: diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index 304aea398f0..2cbc6badee6 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -76,7 +76,7 @@ def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=None, use_sage_types=False): - """ + r""" A mutable list of elements with a common guaranteed universe, which can be set immutable. @@ -98,10 +98,10 @@ def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=Non immutable - ``cr`` -- boolean (default: ``False``); if ``True``, then print a carriage return - after each comma when printing this sequence + after each comma when calling ``repr()`` on this sequence (see note below) - - ``cr_str`` -- boolean (default: ``False``); if ``True``, then print a carriage return - after each comma when calling ``str()`` on this sequence + - ``cr_str`` -- boolean (default: same as ``cr``); if ``True``, then print a carriage return + after each comma when calling ``str()`` on this sequence (see note below) - ``use_sage_types`` -- boolean (default: ``False``); if ``True``, coerce the built-in Python numerical types int, float, complex to the corresponding @@ -203,12 +203,55 @@ def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=Non sage: v.universe() Finite Field of size 5 + .. NOTE:: + + ``cr`` and ``cr_str`` is not recommended (because IPython's pretty printer is used); + nevertheless it is kept for backwards compatibility. + + By default ``Sequence`` are printed using IPython's pretty printer, + so ``cr`` and ``cr_str`` are not taken into account at all:: + + sage: Sequence([1, 2, 3], cr=False) + [1, 2, 3] + sage: Sequence([1, 2, 3], cr=True) + [1, 2, 3] + + Nevertheless, before the pretty printer exists, ``repr()`` is used. + Now ``cr`` and ``cr_str`` still affects the behavior of ``repr()`` and ``str()``:: + + sage: repr(Sequence([1, 2, 3], cr=False)) + '[1, 2, 3]' + sage: repr(Sequence([1, 2, 3], cr=True)) + '[\n1,\n2,\n3\n]' + + In any case, this behavior should probably not be relied upon. + TESTS:: sage: Sequence(["a"], universe=ZZ) Traceback (most recent call last): ... TypeError: unable to convert a to an element of Integer Ring + + Here are some tests for ``cr`` and ``cr_str``, even though they shouldn't be used. + ``cr_str`` can be weird in this case, but we keep the current implementation + (the feature is not recommended anyway so it doesn't make much difference):: + + sage: str(Sequence([1, 2, 3], cr=True, cr_str=True)) + '[\n1,\n2,\n3\n]' + sage: str(Sequence([1, 2, 3], cr=True, cr_str=False)) + '[\n1,\n2,\n3\n]' + + In the opposite case, ``cr_str`` works fine:: + + sage: str(Sequence([1, 2, 3], cr=False, cr_str=False)) + '[1, 2, 3]' + sage: str(Sequence([1, 2, 3], cr=False, cr_str=True)) + '[\n1,\n2,\n3\n]' + sage: repr(Sequence([1, 2, 3], cr=False, cr_str=False)) + '[1, 2, 3]' + sage: repr(Sequence([1, 2, 3], cr=False, cr_str=True)) + '[1, 2, 3]' """ if universe is None: if isinstance(x, Sequence_generic): @@ -285,8 +328,7 @@ class Sequence_generic(sage.structure.sage_object.SageObject, list): - ``immutable`` -- boolean (default: ``True``); whether or not this sequence is immutable - - ``cr`` -- boolean (default: ``False``); if ``True``, then print a carriage return - after each comma when printing this sequence + - ``cr``, ``cr_str`` -- see :func:`Sequence` - ``use_sage_types`` -- boolean (default: ``False``); if ``True``, coerce the built-in Python numerical types int, float, complex to the corresponding From 23487e21e7a275fec1c357dc263264b89df23e57 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 11 Dec 2024 20:55:07 +0700 Subject: [PATCH 22/69] Add a warning comment --- src/sage/repl/display/fancy_repr.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/repl/display/fancy_repr.py b/src/sage/repl/display/fancy_repr.py index afa9f9e7109..12858037fd0 100644 --- a/src/sage/repl/display/fancy_repr.py +++ b/src/sage/repl/display/fancy_repr.py @@ -120,6 +120,7 @@ def __init__(self): from sage.structure.sequence import Sequence_generic from sage.rings.polynomial.multi_polynomial_sequence import ( PolynomialSequence_generic, PolynomialSequence_gf2, PolynomialSequence_gf2e) + # when :issue:`36801` is fixed, the code below will be redundant type_repr[Sequence_generic] = type_repr[list] type_repr[PolynomialSequence_generic] = type_repr[list] type_repr[PolynomialSequence_gf2] = type_repr[list] From dcb03d189c517d6ce0404b362a477d86dc805116 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 22 Dec 2024 12:20:17 +0100 Subject: [PATCH 23/69] Fix tests output for Python 3.13 --- src/doc/de/tutorial/tour_linalg.rst | 2 +- src/doc/en/tutorial/tour_linalg.rst | 2 +- src/doc/fr/tutorial/tour_linalg.rst | 2 +- src/doc/ja/tutorial/tour_linalg.rst | 2 +- src/doc/pt/tutorial/tour_linalg.rst | 2 +- src/doc/ru/tutorial/tour_linalg.rst | 2 +- src/sage/categories/map.pyx | 4 ++-- src/sage/misc/bindable_class.py | 2 +- src/sage/misc/sagedoc.py | 13 +++++++------ src/sage/misc/sageinspect.py | 2 +- src/sage/modular/modsym/modsym.py | 2 +- src/sage/repl/attach.py | 4 ++-- src/sage/repl/rich_output/pretty_print.py | 2 +- 13 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/doc/de/tutorial/tour_linalg.rst b/src/doc/de/tutorial/tour_linalg.rst index 1be6540c89e..abd47d2c488 100644 --- a/src/doc/de/tutorial/tour_linalg.rst +++ b/src/doc/de/tutorial/tour_linalg.rst @@ -245,4 +245,4 @@ Beachten Sie, dass Python zwischen Klein- und Großschreibung unterscheidet: sage: M = MatrixSpace(QQ, 10,10, Sparse=True) Traceback (most recent call last): ... - TypeError: ...__init__() got an unexpected keyword argument 'Sparse' + TypeError: ...__init__() got an unexpected keyword argument 'Sparse'... diff --git a/src/doc/en/tutorial/tour_linalg.rst b/src/doc/en/tutorial/tour_linalg.rst index 84a45f4931b..d1dde6a485e 100644 --- a/src/doc/en/tutorial/tour_linalg.rst +++ b/src/doc/en/tutorial/tour_linalg.rst @@ -239,4 +239,4 @@ Note that Python is case sensitive: sage: M = MatrixSpace(QQ, 10,10, Sparse=True) Traceback (most recent call last): ... - TypeError: ...__init__() got an unexpected keyword argument 'Sparse' + TypeError: ...__init__() got an unexpected keyword argument 'Sparse'... diff --git a/src/doc/fr/tutorial/tour_linalg.rst b/src/doc/fr/tutorial/tour_linalg.rst index 582a915edef..0dcdf044453 100644 --- a/src/doc/fr/tutorial/tour_linalg.rst +++ b/src/doc/fr/tutorial/tour_linalg.rst @@ -241,4 +241,4 @@ Notez que Python distingue les majuscules des minuscules : sage: M = MatrixSpace(QQ, 10,10, Sparse=True) Traceback (most recent call last): ... - TypeError: ...__init__() got an unexpected keyword argument 'Sparse' + TypeError: ...__init__() got an unexpected keyword argument 'Sparse'... diff --git a/src/doc/ja/tutorial/tour_linalg.rst b/src/doc/ja/tutorial/tour_linalg.rst index 227f879136e..263c5d7943a 100644 --- a/src/doc/ja/tutorial/tour_linalg.rst +++ b/src/doc/ja/tutorial/tour_linalg.rst @@ -252,4 +252,4 @@ Pythonでは,大文字小文字が区別されることに注意: sage: M = MatrixSpace(QQ, 10,10, Sparse=True) Traceback (most recent call last): ... - TypeError: ...__init__() got an unexpected keyword argument 'Sparse' + TypeError: ...__init__() got an unexpected keyword argument 'Sparse'... diff --git a/src/doc/pt/tutorial/tour_linalg.rst b/src/doc/pt/tutorial/tour_linalg.rst index 806a36c6446..79eb3ac7a9c 100644 --- a/src/doc/pt/tutorial/tour_linalg.rst +++ b/src/doc/pt/tutorial/tour_linalg.rst @@ -220,4 +220,4 @@ Note que o Python é sensível a maiúsculas e minúsculas: sage: M = MatrixSpace(QQ, 10,10, Sparse=True) Traceback (most recent call last): ... - TypeError: ...__init__() got an unexpected keyword argument 'Sparse' + TypeError: ...__init__() got an unexpected keyword argument 'Sparse'... diff --git a/src/doc/ru/tutorial/tour_linalg.rst b/src/doc/ru/tutorial/tour_linalg.rst index bf2a1084544..6ed95084d90 100644 --- a/src/doc/ru/tutorial/tour_linalg.rst +++ b/src/doc/ru/tutorial/tour_linalg.rst @@ -214,4 +214,4 @@ Sage поддерживает разреженную линейную алгеб sage: M = MatrixSpace(QQ, 10,10, Sparse=True) Traceback (most recent call last): ... - TypeError: ...__init__() got an unexpected keyword argument 'Sparse' + TypeError: ...__init__() got an unexpected keyword argument 'Sparse'... diff --git a/src/sage/categories/map.pyx b/src/sage/categories/map.pyx index 43e476847d0..0007555326a 100644 --- a/src/sage/categories/map.pyx +++ b/src/sage/categories/map.pyx @@ -275,7 +275,7 @@ cdef class Map(Element): maps:: sage: phi.domain # needs sage.rings.number_field - + sage: phi._make_strong_references() # needs sage.rings.number_field sage: print(phi.domain) # needs sage.rings.number_field The constant function (...) -> Number Field in a @@ -343,7 +343,7 @@ cdef class Map(Element): maps:: sage: phi.domain # needs sage.rings.number_field - + sage: phi._make_strong_references() # needs sage.rings.number_field sage: print(phi.domain) # needs sage.rings.number_field The constant function (...) -> Number Field in a diff --git a/src/sage/misc/bindable_class.py b/src/sage/misc/bindable_class.py index 743b5a19da6..c23ba0c2c43 100644 --- a/src/sage/misc/bindable_class.py +++ b/src/sage/misc/bindable_class.py @@ -113,7 +113,7 @@ class BindableClass(metaclass=ClasscallMetaclass): Still, documentation works as usual:: sage: outer.Inner.__doc__ - ' some documentation ' + '...some documentation ' TESTS:: diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index 0505f6039a9..539d90c0f0e 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -694,7 +694,7 @@ def format(s, embedded=False): We check that the todo Sphinx extension is correctly activated:: sage: sage.misc.sagedoc.format(sage.combinat.ranker.on_fly.__doc__) # needs sphinx - " Return ... Todo: add tests as in combinat::rankers\n" + "...Return ...Todo: add tests as in combinat::rankers\n" In the following use case, the ``nodetex`` directive would have been ignored prior to :issue:`11815`:: @@ -1135,10 +1135,11 @@ def search_src(string, extra1='', extra2='', extra3='', extra4='', The following produces an error because the string 'fetch(' is a malformed regular expression:: - sage: print(search_src(" fetch(", "def", interact=False)) - Traceback (most recent call last): - ... - error: missing ), unterminated subpattern at position 6 + sage: try: + ....: print(search_src(" fetch(", "def", interact=False)) + ....: except Exception as e: + ....: print(e) + missing ), unterminated subpattern at position 6 To fix this, *escape* the parenthesis with a backslash:: @@ -1456,7 +1457,7 @@ class _sage_doc: sage: browse_sage_doc._open("reference", testing=True)[0] # needs sagemath_doc_html 'http://localhost:8000/doc/live/reference/index.html' sage: browse_sage_doc(identity_matrix, 'rst')[-107:-47] # needs sage.modules - 'Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring' + '...Full MatrixSpace of 3 by 3 sparse matrices...' """ def __init__(self): """ diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index 585112b5061..12f319fc8e3 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -1986,7 +1986,7 @@ def sage_getdoc(obj, obj_name='', embedded=False): sage: from sage.misc.sageinspect import sage_getdoc sage: sage_getdoc(identity_matrix)[87:124] # needs sage.modules - 'Return the n x n identity matrix over' + '...the n x n identity matrix...' sage: def f(a, b, c, d=1): return a+b+c+d ... sage: import functools diff --git a/src/sage/modular/modsym/modsym.py b/src/sage/modular/modsym/modsym.py index fb46d0edafa..ed7c9285169 100644 --- a/src/sage/modular/modsym/modsym.py +++ b/src/sage/modular/modsym/modsym.py @@ -369,7 +369,7 @@ def ModularSymbols(group=1, {} sage: M = ModularSymbols(11,use_cache=True) sage: sage.modular.modsym.modsym._cache - {(Congruence Subgroup Gamma0(11), 2, 0, Rational Field): } + {(Congruence Subgroup Gamma0(11), 2, 0, Rational Field): } sage: M is ModularSymbols(11,use_cache=True) True sage: M is ModularSymbols(11,use_cache=False) diff --git a/src/sage/repl/attach.py b/src/sage/repl/attach.py index b3e20fe61d8..b9997d8f2df 100644 --- a/src/sage/repl/attach.py +++ b/src/sage/repl/attach.py @@ -40,7 +40,7 @@ ....: traceback.print_exc(file=sys.stdout) Traceback (most recent call last): ... - exec(preparse_file(f.read()) + "\n", globals) + exec(preparse_file(f.read()) + "\n", globals)... File "", line 3, in ValueError: third sage: detach(src) @@ -52,7 +52,7 @@ ....: traceback.print_exc(file=sys.stdout) Traceback (most recent call last): ... - exec(code, globals) + exec(code, globals)... File ".../foobar...sage.py", line ..., in raise ValueError("third") # this should appear in the source snippet... ValueError: third diff --git a/src/sage/repl/rich_output/pretty_print.py b/src/sage/repl/rich_output/pretty_print.py index 93833e01cd8..8e00e3d70e4 100644 --- a/src/sage/repl/rich_output/pretty_print.py +++ b/src/sage/repl/rich_output/pretty_print.py @@ -160,7 +160,7 @@ def pretty_print(self): sage: seq._concatenate_graphs().show(edge_labels=True) # needs sage.graphs sage.plot Traceback (most recent call last): ... - TypeError: ...matplotlib() got an unexpected keyword argument 'edge_labels' + TypeError: ...matplotlib() got an unexpected keyword argument 'edge_labels'... """ try: from sage.plot.plot import Graphics From 2ae4d753378bc2d0f3b964a97778b9798f4e8e10 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 22 Dec 2024 19:30:11 +0700 Subject: [PATCH 24/69] Add _repr_pretty_ framework and implement for correct classes --- src/sage/repl/display/fancy_repr.py | 13 +++--- .../polynomial/multi_polynomial_sequence.py | 40 +++++++++++++++++-- src/sage/structure/sequence.py | 18 +++++++++ 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/sage/repl/display/fancy_repr.py b/src/sage/repl/display/fancy_repr.py index 12858037fd0..392e6a5f0db 100644 --- a/src/sage/repl/display/fancy_repr.py +++ b/src/sage/repl/display/fancy_repr.py @@ -117,14 +117,6 @@ def __init__(self): del type_repr[types.BuiltinFunctionType] del type_repr[types.FunctionType] del type_repr[str] - from sage.structure.sequence import Sequence_generic - from sage.rings.polynomial.multi_polynomial_sequence import ( - PolynomialSequence_generic, PolynomialSequence_gf2, PolynomialSequence_gf2e) - # when :issue:`36801` is fixed, the code below will be redundant - type_repr[Sequence_generic] = type_repr[list] - type_repr[PolynomialSequence_generic] = type_repr[list] - type_repr[PolynomialSequence_gf2] = type_repr[list] - type_repr[PolynomialSequence_gf2e] = type_repr[list] self._type_repr = type_repr def __call__(self, obj, p, cycle): @@ -156,6 +148,11 @@ def __call__(self, obj, p, cycle): sage: pp.format_string(Sequence([[1]*20, [2]*20])) '[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]]' """ + if hasattr(type(obj), '_repr_pretty_'): + # standard method for classes to extend pretty library + # see https://ipython.readthedocs.io/en/stable/api/generated/IPython.lib.pretty.html#extending + obj._repr_pretty_(p, cycle) + return True try: pretty_repr = self._type_repr[type(obj)] except KeyError: diff --git a/src/sage/rings/polynomial/multi_polynomial_sequence.py b/src/sage/rings/polynomial/multi_polynomial_sequence.py index c91b1d5b6a8..ca6f864f807 100644 --- a/src/sage/rings/polynomial/multi_polynomial_sequence.py +++ b/src/sage/rings/polynomial/multi_polynomial_sequence.py @@ -899,16 +899,23 @@ def _magma_init_(self, magma): v = [x._magma_init_(magma) for x in list(self)] return 'ideal<%s|%s>' % (P, ','.join(v)) + def _is_short_for_repr(self): + """ + Return whether this system is considered short for :meth:`_repr_`. + """ + return len(self) < 20 + def _repr_(self): """ Return a string representation of this system. + Typically, :meth:`_repr_pretty_` is used instead of this method. EXAMPLES:: sage: # needs sage.libs.singular sage: P. = PolynomialRing(GF(127)) sage: I = sage.rings.ideal.Katsura(P) - sage: F = Sequence(I); F # indirect doctest + sage: F = Sequence(I); print(F._repr_()) [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, @@ -921,11 +928,38 @@ def _repr_(self): sage: F,s = sr.polynomial_system(); F # needs sage.rings.polynomial.pbori Polynomial Sequence with 36 Polynomials in 20 Variables """ - if len(self) < 20: - return Sequence_generic._repr_(self) + if self._is_short_for_repr(): + return super()._repr_() else: return "Polynomial Sequence with %d Polynomials in %d Variables" % (len(self),self.nvariables()) + def _repr_pretty_(self, p, cycle): + """ + For pretty printing in the Sage command prompt. + + EXAMPLES:: + + sage: # needs sage.libs.singular + sage: P. = PolynomialRing(GF(127)) + sage: I = sage.rings.ideal.Katsura(P) + sage: F = Sequence(I); F # indirect doctest + [a + 2*b + 2*c + 2*d - 1, + a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, + 2*a*b + 2*b*c + 2*c*d - b, + b^2 + 2*a*c + 2*b*d - c] + + If the system contains 20 or more polynomials, a short summary + is printed:: + + sage: sr = mq.SR(allow_zero_inversions=True, gf2=True) # needs sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system(); F # needs sage.rings.polynomial.pbori + Polynomial Sequence with 36 Polynomials in 20 Variables + """ + if self._is_short_for_repr(): + super()._repr_pretty_(p, cycle) + else: + p.text(repr(self)) + def __add__(self, right): """ Add polynomial systems together, i.e. create a union of their diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index 2cbc6badee6..614ad8c0fe4 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -684,6 +684,9 @@ def __hash__(self): def _repr_(self): """ + Return a string representation of this sequence. + Typically, :meth:`_repr_pretty_` is used instead of this method. + EXAMPLES:: sage: Sequence([1,2/3,-2/5])._repr_() @@ -700,6 +703,21 @@ def _repr_(self): else: return list.__repr__(self) + def _repr_pretty_(self, p, cycle): + """ + For pretty printing in the Sage command prompt. + + Since ``Sequence`` inherits from ``list``, we just use IPython's built-in + ``list`` pretty printer. + When :issue:`36801` is fixed, this function will be redundant. + + EXAMPLES:: + + sage: Sequence([1,2/3,-2/5]) # indirect doctest + [1, 2/3, -2/5] + """ + p.pretty(list(self)) + def _latex_(self): r""" TESTS:: From 76bc9915fa7549f7bd4e5edb0d272367cf5d705e Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 22 Dec 2024 20:23:44 +0700 Subject: [PATCH 25/69] Fix more tests --- src/sage/coding/linear_code.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index 07527e7e154..0a7fdd5080b 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -80,12 +80,10 @@ class should inherit from this class. Also ``AbstractLinearCode`` should never sage: G = MS([[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: C.basis() - [ - (1, 1, 1, 0, 0, 0, 0), - (1, 0, 0, 1, 1, 0, 0), - (0, 1, 0, 1, 0, 1, 0), - (1, 1, 0, 1, 0, 0, 1) - ] + [(1, 1, 1, 0, 0, 0, 0), + (1, 0, 0, 1, 1, 0, 0), + (0, 1, 0, 1, 0, 1, 0), + (1, 1, 0, 1, 0, 0, 1)] sage: c = C.basis()[1] sage: c in C True From 1551def6d18f82cd8cc91c6b8afe69b7a15c87c1 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 22 Dec 2024 20:29:34 +0700 Subject: [PATCH 26/69] Retrigger CI From 2deeb13ca0d75334bc6727e207caa0dd40e25ba3 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 22 Dec 2024 21:01:13 +0700 Subject: [PATCH 27/69] Fix more tests --- src/sage/geometry/lattice_polytope.py | 18 ++++++++---------- src/sage/modular/local_comp/local_comp.py | 16 ++++------------ src/sage/modular/modform/constructor.py | 5 +---- src/sage/modular/modform/cuspidal_submodule.py | 7 +------ 4 files changed, 14 insertions(+), 32 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 0ae3a84fa41..38957d20a80 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -2739,16 +2739,14 @@ def nef_partitions(self, keep_symmetric=False, keep_products=True, Partitions will be exactly the same:: sage: p.nef_partitions(hodge_numbers=True) # long time (2s on sage.math, 2011), needs palp - [ - Nef-partition {0, 1, 4, 5} ⊔ {2, 3, 6, 7} (direct product), - Nef-partition {0, 1, 2, 4} ⊔ {3, 5, 6, 7}, - Nef-partition {0, 1, 2, 4, 5} ⊔ {3, 6, 7}, - Nef-partition {0, 1, 2, 4, 5, 6} ⊔ {3, 7} (direct product), - Nef-partition {0, 1, 2, 3} ⊔ {4, 5, 6, 7}, - Nef-partition {0, 1, 2, 3, 4} ⊔ {5, 6, 7}, - Nef-partition {0, 1, 2, 3, 4, 5} ⊔ {6, 7}, - Nef-partition {0, 1, 2, 3, 4, 5, 6} ⊔ {7} (projection) - ] + [Nef-partition {0, 1, 4, 5} ⊔ {2, 3, 6, 7} (direct product), + Nef-partition {0, 1, 2, 4} ⊔ {3, 5, 6, 7}, + Nef-partition {0, 1, 2, 4, 5} ⊔ {3, 6, 7}, + Nef-partition {0, 1, 2, 4, 5, 6} ⊔ {3, 7} (direct product), + Nef-partition {0, 1, 2, 3} ⊔ {4, 5, 6, 7}, + Nef-partition {0, 1, 2, 3, 4} ⊔ {5, 6, 7}, + Nef-partition {0, 1, 2, 3, 4, 5} ⊔ {6, 7}, + Nef-partition {0, 1, 2, 3, 4, 5, 6} ⊔ {7} (projection)] Now it is possible to get Hodge numbers:: diff --git a/src/sage/modular/local_comp/local_comp.py b/src/sage/modular/local_comp/local_comp.py index 13d346ed7d6..dc303ae9e00 100644 --- a/src/sage/modular/local_comp/local_comp.py +++ b/src/sage/modular/local_comp/local_comp.py @@ -676,12 +676,8 @@ def characters(self): sage: f = Newform('81a', names='j'); f q + j0*q^2 + q^4 - j0*q^5 + O(q^6) sage: LocalComponent(f, 3).characters() # long time (12s on sage.math, 2012) - [ - Character of unramified extension Q_3(s)* (s^2 + 2*s + 2 = 0), - of level 2, mapping -2*s |--> -2*d + j0, 4 |--> 1, 3*s + 1 |--> -j0*d + 1, 3 |--> 1, - Character of unramified extension Q_3(s)* (s^2 + 2*s + 2 = 0), - of level 2, mapping -2*s |--> 2*d - j0, 4 |--> 1, 3*s + 1 |--> j0*d - 2, 3 |--> 1 - ] + [Character of unramified extension Q_3(s)* (s^2 + 2*s + 2 = 0), of level 2, mapping -2*s |--> -2*d + j0, 4 |--> 1, 3*s + 1 |--> -j0*d + 1, 3 |--> 1, + Character of unramified extension Q_3(s)* (s^2 + 2*s + 2 = 0), of level 2, mapping -2*s |--> 2*d - j0, 4 |--> 1, 3*s + 1 |--> j0*d - 2, 3 |--> 1] Some ramified examples:: @@ -710,12 +706,8 @@ def characters(self): mapping s |--> 1, 2*s + 1 |--> 1/2*a0, 4*s + 1 |--> -1, -1 |--> 1, 2 |--> 1 ] sage: Newform('243a',names='a').local_component(3).characters() # long time - [ - Character of ramified extension Q_3(s)* (s^2 - 6 = 0), of level 4, - mapping -2*s - 1 |--> -d - 1, 4 |--> 1, 3*s + 1 |--> -d - 1, s |--> 1, - Character of ramified extension Q_3(s)* (s^2 - 6 = 0), of level 4, - mapping -2*s - 1 |--> d, 4 |--> 1, 3*s + 1 |--> d, s |--> 1 - ] + [Character of ramified extension Q_3(s)* (s^2 - 6 = 0), of level 4, mapping -2*s - 1 |--> -d - 1, 4 |--> 1, 3*s + 1 |--> -d - 1, s |--> 1, + Character of ramified extension Q_3(s)* (s^2 - 6 = 0), of level 4, mapping -2*s - 1 |--> d, 4 |--> 1, 3*s + 1 |--> d, s |--> 1] """ T = self.type_space() p = self.prime() diff --git a/src/sage/modular/modform/constructor.py b/src/sage/modular/modform/constructor.py index db65774b193..5877288f896 100644 --- a/src/sage/modular/modform/constructor.py +++ b/src/sage/modular/modform/constructor.py @@ -285,10 +285,7 @@ def ModularForms(group=1, Modular Forms space of dimension 38 for Congruence Subgroup Gamma1(57) of weight 1 over Rational Field sage: M.cuspidal_submodule().basis() # long time - [ - q - q^4 + O(q^6), - q^3 - q^4 + O(q^6) - ] + [q - q^4 + O(q^6), q^3 - q^4 + O(q^6)] The Eisenstein subspace in weight 1 can be computed quickly, without triggering the expensive computation of the cuspidal part:: diff --git a/src/sage/modular/modform/cuspidal_submodule.py b/src/sage/modular/modform/cuspidal_submodule.py index 942b6d628b6..3be7a3c61c0 100644 --- a/src/sage/modular/modform/cuspidal_submodule.py +++ b/src/sage/modular/modform/cuspidal_submodule.py @@ -386,12 +386,7 @@ def _compute_q_expansion_basis(self, prec=None): 2-dimensional space):: sage: CuspForms(GammaH(124, [85]), 1).q_expansion_basis() # long time - [ - q - q^4 - q^6 + O(q^7), - q^2 + O(q^7), - q^3 + O(q^7), - q^5 - q^6 + O(q^7) - ] + [q - q^4 - q^6 + O(q^7), q^2 + O(q^7), q^3 + O(q^7), q^5 - q^6 + O(q^7)] """ if prec is None: prec = self.prec() From d37fbebbadde27c6203a24494ec16c69e393efa0 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 22 Dec 2024 21:06:24 +0700 Subject: [PATCH 28/69] Revert unwanted changes --- src/sage/geometry/lattice_polytope.py | 27 ++++++++++++++------------- src/sage/matrix/matrix2.pyx | 16 ++++++++++------ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 38957d20a80..da030a17966 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -2967,8 +2967,10 @@ def normal_form(self, algorithm='palp_native', permutation=False): sage: o = lattice_polytope.cross_polytope(2) sage: o.normal_form(algorithm='palp_modified') # needs sage.groups - Traceback (most recent call last): - ... + M( 1, 0), + M( 0, 1), + M( 0, -1), + M(-1, 0) in 2-d lattice M The following examples demonstrate the speed of the available algorithms. @@ -3178,13 +3180,17 @@ def _palp_modified_normal_form(self, permutation=False): M( 0, -1) in 2-d lattice M sage: o._palp_modified_normal_form() # needs sage.graphs sage.groups - Traceback (most recent call last): - ... + M( 1, 0), + M( 0, 1), + M( 0, -1), + M(-1, 0) in 2-d lattice M sage: o._palp_modified_normal_form(permutation=True) # needs sage.graphs sage.groups - Traceback (most recent call last): - ... - (3,4)) + (M( 1, 0), + M( 0, 1), + M( 0, -1), + M(-1, 0) + in 2-d lattice M, (3,4)) """ PM = self.vertex_facet_pairing_matrix() PM_max = PM.permutation_normal_form() @@ -3275,16 +3281,11 @@ def _palp_PM_max(self, check=False): sage: o = lattice_polytope.cross_polytope(2) sage: PM = o.vertex_facet_pairing_matrix() sage: PM_max = PM.permutation_normal_form() # needs sage.graphs - Traceback (most recent call last): - ... - sage: PM_max == o._palp_PM_max() # needs sage.graphs sage.groups - Traceback (most recent call last): - ... True sage: P2 = ReflexivePolytope(2, 0) sage: PM_max, permutations = P2._palp_PM_max(check=True) # needs sage.groups - sage: PM_max # needs sage.graphs sage.groups + sage: PM_max # needs sage.graphs [3 0 0] [0 3 0] [0 0 3] diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 7a9494dda1e..07be64d8ca5 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -8654,8 +8654,8 @@ cdef class Matrix(Matrix1): [0 0 0] sage: M.permutation_normal_form() - Traceback (most recent call last): - ... + [2 1 0] + [1 0 0] [0 0 0] sage: M = matrix(ZZ, [[-1, 3], [-1, 5], [2, 4]]) @@ -8665,8 +8665,11 @@ cdef class Matrix(Matrix1): [ 2 4] sage: M.permutation_normal_form(check=True) # needs sage.graphs sage.groups - Traceback (most recent call last): - ... + ( + [ 5 -1] + [ 4 2] + [ 3 -1], + ((1,2,3), (1,2)) ) TESTS:: @@ -8674,8 +8677,9 @@ cdef class Matrix(Matrix1): sage: # needs sage.graphs sage: M = matrix(ZZ, [[3, 4, 5], [3, 4, 5], [3, 5, 4], [2, 0,1]]) sage: M.permutation_normal_form() - Traceback (most recent call last): - ... + [5 4 3] + [5 4 3] + [4 5 3] [1 0 2] sage: M = matrix(ZZ, 0, 0, []) sage: M.permutation_normal_form() From 010e8d0cff4e5fd0864806ce0a3ffffb72abe1f3 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 22 Dec 2024 22:05:24 +0700 Subject: [PATCH 29/69] Unrelated test fix --- src/sage/repl/image.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/repl/image.py b/src/sage/repl/image.py index 06a6f6a671a..1169b29c466 100644 --- a/src/sage/repl/image.py +++ b/src/sage/repl/image.py @@ -113,7 +113,7 @@ def pil(self): sage: from sage.repl.image import Image sage: img = Image('RGB', (16, 16), 'white') sage: img.pil - + """ return self._pil From 4e99193ecb4da5df6cdb3f96323fbead9833a173 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 22 Dec 2024 22:07:03 +0700 Subject: [PATCH 30/69] Fix more tests --- .../calculus_doctest.py | 6 +-- .../linalg_doctest.py | 39 ++++++++----------- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/calculus_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/calculus_doctest.py index 90db67c02e1..b5531b112b4 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/calculus_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/calculus_doctest.py @@ -494,11 +494,7 @@ Sage example in ./calculus.tex, line 2487:: sage: A.eigenvectors_right() - [(1, [ - (1, -1, 1) - ], 1), (-2, [ - (1, -1, 0) - ], 2)] + [(1, [(1, -1, 1)], 1), (-2, [(1, -1, 0)], 2)] Sage example in ./calculus.tex, line 2499:: diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/linalg_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/linalg_doctest.py index e904843bfdd..9a52f0f97ed 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/linalg_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/linalg_doctest.py @@ -406,30 +406,23 @@ sage: A.eigenvalues() [4, 1, 2, 2] sage: A.eigenvectors_right() - [(4, [ - (1, 5, 5, 1) - ], 1), (1, [ - (0, 1, 1, 4) - ], 1), (2, [ - (1, 3, 0, 1), - (0, 0, 1, 1) - ], 2)] + [(4, [(1, 5, 5, 1)], 1), + (1, [(0, 1, 1, 4)], 1), + (2, [(1, 3, 0, 1), (0, 0, 1, 1)], 2)] sage: A.eigenspaces_right() - [ - (4, Vector space of degree 4 and dimension 1 over Finite Field - of size 7 - User basis matrix: - [1 5 5 1]), - (1, Vector space of degree 4 and dimension 1 over Finite Field - of size 7 - User basis matrix: - [0 1 1 4]), - (2, Vector space of degree 4 and dimension 2 over Finite Field - of size 7 - User basis matrix: - [1 3 0 1] - [0 0 1 1]) - ] + [(4, + Vector space of degree 4 and dimension 1 over Finite Field of size 7 + User basis matrix: + [1 5 5 1]), + (1, + Vector space of degree 4 and dimension 1 over Finite Field of size 7 + User basis matrix: + [0 1 1 4]), + (2, + Vector space of degree 4 and dimension 2 over Finite Field of size 7 + User basis matrix: + [1 3 0 1] + [0 0 1 1])] Sage example in ./linalg.tex, line 2770:: From fd108891c041e010efc279939fa5ac81a37b4c4b Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 22 Dec 2024 19:55:31 +0100 Subject: [PATCH 31/69] Fix meta-test broken by previous commit --- src/sage/misc/sagedoc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index 539d90c0f0e..6147ec4983b 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -1187,7 +1187,6 @@ def search_src(string, extra1='', extra2='', extra3='', extra4='', misc/sagedoc.py:... len(search_src("matrix", interact=False).splitlines())... misc/sagedoc.py:... len(search_src("matrix", module="sage.calculus", interact=False).splitlines())... misc/sagedoc.py:... len(search_src("matrix", path_re="calc"... - misc/sagedoc.py:... print(search_src(" fetch(", "def", interact=False))... misc/sagedoc.py:... print(search_src(r" fetch\(", "def", interact=False))... misc/sagedoc.py:... print(search_src(r" fetch\(", "def", "pyx", interact=False))... misc/sagedoc.py:... s = search_src('Matrix', path_re='matrix', interact=False); s.find('x') > 0... From 0069cf13bd260864fce7c2d15363e4f390930f69 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:48:35 +0700 Subject: [PATCH 32/69] Apply suggested changes --- src/sage/misc/cython.py | 6 +++--- src/sage/repl/ipython_extension.py | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index f77b5afcdd5..fde36372712 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -117,7 +117,7 @@ def cython(filename, verbose=0, compile_message=False, - ``view_annotate_callback`` -- function (default: ``webbrowser.open``); a function that takes a string being the path to the html file. This can be overridden to change what to do with the annotated html file. Have no effect unless - ``view_annotate`` is ``True`` + ``view_annotate`` is ``True``. - ``sage_namespace`` -- boolean (default: ``True``); if ``True``, import ``sage.all`` @@ -250,7 +250,7 @@ def cython(filename, verbose=0, compile_message=False, ....: ''', view_annotate=True, annotate=False) Traceback (most recent call last): ... - ValueError: Cannot view annotated file without creating it + ValueError: cannot view annotated file without creating it :: @@ -420,7 +420,7 @@ def cython(filename, verbose=0, compile_message=False, if view_annotate: if not annotate: - raise ValueError("Cannot view annotated file without creating it") + raise ValueError("cannot view annotated file without creating it") view_annotate_callback(os.path.join(target_dir, name + ".html")) # This emulates running "setup.py build" with the correct options diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index c159f193ec5..4f75c563253 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -382,13 +382,12 @@ def cython(self, line, cell): For ``--view-annotate``, the following additional choices are allowed: - - ``--view-annotate=none`` (default) - - ``--view-annotate=auto`` (same as ``--view-annotate``); select one of the - choices below automatically + - ``--view-annotate=none`` (default); do not view the annotated html file + - ``--view-annotate`` (alternatively ``--view-annotate=auto``); select one of the + choices below automatically: use ``webbrowser`` in the Sage command line + and ``displayhtml`` in the Sage notebook - ``--view-annotate=webbrowser``; open the annotation in a web browser - (preferred if the Sage command line is used) - ``--view-annotate=displayhtml``; display the annotation inline in the notebook - (preferred if the Sage notebook is used) - ``cell`` -- string; the Cython source code to process From d1d43668897e11952183b1e3b78a16c3a150f244 Mon Sep 17 00:00:00 2001 From: ekwankyu <129141416+ekwankyu@users.noreply.github.com> Date: Mon, 23 Dec 2024 15:16:41 +0900 Subject: [PATCH 33/69] Update the copyright year in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af91374fe19..f54d7ad34b6 100644 --- a/README.md +++ b/README.md @@ -679,7 +679,7 @@ information, patches, and build scripts are in the accompanying part of the Sage git repository.

- Copyright (C) 2005-2024 The Sage Development Team + Copyright (C) 2005-2025 The Sage Development Team

https://www.sagemath.org From 2d5ce6d5b0fe5d5f85cdfdf714fb239f41cead67 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 23 Dec 2024 13:17:13 +0700 Subject: [PATCH 34/69] Add back some ellipsis and random markers --- src/sage/graphs/generic_graph.py | 10 ++++---- src/sage/modular/dirichlet.py | 20 ++-------------- src/sage/rings/number_field/homset.py | 24 ++----------------- src/sage/rings/number_field/number_field.py | 11 ++------- .../rings/number_field/number_field_rel.py | 21 +--------------- 5 files changed, 12 insertions(+), 74 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index ae1d9bfa4da..badd28f4fb8 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -5361,7 +5361,7 @@ def cycle_basis(self, output='vertex'): A cycle basis in Petersen's Graph :: sage: g = graphs.PetersenGraph() - sage: g.cycle_basis() # needs networkx + sage: g.cycle_basis() # needs networkx, random (changes in networkx 3.2) [[6, 8, 5, 7, 9], [2, 3, 8, 5, 7], [4, 3, 8, 5, 7, 9], @@ -5371,7 +5371,7 @@ def cycle_basis(self, output='vertex'): One can also get the result as a list of lists of edges:: - sage: g.cycle_basis(output='edge') # needs networkx + sage: g.cycle_basis(output='edge') # needs networkx, random (changes in networkx 3.2) [[(6, 8, None), (8, 5, None), (5, 7, None), (7, 9, None), (9, 6, None)], [(2, 3, None), (3, 8, None), (8, 5, None), (5, 7, None), (7, 2, None)], [(4, 3, None), @@ -5562,9 +5562,9 @@ def minimum_cycle_basis(self, algorithm=None, weight_function=None, by_weight=Fa [[1, 2, 3], [1, 2, 3, 4], [5, 6, 7]] sage: sorted(g.minimum_cycle_basis(by_weight=False)) [[1, 2, 3], [1, 3, 4], [5, 6, 7]] - sage: sorted(g.minimum_cycle_basis(by_weight=True, algorithm='NetworkX')) # needs networkx + sage: sorted(g.minimum_cycle_basis(by_weight=True, algorithm='NetworkX')) # needs networkx, random (changes in networkx 3.2) [[2, 3, 1], [2, 3, 4, 1], [6, 7, 5]] - sage: g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX') # needs networkx + sage: g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX') # needs networkx, random (changes in networkx 3.2) [[3, 4, 1], [2, 3, 1], [6, 7, 5]] :: @@ -5572,7 +5572,7 @@ def minimum_cycle_basis(self, algorithm=None, weight_function=None, by_weight=Fa sage: g = Graph([(1, 2), (2, 3), (3, 4), (4, 5), (5, 1), (5, 3)]) sage: sorted(g.minimum_cycle_basis(by_weight=False)) [[1, 2, 3, 5], [3, 4, 5]] - sage: sorted(g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX')) # needs networkx + sage: sorted(g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX')) # needs networkx, random (changes in networkx 3.2) [[3, 4, 5], [5, 3, 2, 1]] TESTS:: diff --git a/src/sage/modular/dirichlet.py b/src/sage/modular/dirichlet.py index 9603bb91e02..f3a778b6766 100644 --- a/src/sage/modular/dirichlet.py +++ b/src/sage/modular/dirichlet.py @@ -1265,16 +1265,7 @@ def galois_orbit(self, sort=True): sage: G = DirichletGroup(13) sage: G.galois_orbits() [[Dirichlet character modulo 13 of conductor 1 mapping 2 |--> 1], - [Dirichlet character modulo 13 of conductor 13 mapping 2 |--> zeta12, - Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -zeta12^3 + zeta12, - Dirichlet character modulo 13 of conductor 13 mapping 2 |--> zeta12^3 - zeta12, - Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -zeta12], - [Dirichlet character modulo 13 of conductor 13 mapping 2 |--> zeta12^2, - Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -zeta12^2 + 1], - [Dirichlet character modulo 13 of conductor 13 mapping 2 |--> zeta12^3, - Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -zeta12^3], - [Dirichlet character modulo 13 of conductor 13 mapping 2 |--> zeta12^2 - 1, - Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -zeta12^2], + ..., [Dirichlet character modulo 13 of conductor 13 mapping 2 |--> -1]] sage: e = G.0 sage: e @@ -3050,14 +3041,7 @@ def galois_orbits(self, v=None, reps_only=False, sort=True, check=True): EXAMPLES:: sage: DirichletGroup(20).galois_orbits() - [[Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> -1], - [Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> -zeta4, - Dirichlet character modulo 20 of conductor 20 mapping 11 |--> -1, 17 |--> zeta4], - [Dirichlet character modulo 20 of conductor 4 mapping 11 |--> -1, 17 |--> 1], - [Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> -1], - [Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> -zeta4, - Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> zeta4], - [Dirichlet character modulo 20 of conductor 1 mapping 11 |--> 1, 17 |--> 1]] + [[Dirichlet character modulo 20 of conductor 20 mapping ...]] sage: DirichletGroup(17, Integers(6), zeta=Integers(6)(5)).galois_orbits() Traceback (most recent call last): ... diff --git a/src/sage/rings/number_field/homset.py b/src/sage/rings/number_field/homset.py index b7d6a98eb2d..49f309fdd34 100644 --- a/src/sage/rings/number_field/homset.py +++ b/src/sage/rings/number_field/homset.py @@ -478,18 +478,7 @@ def list(self): [Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field Defn: a |--> a b |--> b, - Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field - Defn: a |--> -a - 1 - b |--> b, - Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field - Defn: a |--> -a - 1 - b |--> b*a, - Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field - Defn: a |--> a - b |--> b*a, - Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field - Defn: a |--> -a - 1 - b |--> -b*a - b, + ... Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field Defn: a |--> a b |--> -b*a - b] @@ -504,16 +493,7 @@ def list(self): To: Cyclotomic Field of order 24 and degree 8 Defn: a |--> z^6 - 2*z^2 b |--> -z^5 - z^3 + z, - Relative number field morphism: - From: Number Field in a with defining polynomial x^2 - 3 over its base field - To: Cyclotomic Field of order 24 and degree 8 - Defn: a |--> z^6 - 2*z^2 - b |--> z^5 + z^3 - z, - Relative number field morphism: - From: Number Field in a with defining polynomial x^2 - 3 over its base field - To: Cyclotomic Field of order 24 and degree 8 - Defn: a |--> -z^6 + 2*z^2 - b |--> -z^5 - z^3 + z, + ... Relative number field morphism: From: Number Field in a with defining polynomial x^2 - 3 over its base field To: Cyclotomic Field of order 24 and degree 8 diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index f812c5b6a04..ca2cce7ec1e 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -6240,14 +6240,7 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non sage: G.list() [Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 Defn: b1 |--> b1, - Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 - Defn: b1 |--> -b1, - Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 - Defn: b1 |--> 1/12*b1^4 + 1/2*b1, - Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 - Defn: b1 |--> 1/12*b1^4 - 1/2*b1, - Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 - Defn: b1 |--> -1/12*b1^4 + 1/2*b1, + ... Ring endomorphism of Number Field in b1 with defining polynomial x^6 + 108 Defn: b1 |--> -1/12*b1^4 - 1/2*b1] sage: G[2](b1) @@ -9340,7 +9333,7 @@ def embeddings(self, K): sage: x = polygen(QQ, 'x') sage: K. = NumberField(x^3 - 2) - sage: K.embeddings(CC) + sage: K.embeddings(CC) # abs tol 1e-12 [Ring morphism: From: Number Field in a with defining polynomial x^3 - 2 To: Complex Field with 53 bits of precision diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index 55ad652f136..861375b0fb7 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -2046,26 +2046,7 @@ def embeddings(self, K): To: Complex Field with 58 bits of precision Defn: a |--> -0.62996052494743676 - 1.0911236359717214*I b |--> -1.9428902930940239e-16 + 1.0000000000000000*I, - Relative number field morphism: - From: Number Field in a with defining polynomial x^3 - 2 over its base field - To: Complex Field with 58 bits of precision - Defn: a |--> -0.62996052494743657 - 1.0911236359717214*I - b |--> -1.0000000000000000*I, - Relative number field morphism: - From: Number Field in a with defining polynomial x^3 - 2 over its base field - To: Complex Field with 58 bits of precision - Defn: a |--> -0.62996052494743657 + 1.0911236359717214*I - b |--> 1.0000000000000000*I, - Relative number field morphism: - From: Number Field in a with defining polynomial x^3 - 2 over its base field - To: Complex Field with 58 bits of precision - Defn: a |--> -0.62996052494743676 + 1.0911236359717214*I - b |--> -1.9428902930940239e-16 - 1.0000000000000000*I, - Relative number field morphism: - From: Number Field in a with defining polynomial x^3 - 2 over its base field - To: Complex Field with 58 bits of precision - Defn: a |--> 1.2599210498948731 - b |--> 0.99999999999999999*I, + ... Relative number field morphism: From: Number Field in a with defining polynomial x^3 - 2 over its base field To: Complex Field with 58 bits of precision From 788872834c482cdab6ac4122b89d8735bbba50f8 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:18:29 +0700 Subject: [PATCH 35/69] Mark test as random to avoid failure --- src/sage/rings/number_field/galois_group.py | 2 +- src/sage/rings/number_field/number_field.py | 3 +++ src/sage/rings/number_field/number_field_ideal.py | 7 ++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/number_field/galois_group.py b/src/sage/rings/number_field/galois_group.py index c974c3df6ff..bb4e453c650 100644 --- a/src/sage/rings/number_field/galois_group.py +++ b/src/sage/rings/number_field/galois_group.py @@ -994,7 +994,7 @@ def artin_symbol(self, P): sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^4 - 2*x^2 + 2, 'a').galois_closure() sage: G = K.galois_group() - sage: [G.artin_symbol(P) for P in K.primes_above(7)] + sage: [G.artin_symbol(P) for P in K.primes_above(7)] # random (see remark in primes_above) [(1,4)(2,3)(5,8)(6,7), (1,4)(2,3)(5,8)(6,7), (1,5)(2,6)(3,7)(4,8), (1,5)(2,6)(3,7)(4,8)] sage: G.artin_symbol(17) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index dbd8e7e2edf..e0b82bbcb8f 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -3725,6 +3725,9 @@ def primes_above(self, x, degree=None): The output is sorted by residue degree first, then by underlying prime (or equivalently, by norm). + If there is a tie, the exact ordering should be assumed to be random. + See the remark in :meth:`NumberFieldIdeal._richcmp_`. + EXAMPLES:: sage: x = ZZ['x'].gen() diff --git a/src/sage/rings/number_field/number_field_ideal.py b/src/sage/rings/number_field/number_field_ideal.py index 171fba9af6e..71374297177 100644 --- a/src/sage/rings/number_field/number_field_ideal.py +++ b/src/sage/rings/number_field/number_field_ideal.py @@ -230,6 +230,11 @@ def _richcmp_(self, other, op): can give rise to the same ideal. And this can easily be detected using Hermite normal form. + As an implementation detail (this may change in the future), + the Hermite normal form is with respect to the integral basis + computed by Pari, and this may be different across different + runs and operating systems. + EXAMPLES:: sage: x = polygen(ZZ) @@ -237,7 +242,7 @@ def _richcmp_(self, other, op): Number Field in a with defining polynomial x^2 + 3 sage: f = K.factor(15); f (Fractional ideal (1/2*a + 3/2))^2 * (Fractional ideal (5)) - sage: (f[0][0] < f[1][0]) + sage: (f[0][0] < f[1][0]) # potentially random True sage: (f[0][0] == f[0][0]) True From eb50b657af40a9d11b044a16d7ea7f0747033d98 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 23 Dec 2024 16:42:09 +0700 Subject: [PATCH 36/69] Simplify documentation of --view-annotate --- src/sage/repl/ipython_extension.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index 4f75c563253..6c28c03f3da 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -380,14 +380,12 @@ def cython(self, line, cell): See :func:`~sage.misc.cython.cython` for details. - For ``--view-annotate``, the following additional choices are allowed: + If ``--view-annotate`` is given, the annotation is either displayed + inline in the Sage notebook or opened in a new web browser, depends + on whether the Sage notebook is used. - - ``--view-annotate=none`` (default); do not view the annotated html file - - ``--view-annotate`` (alternatively ``--view-annotate=auto``); select one of the - choices below automatically: use ``webbrowser`` in the Sage command line - and ``displayhtml`` in the Sage notebook - - ``--view-annotate=webbrowser``; open the annotation in a web browser - - ``--view-annotate=displayhtml``; display the annotation inline in the notebook + You can override the selection by specifying + ``--view-annotate=webbrowser`` or ``--view-annotate=displayhtml``. - ``cell`` -- string; the Cython source code to process @@ -460,7 +458,7 @@ def cython(self, line, cell): sage: shell.run_cell(''' ....: %%cython --view-annotate=auto ....: print(1) - ....: ''') + ....: ''') # --view-annotate=auto is undocumented feature, equivalent to --view-annotate 1 sage: shell.run_cell(''' ....: %%cython --view-annotate=webbrowser From 41280d7d0e405fe29e876233aba3b86b325f05d2 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 23 Dec 2024 19:23:45 +0800 Subject: [PATCH 37/69] Meson: find more dependencies via pkg-config --- src/meson.build | 49 +++++++++++++++++++++++++-------------- src/sage/libs/meson.build | 8 +++++-- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/meson.build b/src/meson.build index 1e528727a4f..fb22b2cec22 100644 --- a/src/meson.build +++ b/src/meson.build @@ -56,9 +56,10 @@ print(cypari2.__file__.replace('__init__.py', '')) check: true, ).stdout().strip() cypari2 = declare_dependency(include_directories: inc_cypari2) +# Cannot be found via pkg-config pari = cc.find_library('pari') -mpfr = cc.find_library('mpfr') +mpfr = dependency('mpfr') flint = dependency('flint', version: '>=3.0.0') if flint.version().version_compare('<3.1') @@ -78,35 +79,47 @@ 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) -gd = cc.find_library('gd') +gsl = dependency('gsl', version: '>=2.5') +gd = dependency('gdlib', required: false, version: '>=2.1') +if not gd.found() + gd = cc.find_library('gd', required: true) +endif # 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) -m4ri = cc.find_library('m4ri') -m4rie = cc.find_library('m4rie') -mtx = cc.find_library('mtx', required: false, disabler: true) -png = cc.find_library('png', required: false) -if not png.found() - png = cc.find_library('png16') +m4ri = dependency('m4ri', version: '>=20140914') +m4rie = dependency('m4rie', required: false) +if not m4rie.found() + # For some reason, m4rie is not found via pkg-config on some systems (eg Conda) + m4rie = cc.find_library('m4rie') endif -zlib = cc.find_library('z') # Cannot be found via pkg-config -ec = cc.find_library('ec') +mtx = cc.find_library('mtx', required: false, disabler: true) +png = dependency(['libpng', 'png', 'png16'], version: '>=1.2') +zlib = dependency('zlib', version: '>=1.2.11') +# We actually want >= 20231212, but the version number is not updated in the pkgconfig +# https://github.com/conda-forge/eclib-feedstock/issues/48 +ec = dependency('eclib', version: '>=20231211') +# Cannot be found via pkg-config ecm = cc.find_library('ecm') +# Cannot be found via pkg-config ppl = cc.find_library('ppl') -gmpxx = cc.find_library('gmpxx') -fflas = dependency('fflas-ffpack') +gmpxx = dependency('gmpxx') +fflas = dependency('fflas-ffpack', version: '>=2.5.0') fplll = dependency('fplll') -givaro = cc.find_library('givaro') -linbox = dependency('linbox', required: false) +givaro = dependency('givaro', version: '>=4.2.0') +linbox = dependency('linbox', required: false, version: '>=1.7.0') if not linbox.found() linbox = cc.find_library('linbox') endif mpc = cc.find_library('mpc') mpfi = cc.find_library('mpfi') -# Cannot be found via pkg-config (pkg-config file will be added in 4.13) -# Test for common.h header that was added in 4.12 as a indirect version check -gap = cc.find_library('gap', has_headers: ['gap/common.h']) + +gap = dependency('libgap', version: '>=4.13.0', required: false) +if not gap.found() + # Fallback in case pkg-config info is not available + # Test for common.h header that was added in 4.12 as a indirect version check + gap = cc.find_library('gap', has_headers: ['gap/common.h']) +endif singular = dependency('Singular') maxima = find_program('maxima', required: true) # Cannot be found via pkg-config diff --git a/src/sage/libs/meson.build b/src/sage/libs/meson.build index 34b26b09ff1..53470399d46 100644 --- a/src/sage/libs/meson.build +++ b/src/sage/libs/meson.build @@ -1,8 +1,12 @@ sirocco = cc.find_library('sirocco', required: false, disabler: true) # cannot be found via pkg-config ecl = cc.find_library('ecl') -braiding = cc.find_library('braiding') -gc = cc.find_library('gc') +braiding = dependency('libbraiding', required: false) +if not braiding.found() + # Fallback since pkg-config support was only added in v1.3.1 + braiding = cc.find_library('braiding') +endif +gc = dependency(['bdw-gc-threaded', 'bdw-gc'], version: '>=7.6.4') homfly = cc.find_library('homfly', has_headers: ['homfly.h']) py.install_sources( From d3e23a70403a598a0421a4549bde02ac8d975d65 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 23 Dec 2024 18:45:45 +0700 Subject: [PATCH 38/69] Apply suggested changes --- src/sage/repl/ipython_extension.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index 6c28c03f3da..0818b0033b2 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -381,7 +381,7 @@ def cython(self, line, cell): See :func:`~sage.misc.cython.cython` for details. If ``--view-annotate`` is given, the annotation is either displayed - inline in the Sage notebook or opened in a new web browser, depends + inline in the Sage notebook or opened in a new web browser, depending on whether the Sage notebook is used. You can override the selection by specifying From 61166967838d8e8aba0baf3f22d5dcea28775936 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 23 Dec 2024 20:33:05 +0700 Subject: [PATCH 39/69] Convert file path to URI before pass to webbrowser.open() --- src/sage/misc/cython.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index fde36372712..29c013eab19 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -25,6 +25,7 @@ import sys import shutil import webbrowser +from pathlib import Path from sage.env import (SAGE_LOCAL, cython_aliases, sage_include_directories) @@ -79,9 +80,16 @@ def _standard_libs_libdirs_incdirs_aliases(): sequence_number = {} +def _webbrowser_open_file(path): + """ + Open a html file in a web browser. + """ + webbrowser.open(Path(path).as_uri()) + + def cython(filename, verbose=0, compile_message=False, use_cache=False, create_local_c_file=False, annotate=True, view_annotate=False, - view_annotate_callback=webbrowser.open, sage_namespace=True, create_local_so_file=False): + view_annotate_callback=_webbrowser_open_file, sage_namespace=True, create_local_so_file=False): r""" Compile a Cython file. This converts a Cython file to a C (or C++ file), and then compiles that. The .c file and the .so file are @@ -112,11 +120,11 @@ def cython(filename, verbose=0, compile_message=False, then save a copy of the .html file in the current directory. - ``view_annotate`` -- boolean (default: ``False``); if ``True``, open the - annotated html file in a web browser using :func:`webbrowser.open` + annotated html file in a web browser - - ``view_annotate_callback`` -- function (default: ``webbrowser.open``); a function - that takes a string being the path to the html file. This can be overridden to - change what to do with the annotated html file. Have no effect unless + - ``view_annotate_callback`` -- function; a function that takes a string + being the path to the html file. This can be overridden to change + what to do with the annotated html file. Have no effect unless ``view_annotate`` is ``True``. - ``sage_namespace`` -- boolean (default: ``True``); if ``True``, import From 4a82a39e0812e673c69e6a3fea4ef32c3b2915ce Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 23 Dec 2024 20:33:57 +0700 Subject: [PATCH 40/69] Fix findstat._submit --- src/sage/databases/findstat.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/databases/findstat.py b/src/sage/databases/findstat.py index 1285569805e..0822a92c168 100644 --- a/src/sage/databases/findstat.py +++ b/src/sage/databases/findstat.py @@ -213,6 +213,7 @@ def mapping(sigma): from ast import literal_eval from copy import deepcopy +from pathlib import Path import re import webbrowser import tempfile @@ -491,8 +492,9 @@ def _submit(args, url): ....: "CurrentEmail": ""} sage: _submit(args, url) # optional -- webbrowser """ - f = tempfile.NamedTemporaryFile(mode='w', suffix='.html', delete=False) + f = tempfile.NamedTemporaryFile(mode='w', suffix='.html', encoding='utf-8', delete=False) verbose("Created temporary file %s" % f.name, caller_name='FindStat') + f.write('\n\n\n') f.write(FINDSTAT_POST_HEADER) f.write(url) for key, value in args.items(): @@ -506,7 +508,7 @@ def _submit(args, url): f.write(FINDSTAT_FORM_FOOTER) f.close() verbose("Opening file with webbrowser", caller_name='FindStat') - webbrowser.open(f.name) + webbrowser.open(Path(f.name).as_uri()) def _data_to_str(data, domain, codomain=None): From 2ced164bc6c87ab3ae227d975fd9f868c2d80b76 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 24 Dec 2024 19:02:56 +0800 Subject: [PATCH 41/69] Apply suggestions --- src/sage/manifolds/catalog.py | 12 ++++++------ src/sage/manifolds/chart.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/manifolds/catalog.py b/src/sage/manifolds/catalog.py index af0d1a663ec..bbd05367960 100644 --- a/src/sage/manifolds/catalog.py +++ b/src/sage/manifolds/catalog.py @@ -203,11 +203,11 @@ def Kerr(m=1, a=0, coordinates='BL', names=None): -(1 - 2 * m * r / rho**2), 1 + 2 * m * r / rho**2, rho**2, - (r**2 + a**2 + 2 * a**2 * m * r * sin(th) ** 2 / rho**2) * sin(th) ** 2, + (r**2 + a**2 + 2 * a**2 * m * r * sin(th)**2 / rho**2) * sin(th)**2, ) g[0, 1] = 2 * m * r / rho**2 - g[0, 3] = -2 * a * m * r / rho**2 * sin(th) ** 2 - g[1, 3] = -a * sin(th) ** 2 * (1 + 2 * m * r / rho**2) + g[0, 3] = -2 * a * m * r / rho**2 * sin(th)**2 + g[1, 3] = -a * sin(th)**2 * (1 + 2 * m * r / rho**2) return M if coordinates == "BL": @@ -229,14 +229,14 @@ def Kerr(m=1, a=0, coordinates='BL', names=None): M._first_ngens = C._first_ngens g = M.metric('g') t, r, th, ph = C[:] - rho = sqrt(r**2 + a**2 * cos(th) ** 2) + rho = sqrt(r**2 + a**2 * cos(th)**2) g[0, 0], g[1, 1], g[2, 2], g[3, 3] = ( -(1 - 2 * m * r / rho**2), rho**2 / (r**2 - 2 * m * r + a**2), rho**2, - (r**2 + a**2 + 2 * m * r * a**2 / rho**2 * sin(th) ** 2) * sin(th) ** 2, + (r**2 + a**2 + 2 * m * r * a**2 / rho**2 * sin(th)**2) * sin(th)**2, ) - g[0, 3] = -2 * m * r * a * sin(th) ** 2 / rho**2 + g[0, 3] = -2 * m * r * a * sin(th)**2 / rho**2 return M raise NotImplementedError( diff --git a/src/sage/manifolds/chart.py b/src/sage/manifolds/chart.py index ec8298a480b..c9bc4c802f1 100644 --- a/src/sage/manifolds/chart.py +++ b/src/sage/manifolds/chart.py @@ -3847,7 +3847,7 @@ def set_inverse(self, *transformations, **kwds): check = kwds.pop('check', True) verbose = kwds.pop('verbose', False) for unknown_key in kwds: - raise TypeError("{} is not a valid keyword " "argument".format(unknown_key)) + raise TypeError("{} is not a valid keyword argument".format(unknown_key)) self._inverse = type(self)(self._chart2, self._chart1, *transformations) self._inverse._inverse = self if check: @@ -3875,7 +3875,7 @@ def set_inverse(self, *transformations, **kwds): infos.append(" {} {}".format(eq, resu)) if any_failure: infos.append( - "NB: a failed report can reflect a mere lack of " "simplification." + "NB: a failed report can reflect a mere lack of simplification." ) if verbose or any_failure: for li in infos: From 18490a349b3da492a3267122de4ef6d92fdfba44 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Tue, 24 Dec 2024 23:31:57 +0900 Subject: [PATCH 42/69] Fix release creation --- .github/workflows/dist.yml | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index 538b44d1431..9888f2f1095 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -119,10 +119,38 @@ jobs: with: name: dist path: dist - - uses: softprops/action-gh-release@v2 + - name: Create release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + latest_release_tag=$(curl -s https://api.github.com/repos/${{ github.repository }}/releases \ + | jq -r 'sort_by(.created_at) | last(.[]).tag_name') + + release_notes=$(curl -s \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository }}/releases/generate-notes \ + -d "{ + \"tag_name\": \"${{ github.ref_name }}\", + \"previous_tag_name\": \"$latest_release_tag\" + }" | jq -r '.body') + + curl -L \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository }}/releases \ + -d "{ + \"tag_name\": \"${{ github.ref_name }}\", + \"prerelease\": ${{ contains(github.ref, 'beta') || contains(github.ref, 'rc') }}, + \"body\": \"$release_notes\" + }" + - name: Create release assets + uses: softprops/action-gh-release@v2 with: - generate_release_notes: true - prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'rc') }} files: | dist/* upstream/* From 28ef7538ff38548df3f403bcccf74cee4134ac65 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 25 Dec 2024 04:23:11 +0900 Subject: [PATCH 43/69] Remove empty lines --- .github/workflows/dist.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index 9888f2f1095..191fd1c8fad 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -125,7 +125,6 @@ jobs: run: | latest_release_tag=$(curl -s https://api.github.com/repos/${{ github.repository }}/releases \ | jq -r 'sort_by(.created_at) | last(.[]).tag_name') - release_notes=$(curl -s \ -X POST \ -H "Accept: application/vnd.github+json" \ @@ -136,7 +135,6 @@ jobs: \"tag_name\": \"${{ github.ref_name }}\", \"previous_tag_name\": \"$latest_release_tag\" }" | jq -r '.body') - curl -L \ -X POST \ -H "Accept: application/vnd.github+json" \ From d1166e1b1bab973ca831397ef77c4fd05ca7445d Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 27 Dec 2024 17:26:14 +0700 Subject: [PATCH 44/69] Apply suggestion Co-authored-by: Martin Rubey --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 961cb40d751..3f963e28cb7 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -432,9 +432,8 @@ cdef class MPolynomialRing_base(CommutativeRing): Also, if the solution is not unique, it spits out one solution, without any notice that there are more. - Lastly, the interpolation function for univariate polynomial rings, - :meth:`~sage.rings.polynomial.polynomial_ring.PolynomialRing_field.lagrange_polynomial`, - is called. + For interpolation in the univariate case use + :meth:`~sage.rings.polynomial.polynomial_ring.PolynomialRing_field.lagrange_polynomial`. .. WARNING:: From 363217b367db5b7d1d32103286f5c1df78dc0c84 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 27 Dec 2024 11:23:21 +0000 Subject: [PATCH 45/69] Pytest: Improve doctest integration --- .gitignore | 1 - .vscode/settings.json | 4 +- conftest.py | 347 +++++++++++++++++++ pyproject.toml | 9 + src/conftest.py | 184 ---------- src/sage/doctest/forker.py | 52 +-- src/sage/repl/rich_output/display_manager.py | 17 +- src/sage/repl/user_globals.py | 2 +- src/tox.ini | 8 - 9 files changed, 400 insertions(+), 224 deletions(-) create mode 100644 conftest.py delete mode 100644 src/conftest.py diff --git a/.gitignore b/.gitignore index 323d81b557b..60ea5f51490 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ /config.log /config.status /configure -/conftest* /confdefs.h /m4/sage_spkg_configures.m4 diff --git a/.vscode/settings.json b/.vscode/settings.json index c38aafb376d..b4a993ff7f3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,9 +18,7 @@ }, "python.testing.pytestEnabled": true, "python.testing.pytestArgs": [ - "--rootdir=src/sage", - "-c=src/tox.ini", - "--doctest-modules" + "--doctest" ], "python.testing.unittestEnabled": false, "cSpell.words": [ diff --git a/conftest.py b/conftest.py new file mode 100644 index 00000000000..5307d7f6233 --- /dev/null +++ b/conftest.py @@ -0,0 +1,347 @@ +# pyright: strict +"""Configuration and fixtures for pytest. + +This file configures pytest and provides some global fixtures. +See https://docs.pytest.org/en/latest/index.html for more details. +""" + +from __future__ import annotations + +import doctest +import inspect +import sys +import warnings +from pathlib import Path +from typing import Any, Iterable, Optional + +import pytest +from _pytest.doctest import ( + DoctestItem, + DoctestModule, + _get_continue_on_failure, + _get_runner, + _is_mocked, + _patch_unwrap_mock_aware, + get_optionflags, +) +from _pytest.pathlib import ImportMode, import_path + +from sage.doctest.forker import ( + init_sage, + showwarning_with_traceback, +) +from sage.doctest.parsing import SageDocTestParser, SageOutputChecker + + +class SageDoctestModule(DoctestModule): + """ + This is essentially a copy of `DoctestModule` from + https://github.com/pytest-dev/pytest/blob/main/src/_pytest/doctest.py. + The only change is that we use `SageDocTestParser` to extract the doctests + and `SageOutputChecker` to verify the output. + """ + + def collect(self) -> Iterable[DoctestItem]: + import doctest + + class MockAwareDocTestFinder(doctest.DocTestFinder): + """A hackish doctest finder that overrides stdlib internals to fix a stdlib bug. + https://github.com/pytest-dev/pytest/issues/3456 + https://bugs.python.org/issue25532 + """ + + def __init__(self) -> None: + super().__init__(parser=SageDocTestParser(set(["sage"]))) + + def _find_lineno(self, obj, source_lines): + """Doctest code does not take into account `@property`, this + is a hackish way to fix it. https://bugs.python.org/issue17446 + Wrapped Doctests will need to be unwrapped so the correct + line number is returned. This will be reported upstream. #8796 + """ + if isinstance(obj, property): + obj = getattr(obj, "fget", obj) + + if hasattr(obj, "__wrapped__"): + # Get the main obj in case of it being wrapped + obj = inspect.unwrap(obj) + + # Type ignored because this is a private function. + return super()._find_lineno( # type:ignore[misc] + obj, + source_lines, + ) + + def _find( + self, tests, obj, name, module, source_lines, globs, seen + ) -> None: + if _is_mocked(obj): + return + with _patch_unwrap_mock_aware(): + # Type ignored because this is a private function. + super()._find( # type:ignore[misc] + tests, obj, name, module, source_lines, globs, seen + ) + + if self.path.name == "conftest.py": + module = self.config.pluginmanager._importconftest( + self.path, + self.config.getoption("importmode"), + rootpath=self.config.rootpath, + consider_namespace_packages=True, + ) + else: + try: + module = import_path( + self.path, + mode=ImportMode.importlib, + root=self.config.rootpath, + consider_namespace_packages=True, + ) + except ImportError as exception: + if self.config.getvalue("doctest_ignore_import_errors"): + pytest.skip("unable to import module %r" % self.path) + else: + if isinstance(exception, ModuleNotFoundError): + # Ignore some missing features/modules for now + # TODO: Remove this once all optional things are using Features + if exception.name in ( + "valgrind", + "rpy2", + "sage.libs.coxeter3.coxeter", + ): + pytest.skip( + f"unable to import module { self.path } due to missing feature { exception.name }" + ) + raise + # Uses internal doctest module parsing mechanism. + finder = MockAwareDocTestFinder() + optionflags = get_optionflags(self.config) + from sage.features import FeatureNotPresentError + + runner = _get_runner( + verbose=False, + optionflags=optionflags, + checker=SageOutputChecker(), + continue_on_failure=_get_continue_on_failure(self.config), + ) + try: + for test in finder.find(module, module.__name__): + if test.examples: # skip empty doctests + yield DoctestItem.from_parent( + self, name=test.name, runner=runner, dtest=test + ) + except FeatureNotPresentError as exception: + pytest.skip( + f"unable to import module { self.path } due to missing feature { exception.feature.name }" + ) + except ModuleNotFoundError as exception: + # TODO: Remove this once all optional things are using Features + pytest.skip( + f"unable to import module { self.path } due to missing module { exception.name }" + ) + + +class IgnoreCollector(pytest.Collector): + """ + Ignore a file. + """ + + def __init__(self, parent: pytest.Collector) -> None: + super().__init__("ignore", parent) + + def collect(self) -> Iterable[pytest.Item | pytest.Collector]: + return [] + + +def pytest_collect_file( + file_path: Path, parent: pytest.Collector +) -> pytest.Collector | None: + """ + This hook is called when collecting test files, and can be used to + modify the file or test selection logic by returning a list of + ``pytest.Item`` objects which the ``pytest`` command will directly + add to the list of test items. + + See `pytest documentation `_. + """ + if ( + file_path.parent.name == "combinat" + or file_path.parent.parent.name == "combinat" + ): + # Crashes CI for some reason + return IgnoreCollector.from_parent(parent) + if file_path.suffix == ".pyx": + # We don't allow pytests to be defined in Cython files. + # Normally, Cython files are filtered out already by pytest and we only + # hit this here if someone explicitly runs `pytest some_file.pyx`. + return IgnoreCollector.from_parent(parent) + elif file_path.suffix == ".py": + if parent.config.option.doctest: + if file_path.name == "__main__.py" or file_path.name == "setup.py": + # We don't allow tests to be defined in __main__.py/setup.py files (because their import will fail). + return IgnoreCollector.from_parent(parent) + if ( + ( + file_path.name == "postprocess.py" + and file_path.parent.name == "nbconvert" + ) + or ( + file_path.name == "giacpy-mkkeywords.py" + and file_path.parent.name == "autogen" + ) + or ( + file_path.name == "flint_autogen.py" + and file_path.parent.name == "autogen" + ) + ): + # This is an executable file. + return IgnoreCollector.from_parent(parent) + + if file_path.name == "conftest_inputtest.py": + # This is an input file for testing the doctest machinery (and contains broken doctests). + return IgnoreCollector.from_parent(parent) + + if ( + ( + file_path.name == "finite_dimensional_lie_algebras_with_basis.py" + and file_path.parent.name == "categories" + ) + or ( + file_path.name == "__init__.py" + and file_path.parent.name == "crypto" + ) + or (file_path.name == "__init__.py" and file_path.parent.name == "mq") + ): + # TODO: Fix these (import fails with "RuntimeError: dictionary changed size during iteration") + return IgnoreCollector.from_parent(parent) + + if ( + file_path.name in ("forker.py", "reporting.py") + ) and file_path.parent.name == "doctest": + # Fails with many errors due to different testing framework + return IgnoreCollector.from_parent(parent) + + if ( + ( + file_path.name == "arithgroup_generic.py" + and file_path.parent.name == "arithgroup" + ) + or ( + file_path.name == "pari.py" + and file_path.parent.name == "lfunctions" + ) + or ( + file_path.name == "permgroup_named.py" + and file_path.parent.name == "perm_gps" + ) + or ( + file_path.name == "finitely_generated.py" + and file_path.parent.name == "matrix_gps" + ) + or ( + file_path.name == "libgap_mixin.py" + and file_path.parent.name == "groups" + ) + or ( + file_path.name == "finitely_presented.py" + and file_path.parent.name == "groups" + ) + or ( + file_path.name == "classical_geometries.py" + and file_path.parent.name == "generators" + ) + ): + # Fails with "Fatal Python error" + return IgnoreCollector.from_parent(parent) + + return SageDoctestModule.from_parent(parent, path=file_path) + + +def pytest_addoption(parser): + # Add a command line option to run doctests + # (we don't use the built-in --doctest-modules option because then doctests are collected twice) + group = parser.getgroup("collect") + group.addoption( + "--doctest", + action="store_true", + default=False, + help="Run doctests in all .py modules", + dest="doctest", + ) + + +# Monkey patch exception printing to replace the full qualified name of the exception by its short name +# TODO: Remove this hack once migration to pytest is complete +import traceback + +old_format_exception_only = traceback.format_exception_only + + +def format_exception_only(etype: type, value: BaseException) -> list[str]: + formatted_exception = old_format_exception_only(etype, value) + exception_name = etype.__name__ + if etype.__module__: + exception_full_name = etype.__module__ + "." + etype.__qualname__ + else: + exception_full_name = etype.__qualname__ + + for i, line in enumerate(formatted_exception): + if line.startswith(exception_full_name): + formatted_exception[i] = line.replace( + exception_full_name, exception_name, 1 + ) + return formatted_exception + + +# Initialize Sage-specific doctest stuff +init_sage() + +# Monkey patch doctest to use our custom printer etc +old_run = doctest.DocTestRunner.run + + +def doctest_run( + self: doctest.DocTestRunner, + test: doctest.DocTest, + compileflags: Optional[int] = None, + out: Any = None, + clear_globs: bool = True, +) -> doctest.TestResults: + from sage.repl.rich_output import get_display_manager + from sage.repl.user_globals import set_globals + + traceback.format_exception_only = format_exception_only + + # Display warnings in doctests + warnings.showwarning = showwarning_with_traceback + setattr(sys, "__displayhook__", get_display_manager().displayhook) + + # Ensure that injecting globals works as expected in doctests + set_globals(test.globs) + return old_run(self, test, compileflags, out, clear_globs) + + +doctest.DocTestRunner.run = doctest_run + + +@pytest.fixture(autouse=True, scope="session") +def add_imports(doctest_namespace: dict[str, Any]): + """ + Add global imports for doctests. + + See `pytest documentation `. + """ + # Inject sage.all into each doctest + import sage.repl.ipython_kernel.all_jupyter + + dict_all = sage.repl.ipython_kernel.all_jupyter.__dict__ + + # Remove '__package__' item from the globals since it is not + # always in the globals in an actual Sage session. + dict_all.pop("__package__", None) + + sage_namespace = dict(dict_all) + sage_namespace["__name__"] = "__main__" + + doctest_namespace.update(**sage_namespace) diff --git a/pyproject.toml b/pyproject.toml index da06db03649..e2b17964399 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,6 +94,15 @@ platforms = [ 'osx-64', 'linux-64', 'linux-aarch64', 'osx-arm64' ] +[tool.pytest.ini_options] +python_files = "*_test.py" +norecursedirs = "local prefix venv build builddir pkgs .git src/doc src/bin src/sage_setup/autogen/flint tools" +# The "no:warnings" is to stop pytest from capturing warnings so that they are printed to the output of the doctest +addopts = "--import-mode importlib -p no:warnings" +doctest_optionflags = "NORMALIZE_WHITESPACE ELLIPSIS" +# https://docs.pytest.org/en/stable/reference/reference.html#confval-consider_namespace_packages +consider_namespace_packages = true + # External dependencies in the format proposed by https://peps.python.org/pep-0725 [external] build-requires = [ diff --git a/src/conftest.py b/src/conftest.py deleted file mode 100644 index 951d2fddfad..00000000000 --- a/src/conftest.py +++ /dev/null @@ -1,184 +0,0 @@ -# pyright: strict -"""Configuration and fixtures for pytest. - -This file configures pytest and provides some global fixtures. -See https://docs.pytest.org/en/latest/index.html for more details. -""" - -from __future__ import annotations - -import inspect -from pathlib import Path -from typing import Any, Iterable - -import pytest -from _pytest.doctest import ( - DoctestItem, - DoctestModule, - _get_continue_on_failure, - _get_runner, - _is_mocked, - _patch_unwrap_mock_aware, - get_optionflags, -) -from _pytest.pathlib import ImportMode, import_path -from sage.doctest.parsing import SageDocTestParser, SageOutputChecker - - -class SageDoctestModule(DoctestModule): - """ - This is essentially a copy of `DoctestModule` from - https://github.com/pytest-dev/pytest/blob/main/src/_pytest/doctest.py. - The only change is that we use `SageDocTestParser` to extract the doctests - and `SageOutputChecker` to verify the output. - """ - - def collect(self) -> Iterable[DoctestItem]: - import doctest - - class MockAwareDocTestFinder(doctest.DocTestFinder): - """A hackish doctest finder that overrides stdlib internals to fix a stdlib bug. - https://github.com/pytest-dev/pytest/issues/3456 - https://bugs.python.org/issue25532 - """ - - def __init__(self) -> None: - super().__init__(parser=SageDocTestParser(set(["sage"]))) - - def _find_lineno(self, obj, source_lines): - """Doctest code does not take into account `@property`, this - is a hackish way to fix it. https://bugs.python.org/issue17446 - Wrapped Doctests will need to be unwrapped so the correct - line number is returned. This will be reported upstream. #8796 - """ - if isinstance(obj, property): - obj = getattr(obj, "fget", obj) - - if hasattr(obj, "__wrapped__"): - # Get the main obj in case of it being wrapped - obj = inspect.unwrap(obj) - - # Type ignored because this is a private function. - return super()._find_lineno( # type:ignore[misc] - obj, - source_lines, - ) - - def _find( - self, tests, obj, name, module, source_lines, globs, seen - ) -> None: - if _is_mocked(obj): - return - with _patch_unwrap_mock_aware(): - - # Type ignored because this is a private function. - super()._find( # type:ignore[misc] - tests, obj, name, module, source_lines, globs, seen - ) - - if self.path.name == "conftest.py": - module = self.config.pluginmanager._importconftest( - self.path, - self.config.getoption("importmode"), - rootpath=self.config.rootpath, - ) - else: - try: - module = import_path( - self.path, - mode=ImportMode.importlib, - root=self.config.rootpath, - consider_namespace_packages=True, - ) - except ImportError: - if self.config.getvalue("doctest_ignore_import_errors"): - pytest.skip("unable to import module %r" % self.path) - else: - raise - # Uses internal doctest module parsing mechanism. - finder = MockAwareDocTestFinder() - optionflags = get_optionflags(self.config) - runner = _get_runner( - verbose=False, - optionflags=optionflags, - checker=SageOutputChecker(), - continue_on_failure=_get_continue_on_failure(self.config), - ) - - for test in finder.find(module, module.__name__): - if test.examples: # skip empty doctests - yield DoctestItem.from_parent( - self, name=test.name, runner=runner, dtest=test - ) - - -class IgnoreCollector(pytest.Collector): - """ - Ignore a file. - """ - def __init__(self, parent: pytest.Collector) -> None: - super().__init__('ignore', parent) - - def collect(self) -> Iterable[pytest.Item | pytest.Collector]: - return [] - - -def pytest_collect_file( - file_path: Path, parent: pytest.Collector -) -> pytest.Collector | None: - """ - This hook is called when collecting test files, and can be used to - modify the file or test selection logic by returning a list of - ``pytest.Item`` objects which the ``pytest`` command will directly - add to the list of test items. - - See `pytest documentation `_. - """ - if file_path.suffix == ".pyx": - # We don't allow pytests to be defined in Cython files. - # Normally, Cython files are filtered out already by pytest and we only - # hit this here if someone explicitly runs `pytest some_file.pyx`. - return IgnoreCollector.from_parent(parent) - elif file_path.suffix == ".py": - if parent.config.option.doctest: - if file_path.name == "__main__.py": - # We don't allow tests to be defined in __main__.py files (because their import will fail). - return IgnoreCollector.from_parent(parent) - if file_path.name == "postprocess.py" and file_path.parent.name == "nbconvert": - # This is an executable file. - return IgnoreCollector.from_parent(parent) - return SageDoctestModule.from_parent(parent, path=file_path) - - -def pytest_addoption(parser): - # Add a command line option to run doctests - # (we don't use the built-in --doctest-modules option because then doctests are collected twice) - group = parser.getgroup("collect") - group.addoption( - "--doctest", - action="store_true", - default=False, - help="Run doctests in all .py modules", - dest="doctest", - ) - - -@pytest.fixture(autouse=True, scope="session") -def add_imports(doctest_namespace: dict[str, Any]): - """ - Add global imports for doctests. - - See `pytest documentation `. - """ - # Inject sage.all into each doctest - import sage.all - dict_all = sage.all.__dict__ - - # Remove '__package__' item from the globals since it is not - # always in the globals in an actual Sage session. - dict_all.pop("__package__", None) - - sage_namespace = dict(dict_all) - sage_namespace["__name__"] = "__main__" - - doctest_namespace.update(**sage_namespace) diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index bf6d49906de..ded98333f41 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -45,38 +45,48 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from __future__ import annotations - +import doctest +import errno +import gc +import hashlib +import linecache +import multiprocessing import os import platform +import re +import signal import sys +import tempfile import time -import signal -import linecache -import hashlib -import multiprocessing -import warnings -import re -import errno -import doctest import traceback -import tempfile +import typing +import warnings from collections import defaultdict from dis import findlinestarts from queue import Empty -import gc + import IPython.lib.pretty -import sage.misc.randstate as randstate -from sage.misc.timing import walltime -from .util import Timer, RecordingDict, count_noun -from .sources import DictAsObject -from .parsing import OriginalSource, reduce_hex -from sage.structure.sage_object import SageObject -from .parsing import SageOutputChecker, pre_hash, get_source, unparse_optional_tags -from sage.repl.user_globals import set_globals from sage.cpython.atexit import restore_atexit from sage.cpython.string import bytes_to_str, str_to_bytes +from sage.doctest.parsing import ( + OriginalSource, + SageOutputChecker, + get_source, + pre_hash, + reduce_hex, + unparse_optional_tags, +) +from sage.doctest.sources import DictAsObject +from sage.doctest.util import RecordingDict, Timer, count_noun +from sage.misc import randstate +from sage.repl.user_globals import set_globals +from sage.structure.sage_object import SageObject + +if typing.TYPE_CHECKING: + from sage.doctest.control import DocTestController # With OS X, Python 3.8 defaults to use 'spawn' instead of 'fork' in # multiprocessing, and Sage doctesting doesn't work with 'spawn'. See @@ -113,7 +123,7 @@ def inner(obj, p, cycle): return inner -def init_sage(controller=None): +def init_sage(controller: DocTestController | None = None) -> None: """ Import the Sage library. @@ -1710,7 +1720,7 @@ class DocTestDispatcher(SageObject): Create parallel :class:`DocTestWorker` processes and dispatches doctesting tasks. """ - def __init__(self, controller): + def __init__(self, controller: DocTestController): """ INPUT: diff --git a/src/sage/repl/rich_output/display_manager.py b/src/sage/repl/rich_output/display_manager.py index 2d1be377cad..61ea74ef30b 100644 --- a/src/sage/repl/rich_output/display_manager.py +++ b/src/sage/repl/rich_output/display_manager.py @@ -32,18 +32,23 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - +from __future__ import annotations import warnings +from typing import Any + +from typing_extensions import Self -from sage.structure.sage_object import SageObject from sage.repl.rich_output.output_basic import ( - OutputPlainText, OutputAsciiArt, OutputUnicodeArt, OutputLatex, + OutputAsciiArt, + OutputPlainText, + OutputUnicodeArt, ) from sage.repl.rich_output.output_browser import ( OutputHtml, ) from sage.repl.rich_output.preferences import DisplayPreferences +from sage.structure.sage_object import SageObject class DisplayException(Exception): @@ -185,7 +190,7 @@ def __exit__(self, exception_type, value, traceback): class DisplayManager(SageObject): - _instance = None + _instance: Self | None = None def __init__(self): """ @@ -205,7 +210,7 @@ def __init__(self): self.switch_backend(BackendSimple()) @classmethod - def get_instance(cls): + def get_instance(cls) -> Self: """ Get the singleton instance. @@ -771,7 +776,7 @@ def supported_output(self): """ return self._supported_output - def displayhook(self, obj): + def displayhook(self, obj: Any) -> None | Any: """ Implementation of the displayhook. diff --git a/src/sage/repl/user_globals.py b/src/sage/repl/user_globals.py index 444c0af1405..9e2090b8224 100644 --- a/src/sage/repl/user_globals.py +++ b/src/sage/repl/user_globals.py @@ -102,7 +102,7 @@ def get_globals(): return user_globals -def set_globals(g): +def set_globals(g: dict) -> None: """ Set the dictionary of all user globals to ``g``. diff --git a/src/tox.ini b/src/tox.ini index 68a64b498d5..f7b20398939 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -376,14 +376,6 @@ exclude = sage/graphs/graph_plot.py sage/misc/sagedoc.py -[pytest] -python_files = *_test.py -norecursedirs = local prefix venv build builddir pkgs .git src/doc src/bin tools -addopts = --import-mode importlib -doctest_optionflags = NORMALIZE_WHITESPACE ELLIPSIS -# https://docs.pytest.org/en/stable/reference/reference.html#confval-consider_namespace_packages -consider_namespace_packages = True - [coverage:run] source = sage concurrency = multiprocessing,thread From af5ff8337b19ada0cf989f370102665de0c3dc75 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 27 Dec 2024 12:16:16 +0000 Subject: [PATCH 46/69] Fix docstring formatting to use raw string literals in multiple files Discovered via pytest, which follows stricter rules when parsing doctests. --- src/sage/algebras/free_algebra_quotient_element.py | 2 +- src/sage/algebras/lie_algebras/bgg_dual_module.py | 2 +- src/sage/algebras/steenrod/steenrod_algebra_misc.py | 8 ++++---- src/sage/misc/inline_fortran.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/algebras/free_algebra_quotient_element.py b/src/sage/algebras/free_algebra_quotient_element.py index b594cc65dec..640c868617f 100644 --- a/src/sage/algebras/free_algebra_quotient_element.py +++ b/src/sage/algebras/free_algebra_quotient_element.py @@ -142,7 +142,7 @@ def _repr_(self): return repr_lincomb(zip(mons, cffs), strip_one=True) def _latex_(self): - """ + r""" EXAMPLES:: sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ) diff --git a/src/sage/algebras/lie_algebras/bgg_dual_module.py b/src/sage/algebras/lie_algebras/bgg_dual_module.py index c4e060131da..854c62ea5ac 100644 --- a/src/sage/algebras/lie_algebras/bgg_dual_module.py +++ b/src/sage/algebras/lie_algebras/bgg_dual_module.py @@ -172,7 +172,7 @@ def _repr_generator(self, m): return self._module._repr_generator(m) + "^*" def _latex_generator(self, m): - """ + r""" Return a latex representation of the generator indexed by ``m``. EXAMPLES:: diff --git a/src/sage/algebras/steenrod/steenrod_algebra_misc.py b/src/sage/algebras/steenrod/steenrod_algebra_misc.py index 1bf8e278502..1aeeab27050 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_misc.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_misc.py @@ -567,7 +567,7 @@ def normalize_profile(profile, precision=None, truncation_type='auto', p=2, gene def milnor_mono_to_string(mono, latex=False, generic=False): - """ + r""" String representation of element of the Milnor basis. This is used by the _repr_ and _latex_ methods. @@ -720,7 +720,7 @@ def serre_cartan_mono_to_string(mono, latex=False, generic=False): def wood_mono_to_string(mono, latex=False): - """ + r""" String representation of element of Wood's Y and Z bases. This is used by the _repr_ and _latex_ methods. @@ -806,7 +806,7 @@ def wall_mono_to_string(mono, latex=False): def wall_long_mono_to_string(mono, latex=False): - """ + r""" Alternate string representation of element of Wall's basis. This is used by the _repr_ and _latex_ methods. @@ -891,7 +891,7 @@ def arnonA_mono_to_string(mono, latex=False, p=2): def arnonA_long_mono_to_string(mono, latex=False, p=2): - """ + r""" Alternate string representation of element of Arnon's A basis. This is used by the _repr_ and _latex_ methods. diff --git a/src/sage/misc/inline_fortran.py b/src/sage/misc/inline_fortran.py index e245249af20..85f3740d984 100644 --- a/src/sage/misc/inline_fortran.py +++ b/src/sage/misc/inline_fortran.py @@ -12,7 +12,7 @@ def _import_module_from_path(name, path=None): - """ + r""" Import the module named ``name`` by searching the given path entries (or `sys.path` by default). From cd41311d03523877a40b3be8ccdea98160fac657 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 27 Dec 2024 12:53:59 +0000 Subject: [PATCH 47/69] Switch devcontainer to use meson --- .devcontainer/onCreate-conda.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.devcontainer/onCreate-conda.sh b/.devcontainer/onCreate-conda.sh index 380592bca5c..3226b78c51d 100755 --- a/.devcontainer/onCreate-conda.sh +++ b/.devcontainer/onCreate-conda.sh @@ -10,5 +10,4 @@ mamba env create -y --file environment-3.11-linux.yml || mamba env update -y --f conda init bash # Build sage -conda run -n sage-dev ./bootstrap -conda run -n sage-dev pip install --no-build-isolation -v -v -e ./src +conda run -n sage-dev pip install --no-build-isolation -v -v -e . From 56edd953bf33442974344c85cb1268dd7dde7e0a Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 28 Dec 2024 18:33:31 +0100 Subject: [PATCH 48/69] avoid conversion in lex_M_fast --- src/sage/graphs/traversals.pyx | 56 +++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/src/sage/graphs/traversals.pyx b/src/sage/graphs/traversals.pyx index 0ce87c3ad11..40d641cfe04 100644 --- a/src/sage/graphs/traversals.pyx +++ b/src/sage/graphs/traversals.pyx @@ -69,10 +69,12 @@ from libcpp.vector cimport vector from cysignals.signals cimport sig_on, sig_off from memory_allocator cimport MemoryAllocator +from sage.graphs.base.c_graph cimport CGraph, CGraphBackend +from sage.graphs.base.static_sparse_backend cimport StaticSparseCGraph +from sage.graphs.base.static_sparse_backend cimport StaticSparseBackend from sage.graphs.base.static_sparse_graph cimport init_short_digraph from sage.graphs.base.static_sparse_graph cimport free_short_digraph from sage.graphs.base.static_sparse_graph cimport out_degree -from sage.graphs.base.c_graph cimport CGraph, CGraphBackend from sage.graphs.graph_decompositions.slice_decomposition cimport \ extended_lex_BFS @@ -753,8 +755,7 @@ def lex_M(self, triangulation=False, labels=False, initial_vertex=None, algorith - ``labels`` -- boolean (default: ``False``); whether to return the labels assigned to each vertex - - ``initial_vertex`` -- (default: ``None``) the first vertex to - consider + - ``initial_vertex`` -- (default: ``None``); the first vertex to consider - ``algorithm`` -- string (default: ``None``); one of the following algorithms: @@ -820,6 +821,18 @@ def lex_M(self, triangulation=False, labels=False, initial_vertex=None, algorith sage: g.lex_M() [6, 4, 5, 3, 2, 1] + The ordering depends on the initial vertex:: + + sage: G = graphs.HouseGraph() + sage: G.lex_M(algorithm='lex_M_slow', initial_vertex=0) + [4, 3, 2, 1, 0] + sage: G.lex_M(algorithm='lex_M_slow', initial_vertex=2) + [1, 4, 3, 0, 2] + sage: G.lex_M(algorithm='lex_M_fast', initial_vertex=0) + [4, 3, 2, 1, 0] + sage: G.lex_M(algorithm='lex_M_fast', initial_vertex=2) + [1, 4, 3, 0, 2] + TESTS: ``'lex_M_fast'`` cannot return labels:: @@ -1127,6 +1140,18 @@ def lex_M_fast(G, triangulation=False, initial_vertex=None): Traceback (most recent call last): ... ValueError: 'foo' is not a graph vertex + + Immutable graphs:: + + sage: from sage.graphs.traversals import lex_M_fast + sage: G = graphs.RandomGNP(10, .7) + sage: G._backend + + sage: H = Graph(G, immutable=True) + sage: H._backend + + sage: lex_M_fast(G) == lex_M_fast(H) + True """ if initial_vertex is not None and initial_vertex not in G: raise ValueError("'{}' is not a graph vertex".format(initial_vertex)) @@ -1136,16 +1161,19 @@ def lex_M_fast(G, triangulation=False, initial_vertex=None): # ==> Initialization - cdef list int_to_v = list(G) cdef int i, j, k, v, w, z - if initial_vertex is not None: - # We put the initial vertex at first place in the ordering - i = int_to_v.index(initial_vertex) - int_to_v[0], int_to_v[i] = int_to_v[i], int_to_v[0] - + cdef list int_to_v + cdef StaticSparseCGraph cg cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_v) + if isinstance(G, StaticSparseBackend): + cg = G._cg + sd = cg.g + int_to_v = cg._vertex_to_labels + else: + int_to_v = list(G) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_v) + cdef uint32_t* p_tmp cdef uint32_t* p_end @@ -1153,6 +1181,11 @@ def lex_M_fast(G, triangulation=False, initial_vertex=None): cdef list unnumbered_vertices = list(range(n)) + if initial_vertex is not None: + # We put the initial vertex at the first place + i = int_to_v.index(initial_vertex) + unnumbered_vertices[0], unnumbered_vertices[i] = unnumbered_vertices[i], unnumbered_vertices[0] + cdef MemoryAllocator mem = MemoryAllocator() cdef int* label = mem.allocarray(n, sizeof(int)) cdef int* alpha = mem.allocarray(n, sizeof(int)) @@ -1237,7 +1270,8 @@ def lex_M_fast(G, triangulation=False, initial_vertex=None): k += 2 label[w] = k - free_short_digraph(sd) + if not isinstance(G, StaticSparseBackend): + free_short_digraph(sd) cdef list ordering = [int_to_v[alpha[i]] for i in range(n)] From 02fee8f9449cba6b915fb9993263e900c6f5ac45 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 28 Dec 2024 18:38:22 +0100 Subject: [PATCH 49/69] avoid conversion in maximum_cardinality_search --- src/sage/graphs/traversals.pyx | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/traversals.pyx b/src/sage/graphs/traversals.pyx index 40d641cfe04..5f4cbae97b0 100644 --- a/src/sage/graphs/traversals.pyx +++ b/src/sage/graphs/traversals.pyx @@ -1432,17 +1432,27 @@ def maximum_cardinality_search(G, reverse=False, tree=False, initial_vertex=None if N == 1: return (list(G), DiGraph(G)) if tree else list(G) - cdef list int_to_vertex = list(G) + cdef list int_to_vertex + cdef StaticSparseCGraph cg + cdef short_digraph sd + if isinstance(G, StaticSparseBackend): + cg = G._cg + sd = cg.g + int_to_vertex = cg._vertex_to_labels + else: + int_to_vertex = list(G) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) if initial_vertex is None: initial_vertex = 0 elif initial_vertex in G: - initial_vertex = int_to_vertex.index(initial_vertex) + if isinstance(G, StaticSparseBackend): + initial_vertex = cg._vertex_to_int[initial_vertex] + else: + initial_vertex = int_to_vertex.index(initial_vertex) else: raise ValueError("vertex ({0}) is not a vertex of the graph".format(initial_vertex)) - cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) cdef uint32_t** p_vertices = sd.neighbors cdef uint32_t* p_tmp cdef uint32_t* p_end @@ -1489,7 +1499,8 @@ def maximum_cardinality_search(G, reverse=False, tree=False, initial_vertex=None pred[v] = u p_tmp += 1 - free_short_digraph(sd) + if not isinstance(G, StaticSparseBackend): + free_short_digraph(sd) if len(alpha) < N: raise ValueError("the input graph is not connected") From 97b0d9b1b98728311689eace76a317ca55f4a2ff Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 28 Dec 2024 18:43:10 +0100 Subject: [PATCH 50/69] add doctest to maximum_cardinality_search --- src/sage/graphs/traversals.pyx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/sage/graphs/traversals.pyx b/src/sage/graphs/traversals.pyx index 5f4cbae97b0..bad9247eca5 100644 --- a/src/sage/graphs/traversals.pyx +++ b/src/sage/graphs/traversals.pyx @@ -1422,6 +1422,17 @@ def maximum_cardinality_search(G, reverse=False, tree=False, initial_vertex=None Traceback (most recent call last): ... ValueError: vertex (17) is not a vertex of the graph + + Immutable graphs;: + + sage: G = graphs.RandomGNP(10, .7) + sage: G._backend + + sage: H = Graph(G, immutable=True) + sage: H._backend + + sage: G.maximum_cardinality_search() == H.maximum_cardinality_search() + True """ if tree: from sage.graphs.digraph import DiGraph From d05de5b71099c4549c3c809e680385a33a307c5c Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 28 Dec 2024 18:50:16 +0100 Subject: [PATCH 51/69] use pairing heap in maximum_cardinality_search --- src/sage/graphs/traversals.pyx | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/sage/graphs/traversals.pyx b/src/sage/graphs/traversals.pyx index bad9247eca5..abfd224752b 100644 --- a/src/sage/graphs/traversals.pyx +++ b/src/sage/graphs/traversals.pyx @@ -63,12 +63,11 @@ from collections import deque from libc.string cimport memset from libc.stdint cimport uint32_t -from libcpp.queue cimport priority_queue -from libcpp.pair cimport pair from libcpp.vector cimport vector from cysignals.signals cimport sig_on, sig_off from memory_allocator cimport MemoryAllocator +from sage.data_structures.pairing_heap cimport PairingHeap_of_n_integers from sage.graphs.base.c_graph cimport CGraph, CGraphBackend from sage.graphs.base.static_sparse_backend cimport StaticSparseCGraph from sage.graphs.base.static_sparse_backend cimport StaticSparseBackend @@ -1388,9 +1387,9 @@ def maximum_cardinality_search(G, reverse=False, tree=False, initial_vertex=None sage: G.maximum_cardinality_search(initial_vertex=0) [3, 2, 1, 0] sage: G.maximum_cardinality_search(initial_vertex=1) - [0, 3, 2, 1] + [3, 2, 0, 1] sage: G.maximum_cardinality_search(initial_vertex=2) - [0, 1, 3, 2] + [0, 3, 1, 2] sage: G.maximum_cardinality_search(initial_vertex=3) [0, 1, 2, 3] sage: G.maximum_cardinality_search(initial_vertex=3, reverse=True) @@ -1475,27 +1474,18 @@ def maximum_cardinality_search(G, reverse=False, tree=False, initial_vertex=None cdef int i, u, v for i in range(N): - weight[i] = 0 - seen[i] = False pred[i] = i - # We emulate a heap with decrease key operation using a priority queue. - # A vertex can be inserted multiple times (up to its degree), but only the - # first extraction (with maximum weight) matters. The size of the queue will - # never exceed O(m). - cdef priority_queue[pair[int, int]] pq - pq.push((0, initial_vertex)) + # We emulate a max-heap data structure using a min-heap with negative values + cdef PairingHeap_of_n_integers P = PairingHeap_of_n_integers(N) + P.push(initial_vertex, 0) # The ordering alpha is feed in reversed order and revert afterword cdef list alpha = [] - while not pq.empty(): - _, u = pq.top() - pq.pop() - if seen[u]: - # We use a lazy decrease key mode, so u can be several times in pq - continue - + while P: + u = P.top_item() + P.pop() alpha.append(int_to_vertex[u]) seen[u] = True @@ -1505,7 +1495,7 @@ def maximum_cardinality_search(G, reverse=False, tree=False, initial_vertex=None v = p_tmp[0] if not seen[v]: weight[v] += 1 - pq.push((weight[v], v)) + P.decrease(v, -weight[v]) if pred[v] == v: pred[v] = u p_tmp += 1 From 438865ccd5f05e5c68c6dc6ae194bd4c72924c3d Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 28 Dec 2024 19:03:44 +0100 Subject: [PATCH 52/69] avoid conversion in maximum_cardinality_search_M --- src/sage/graphs/traversals.pyx | 41 +++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/sage/graphs/traversals.pyx b/src/sage/graphs/traversals.pyx index abfd224752b..11cdb87c8b9 100644 --- a/src/sage/graphs/traversals.pyx +++ b/src/sage/graphs/traversals.pyx @@ -1808,16 +1808,18 @@ def maximum_cardinality_search_M(G, initial_vertex=None): Traceback (most recent call last): ... ValueError: vertex (17) is not a vertex of the graph - """ - cdef list int_to_vertex = list(G) - if initial_vertex is None: - initial_vertex = 0 - elif initial_vertex in G: - initial_vertex = int_to_vertex.index(initial_vertex) - else: - raise ValueError("vertex ({0}) is not a vertex of the graph".format(initial_vertex)) + Immutable graphs:: + sage: G = graphs.RandomGNP(10, .7) + sage: G._backend + + sage: H = Graph(G, immutable=True) + sage: H._backend + + sage: G.maximum_cardinality_search_M() == H.maximum_cardinality_search_M() + True + """ cdef int N = G.order() if not N: return ([], [], []) @@ -1827,8 +1829,26 @@ def maximum_cardinality_search_M(G, initial_vertex=None): # Copying the whole graph to obtain the list of neighbors quicker than by # calling out_neighbors. This data structure is well documented in the # module sage.graphs.base.static_sparse_graph + cdef list int_to_vertex + cdef StaticSparseCGraph cg cdef short_digraph sd - init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) + if isinstance(G, StaticSparseBackend): + cg = G._cg + sd = cg.g + int_to_vertex = cg._vertex_to_labels + else: + int_to_vertex = list(G) + init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex) + + if initial_vertex is None: + initial_vertex = 0 + elif initial_vertex in G: + if isinstance(G, StaticSparseBackend): + initial_vertex = cg._vertex_to_int[initial_vertex] + else: + initial_vertex = int_to_vertex.index(initial_vertex) + else: + raise ValueError("vertex ({0}) is not a vertex of the graph".format(initial_vertex)) cdef MemoryAllocator mem = MemoryAllocator() cdef int* alpha = mem.calloc(N, sizeof(int)) @@ -1840,7 +1860,8 @@ def maximum_cardinality_search_M(G, initial_vertex=None): maximum_cardinality_search_M_short_digraph(sd, initial_vertex, alpha, alpha_inv, F, X) sig_off() - free_short_digraph(sd) + if not isinstance(G, StaticSparseBackend): + free_short_digraph(sd) cdef int u, v return ([int_to_vertex[alpha[u]] for u in range(N)], From f40fe2a10137b33db83c9682d4516e4785845d34 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 29 Dec 2024 15:03:37 +0700 Subject: [PATCH 53/69] Faster conversion from numpy array to matrix mod 2 --- src/sage/matrix/matrix_mod2_dense.pyx | 19 ++++++++++++++- src/sage/modules/numpy_util.pxd | 3 +++ src/sage/modules/numpy_util.pyx | 33 +++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix_mod2_dense.pyx b/src/sage/matrix/matrix_mod2_dense.pyx index 55f39acf67f..f7d06f2fafa 100644 --- a/src/sage/matrix/matrix_mod2_dense.pyx +++ b/src/sage/matrix/matrix_mod2_dense.pyx @@ -108,7 +108,7 @@ from cysignals.memory cimport check_malloc, sig_free from cysignals.signals cimport sig_on, sig_str, sig_off cimport sage.matrix.matrix_dense as matrix_dense -from sage.matrix.args cimport SparseEntry, MatrixArgs_init +from sage.matrix.args cimport SparseEntry, MatrixArgs_init, MA_ENTRIES_NDARRAY from libc.stdio cimport * from sage.structure.element cimport (Matrix, Vector) from sage.modules.free_module_element cimport FreeModuleElement @@ -257,8 +257,25 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse [] sage: Matrix(GF(2),0,2) [] + + Make sure construction from numpy array is reasonably fast:: + + sage: # needs numpy + sage: import numpy as np + sage: n = 5000 + sage: M = matrix(GF(2), np.random.randint(0, 2, (n, n))) # around 700ms + + Unsupported numpy data types (slower but still works):: + + sage: # needs numpy + sage: n = 100 + sage: M = matrix(GF(2), np.random.randint(0, 2, (n, n)).astype(np.float32)) """ ma = MatrixArgs_init(parent, entries) + if ma.get_type() == MA_ENTRIES_NDARRAY: + from ..modules.numpy_util import set_matrix_mod2_from_numpy + if set_matrix_mod2_from_numpy(self, ma.entries): + return for t in ma.iter(coerce, True): se = t mzd_write_bit(self._entries, se.i, se.j, se.entry) diff --git a/src/sage/modules/numpy_util.pxd b/src/sage/modules/numpy_util.pxd index 95d84956039..8bd53e81347 100644 --- a/src/sage/modules/numpy_util.pxd +++ b/src/sage/modules/numpy_util.pxd @@ -1,5 +1,8 @@ from libc.stdint cimport uintptr_t from sage.libs.m4ri cimport * +from sage.matrix.matrix_mod2_dense cimport Matrix_mod2_dense + +cpdef int set_matrix_mod2_from_numpy(Matrix_mod2_dense a, b) except -1 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 diff --git a/src/sage/modules/numpy_util.pyx b/src/sage/modules/numpy_util.pyx index a3a90446694..30cfdefa859 100644 --- a/src/sage/modules/numpy_util.pyx +++ b/src/sage/modules/numpy_util.pyx @@ -1,12 +1,12 @@ # sage.doctest: optional - numpy +# cython: fast_getattr=False +# https://github.com/cython/cython/issues/6442 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: @@ -64,3 +64,32 @@ cpdef int set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) excep mzd_write_bit(entries, 0, i, x_bool[i]) return True return False + + +cpdef int _set_matrix_mod2_from_numpy_helper(Matrix_mod2_dense a, np.ndarray[numpy_integral, ndim=2] b) except -1: + """ + Internal function, helper for :func:`set_matrix_mod2_from_numpy`. + """ + if not (a.nrows() == b.shape[0] and a.ncols() == b.shape[1]): + raise ValueError("shape mismatch") + for i in range(b.shape[0]): + for j in range(b.shape[1]): + a.set_unsafe_int(i, j, b[i, j] & 1) + return True + + +cpdef int set_matrix_mod2_from_numpy(Matrix_mod2_dense a, b) except -1: + """ + Try to set the entries of a matrix from a numpy array. + + INPUT: + + - ``a`` -- the destination matrix + - ``b`` -- a numpy array, must have dimension 2 and the same shape as ``a`` + + OUTPUT: ``True`` if successful, ``False`` otherwise. May throw ``ValueError``. + """ + try: + return (_set_matrix_mod2_from_numpy_helper)(a, b) # https://github.com/cython/cython/issues/6588 + except TypeError: + return False From a6703f2e88cb08d466fe78f478fcdd67c916eea8 Mon Sep 17 00:00:00 2001 From: Lennard Hofmann Date: Sun, 29 Dec 2024 15:47:44 +0100 Subject: [PATCH 54/69] Remove outdated note from docstring Sage no longer sorts the output since commit 5b0c7b45f06ebee0b4a06bbe158 --- src/sage/graphs/graph.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 1e3025117df..7c640ee3c70 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -5823,12 +5823,6 @@ def cliques_maximal(self, algorithm='native'): implementation of the Bron and Kerbosch Algorithm [BK1973]_ - .. NOTE:: - - This method sorts its output before returning it. If you prefer to - save the extra time, you can call - :class:`sage.graphs.independent_sets.IndependentSets` directly. - .. NOTE:: Sage's implementation of the enumeration of *maximal* independent From 5c659630fdb007b463821362b6887f32015d7fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 30 Dec 2024 17:29:14 +0100 Subject: [PATCH 55/69] deprecate fully the auld class IntegralDomain --- .../polynomial/polynomial_quotient_ring.py | 6 +-- src/sage/rings/ring.pyx | 47 ++----------------- 2 files changed, 7 insertions(+), 46 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index 7275a122c06..115647adadf 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -34,7 +34,7 @@ # 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/ #***************************************************************************** @@ -42,7 +42,7 @@ import sage.rings.rational_field from sage.arith.misc import crt -from sage.rings.ring import Field, IntegralDomain, CommutativeRing +from sage.rings.ring import Field, CommutativeRing from sage.misc.cachefunc import cached_method from sage.rings.polynomial.polynomial_quotient_ring_element import PolynomialQuotientRingElement @@ -2277,7 +2277,7 @@ def _richcmp_(self, other, op): return richcmp(self.parent(), other.parent(), op) -class PolynomialQuotientRing_domain(PolynomialQuotientRing_generic, IntegralDomain): +class PolynomialQuotientRing_domain(PolynomialQuotientRing_generic, CommutativeRing): """ EXAMPLES:: diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index 36b84c399fe..bd95cd3e075 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -23,7 +23,7 @@ The class inheritance hierarchy is: - :class:`NoetherianRing` (deprecated and essentially removed) - :class:`CommutativeAlgebra` (deprecated and essentially removed) - - :class:`IntegralDomain` (deprecated) + - :class:`IntegralDomain` (deprecated and essentially removed) - :class:`DedekindDomain` (deprecated and essentially removed) - :class:`PrincipalIdealDomain` (deprecated and essentially removed) @@ -954,50 +954,11 @@ cdef class CommutativeRing(Ring): cdef class IntegralDomain(CommutativeRing): - """ - Generic integral domain class. - - This class is deprecated. Please use the - :class:`sage.categories.integral_domains.IntegralDomains` - category instead. - """ _default_category = IntegralDomains() - def __init__(self, base_ring, names=None, normalize=True, category=None): - """ - Initialize ``self``. - - INPUT: - - - ``category`` -- (default: ``None``) a category, or ``None`` - - This method is used by all the abstract subclasses of - :class:`IntegralDomain`, like :class:`Field`, ... in order to - avoid cascade calls Field.__init__ -> - IntegralDomain.__init__ -> - ... - - EXAMPLES:: - - sage: F = IntegralDomain(QQ) - sage: F.category() - Category of integral domains - - sage: F = Field(QQ) - sage: F.category() - Category of fields - - The default value for the category is specified by the class - attribute ``default_category``:: - - sage: IntegralDomain._default_category - Category of integral domains - - sage: Field._default_category - Category of fields - """ - CommutativeRing.__init__(self, base_ring, names=names, normalize=normalize, - category=category) + def __init__(self, *args, **kwds): + deprecation(37234, "use the category IntegralDomains") + super().__init__(*args, **kwds) cdef class NoetherianRing(CommutativeRing): From 813a84fada7981a0323f51a8835a9d34040826ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 30 Dec 2024 17:31:08 +0100 Subject: [PATCH 56/69] fix the deprecation number --- src/sage/rings/ring.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index bd95cd3e075..0891853efba 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -957,7 +957,7 @@ cdef class IntegralDomain(CommutativeRing): _default_category = IntegralDomains() def __init__(self, *args, **kwds): - deprecation(37234, "use the category IntegralDomains") + deprecation(39227, "use the category IntegralDomains") super().__init__(*args, **kwds) From 7501d931cb1814af1b1b29edeb5c17baab26e9dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 30 Dec 2024 19:35:49 +0100 Subject: [PATCH 57/69] fixing pycodestyle E222 in many cython files --- src/sage/coding/binary_code.pyx | 187 +++++++++++------- src/sage/combinat/designs/designs_pyx.pyx | 12 +- .../designs/evenly_distributed_sets.pyx | 14 +- .../combinat/designs/subhypergraph_search.pyx | 18 +- src/sage/combinat/integer_lists/base.pyx | 2 +- src/sage/games/sudoku_backtrack.pyx | 4 +- .../automorphism_group_canonical_label.pyx | 12 +- .../partn_ref/canonical_augmentation.pyx | 18 +- .../perm_gps/partn_ref/data_structures.pyx | 28 +-- .../perm_gps/partn_ref/double_coset.pyx | 8 +- src/sage/libs/flint/fq_nmod_mpoly.pxd | 2 +- src/sage/libs/linbox/fflas.pxd | 24 +-- src/sage/libs/singular/decl.pxd | 58 +++--- src/sage/libs/singular/function.pyx | 8 +- src/sage/libs/singular/polynomial.pyx | 4 +- src/sage/libs/singular/ring.pyx | 8 +- src/sage/libs/singular/singular.pyx | 8 +- src/sage/libs/symmetrica/symmetrica.pxi | 2 +- src/sage/matrix/args.pxd | 2 +- src/sage/matrix/matrix0.pyx | 2 +- src/sage/matrix/matrix_gf2e_dense.pyx | 8 +- src/sage/matrix/matrix_integer_dense.pyx | 14 +- src/sage/matrix/matrix_mod2_dense.pyx | 8 +- src/sage/matrix/matrix_modn_sparse.pyx | 2 +- src/sage/matrix/misc.pyx | 2 +- src/sage/modules/vector_mod2_dense.pyx | 2 +- src/sage/modules/vector_modn_dense.pyx | 2 +- src/sage/numerical/backends/glpk_backend.pyx | 4 +- src/sage/plot/plot3d/base.pyx | 4 +- src/sage/rings/complex_interval.pyx | 2 +- src/sage/rings/complex_mpc.pyx | 2 +- .../number_field_element_quadratic.pyx | 4 +- .../rings/padics/padic_generic_element.pyx | 2 +- .../multi_polynomial_libsingular.pyx | 2 +- .../polynomial/polynomial_modn_dense_ntl.pyx | 2 +- .../rings/puiseux_series_ring_element.pyx | 2 +- src/sage/stats/hmm/chmm.pyx | 2 +- src/sage/stats/time_series.pyx | 2 +- 38 files changed, 262 insertions(+), 225 deletions(-) diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index 3c73e0f7176..369a01b0fa4 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -1279,25 +1279,33 @@ cdef class OrbitPartition: nwords = (1 << nrows) self.nwords = nwords self.ncols = ncols - self.wd_parent = sig_malloc( nwords * sizeof(int) ) - self.wd_rank = sig_malloc( nwords * sizeof(int) ) - self.wd_min_cell_rep = sig_malloc( nwords * sizeof(int) ) - self.wd_size = sig_malloc( nwords * sizeof(int) ) - self.col_parent = sig_malloc( ncols * sizeof(int) ) - self.col_rank = sig_malloc( ncols * sizeof(int) ) - self.col_min_cell_rep = sig_malloc( ncols * sizeof(int) ) - self.col_size = sig_malloc( ncols * sizeof(int) ) + self.wd_parent = sig_malloc(nwords * sizeof(int)) + self.wd_rank = sig_malloc(nwords * sizeof(int)) + self.wd_min_cell_rep = sig_malloc(nwords * sizeof(int)) + self.wd_size = sig_malloc(nwords * sizeof(int)) + self.col_parent = sig_malloc(ncols * sizeof(int)) + self.col_rank = sig_malloc(ncols * sizeof(int)) + self.col_min_cell_rep = sig_malloc(ncols * sizeof(int)) + self.col_size = sig_malloc(ncols * sizeof(int)) if self.wd_parent is NULL or self.wd_rank is NULL or self.wd_min_cell_rep is NULL \ or self.wd_size is NULL or self.col_parent is NULL or self.col_rank is NULL \ or self.col_min_cell_rep is NULL or self.col_size is NULL: - if self.wd_parent is not NULL: sig_free(self.wd_parent) - if self.wd_rank is not NULL: sig_free(self.wd_rank) - if self.wd_min_cell_rep is not NULL: sig_free(self.wd_min_cell_rep) - if self.wd_size is not NULL: sig_free(self.wd_size) - if self.col_parent is not NULL: sig_free(self.col_parent) - if self.col_rank is not NULL: sig_free(self.col_rank) - if self.col_min_cell_rep is not NULL: sig_free(self.col_min_cell_rep) - if self.col_size is not NULL: sig_free(self.col_size) + if self.wd_parent is not NULL: + sig_free(self.wd_parent) + if self.wd_rank is not NULL: + sig_free(self.wd_rank) + if self.wd_min_cell_rep is not NULL: + sig_free(self.wd_min_cell_rep) + if self.wd_size is not NULL: + sig_free(self.wd_size) + if self.col_parent is not NULL: + sig_free(self.col_parent) + if self.col_rank is not NULL: + sig_free(self.col_rank) + if self.col_min_cell_rep is not NULL: + sig_free(self.col_min_cell_rep) + if self.col_size is not NULL: + sig_free(self.col_size) raise MemoryError("Memory.") for word from 0 <= word < nwords: self.wd_parent[word] = word @@ -1605,33 +1613,43 @@ cdef class PartitionStack: self.flag = (1 << (self.radix-1)) # data - self.wd_ents = sig_malloc( self.nwords * sizeof_int ) - self.wd_lvls = sig_malloc( self.nwords * sizeof_int ) - self.col_ents = sig_malloc( self.ncols * sizeof_int ) - self.col_lvls = sig_malloc( self.ncols * sizeof_int ) + self.wd_ents = sig_malloc( self.nwords * sizeof_int ) + self.wd_lvls = sig_malloc( self.nwords * sizeof_int ) + self.col_ents = sig_malloc( self.ncols * sizeof_int ) + self.col_lvls = sig_malloc( self.ncols * sizeof_int ) # scratch space - self.col_degs = sig_malloc( self.ncols * sizeof_int ) + self.col_degs = sig_malloc( self.ncols * sizeof_int ) self.col_counts = sig_malloc( self.nwords * sizeof_int ) self.col_output = sig_malloc( self.ncols * sizeof_int ) - self.wd_degs = sig_malloc( self.nwords * sizeof_int ) - self.wd_counts = sig_malloc( (self.ncols+1) * sizeof_int ) - self.wd_output = sig_malloc( self.nwords * sizeof_int ) + self.wd_degs = sig_malloc( self.nwords * sizeof_int ) + self.wd_counts = sig_malloc( (self.ncols+1) * sizeof_int ) + self.wd_output = sig_malloc( self.nwords * sizeof_int ) if self.wd_ents is NULL or self.wd_lvls is NULL or self.col_ents is NULL \ or self.col_lvls is NULL or self.col_degs is NULL or self.col_counts is NULL \ or self.col_output is NULL or self.wd_degs is NULL or self.wd_counts is NULL \ or self.wd_output is NULL: - if self.wd_ents is not NULL: sig_free(self.wd_ents) - if self.wd_lvls is not NULL: sig_free(self.wd_lvls) - if self.col_ents is not NULL: sig_free(self.col_ents) - if self.col_lvls is not NULL: sig_free(self.col_lvls) - if self.col_degs is not NULL: sig_free(self.col_degs) - if self.col_counts is not NULL: sig_free(self.col_counts) - if self.col_output is not NULL: sig_free(self.col_output) - if self.wd_degs is not NULL: sig_free(self.wd_degs) - if self.wd_counts is not NULL: sig_free(self.wd_counts) - if self.wd_output is not NULL: sig_free(self.wd_output) + if self.wd_ents is not NULL: + sig_free(self.wd_ents) + if self.wd_lvls is not NULL: + sig_free(self.wd_lvls) + if self.col_ents is not NULL: + sig_free(self.col_ents) + if self.col_lvls is not NULL: + sig_free(self.col_lvls) + if self.col_degs is not NULL: + sig_free(self.col_degs) + if self.col_counts is not NULL: + sig_free(self.col_counts) + if self.col_output is not NULL: + sig_free(self.col_output) + if self.wd_degs is not NULL: + sig_free(self.wd_degs) + if self.wd_counts is not NULL: + sig_free(self.wd_counts) + if self.wd_output is not NULL: + sig_free(self.wd_output) raise MemoryError("Memory.") nwords = self.nwords @@ -3073,40 +3091,54 @@ cdef class BinaryCodeClassifier: self.alpha_size = self.w_gamma_size + self.radix self.Phi_size = self.w_gamma_size/self.radix + 1 - self.w_gamma = sig_malloc( self.w_gamma_size * sizeof(int) ) - self.alpha = sig_malloc( self.alpha_size * sizeof(int) ) - self.Phi = sig_malloc( self.Phi_size * (self.L+1) * sizeof(unsigned int) ) - self.Omega = sig_malloc( self.Phi_size * self.L * sizeof(unsigned int) ) - self.W = sig_malloc( self.Phi_size * self.radix * 2 * sizeof(unsigned int) ) + self.w_gamma = sig_malloc( self.w_gamma_size * sizeof(int) ) + self.alpha = sig_malloc( self.alpha_size * sizeof(int) ) + self.Phi = sig_malloc( self.Phi_size * (self.L+1) * sizeof(unsigned int) ) + self.Omega = sig_malloc( self.Phi_size * self.L * sizeof(unsigned int) ) + self.W = sig_malloc( self.Phi_size * self.radix * 2 * sizeof(unsigned int) ) - self.base = sig_malloc( self.radix * sizeof(int) ) + self.base = sig_malloc( self.radix * sizeof(int) ) self.aut_gp_gens = sig_malloc( self.aut_gens_size * sizeof(int) ) - self.c_gamma = sig_malloc( self.radix * sizeof(int) ) - self.labeling = sig_malloc( self.radix * 3 * sizeof(int) ) - self.Lambda1 = sig_malloc( self.radix * 2 * sizeof(int) ) - self.Lambda2 = sig_malloc( self.radix * 2 * sizeof(int) ) - self.Lambda3 = sig_malloc( self.radix * 2 * sizeof(int) ) - self.v = sig_malloc( self.radix * 2 * sizeof(int) ) - self.e = sig_malloc( self.radix * 2 * sizeof(int) ) + self.c_gamma = sig_malloc( self.radix * sizeof(int) ) + self.labeling = sig_malloc( self.radix * 3 * sizeof(int) ) + self.Lambda1 = sig_malloc( self.radix * 2 * sizeof(int) ) + self.Lambda2 = sig_malloc( self.radix * 2 * sizeof(int) ) + self.Lambda3 = sig_malloc( self.radix * 2 * sizeof(int) ) + self.v = sig_malloc( self.radix * 2 * sizeof(int) ) + self.e = sig_malloc( self.radix * 2 * sizeof(int) ) if self.Phi is NULL or self.Omega is NULL or self.W is NULL or self.Lambda1 is NULL \ or self.Lambda2 is NULL or self.Lambda3 is NULL or self.w_gamma is NULL \ or self.c_gamma is NULL or self.alpha is NULL or self.v is NULL or self.e is NULL \ or self.aut_gp_gens is NULL or self.labeling is NULL or self.base is NULL: - if self.Phi is not NULL: sig_free(self.Phi) - if self.Omega is not NULL: sig_free(self.Omega) - if self.W is not NULL: sig_free(self.W) - if self.Lambda1 is not NULL: sig_free(self.Lambda1) - if self.Lambda2 is not NULL: sig_free(self.Lambda2) - if self.Lambda3 is not NULL: sig_free(self.Lambda3) - if self.w_gamma is not NULL: sig_free(self.w_gamma) - if self.c_gamma is not NULL: sig_free(self.c_gamma) - if self.alpha is not NULL: sig_free(self.alpha) - if self.v is not NULL: sig_free(self.v) - if self.e is not NULL: sig_free(self.e) - if self.aut_gp_gens is not NULL: sig_free(self.aut_gp_gens) - if self.labeling is not NULL: sig_free(self.labeling) - if self.base is not NULL: sig_free(self.base) + if self.Phi is not NULL: + sig_free(self.Phi) + if self.Omega is not NULL: + sig_free(self.Omega) + if self.W is not NULL: + sig_free(self.W) + if self.Lambda1 is not NULL: + sig_free(self.Lambda1) + if self.Lambda2 is not NULL: + sig_free(self.Lambda2) + if self.Lambda3 is not NULL: + sig_free(self.Lambda3) + if self.w_gamma is not NULL: + sig_free(self.w_gamma) + if self.c_gamma is not NULL: + sig_free(self.c_gamma) + if self.alpha is not NULL: + sig_free(self.alpha) + if self.v is not NULL: + sig_free(self.v) + if self.e is not NULL: + sig_free(self.e) + if self.aut_gp_gens is not NULL: + sig_free(self.aut_gp_gens) + if self.labeling is not NULL: + sig_free(self.labeling) + if self.base is not NULL: + sig_free(self.base) raise MemoryError("Memory.") def __dealloc__(self): @@ -3371,27 +3403,32 @@ cdef class BinaryCodeClassifier: self.w_gamma_size *= 2 self.alpha_size = self.w_gamma_size + self.radix self.Phi_size = self.w_gamma_size/self.radix + 1 - self.w_gamma = sig_realloc(self.w_gamma, self.w_gamma_size * sizeof(int) ) - self.alpha = sig_realloc(self.alpha, self.alpha_size * sizeof(int) ) - self.Phi = sig_realloc(self.Phi, self.Phi_size * self.L * sizeof(int) ) - self.Omega = sig_realloc(self.Omega, self.Phi_size * self.L * sizeof(int) ) - self.W = sig_realloc(self.W, self.Phi_size * self.radix * 2 * sizeof(int) ) + self.w_gamma = sig_realloc(self.w_gamma, self.w_gamma_size * sizeof(int)) + self.alpha = sig_realloc(self.alpha, self.alpha_size * sizeof(int)) + self.Phi = sig_realloc(self.Phi, self.Phi_size * self.L * sizeof(int)) + self.Omega = sig_realloc(self.Omega, self.Phi_size * self.L * sizeof(int)) + self.W = sig_realloc(self.W, self.Phi_size * self.radix * 2 * sizeof(int)) if self.w_gamma is NULL or self.alpha is NULL or self.Phi is NULL or self.Omega is NULL or self.W is NULL: - if self.w_gamma is not NULL: sig_free(self.w_gamma) - if self.alpha is not NULL: sig_free(self.alpha) - if self.Phi is not NULL: sig_free(self.Phi) - if self.Omega is not NULL: sig_free(self.Omega) - if self.W is not NULL: sig_free(self.W) + if self.w_gamma is not NULL: + sig_free(self.w_gamma) + if self.alpha is not NULL: + sig_free(self.alpha) + if self.Phi is not NULL: + sig_free(self.Phi) + if self.Omega is not NULL: + sig_free(self.Omega) + if self.W is not NULL: + sig_free(self.W) raise MemoryError("Memory.") for i from 0 <= i < self.Phi_size * self.L: self.Omega[i] = 0 word_gamma = self.w_gamma alpha = self.alpha # think of alpha as of length exactly nwords + ncols - Phi = self.Phi + Phi = self.Phi Omega = self.Omega - W = self.W - e = self.e - nu = PartitionStack(nrows, ncols) + W = self.W + e = self.e + nu = PartitionStack(nrows, ncols) Theta = OrbitPartition(nrows, ncols) # trivial case diff --git a/src/sage/combinat/designs/designs_pyx.pyx b/src/sage/combinat/designs/designs_pyx.pyx index 790111d4326..99f2d87574b 100644 --- a/src/sage/combinat/designs/designs_pyx.pyx +++ b/src/sage/combinat/designs/designs_pyx.pyx @@ -822,9 +822,9 @@ def is_quasi_difference_matrix(M, G, int k, int lmbda, int mu, int u, verbose=Fa # Width of the matrix for R in M: - if len(R)!=k: + if len(R) != k: if verbose: - print("The matrix has {} columns but k={}".format(len(R),k)) + print("The matrix has {} columns but k={}".format(len(R), k)) return False # When |G|=0 @@ -836,10 +836,10 @@ def is_quasi_difference_matrix(M, G, int k, int lmbda, int mu, int u, verbose=Fa cdef dict group_to_int = {v:i for i,v in enumerate(int_to_group)} # Allocations - cdef int ** x_minus_y = sig_malloc((n+1)*sizeof(int *)) - cdef int * x_minus_y_data = sig_malloc((n+1)*(n+1)*sizeof(int)) - cdef int * M_c = sig_malloc(k*M_nrows*sizeof(int)) - cdef int * G_seen = sig_malloc((n+1)*sizeof(int)) + cdef int ** x_minus_y = sig_malloc((n+1)*sizeof(int *)) + cdef int * x_minus_y_data = sig_malloc((n+1)*(n+1)*sizeof(int)) + cdef int * M_c = sig_malloc(k*M_nrows*sizeof(int)) + cdef int * G_seen = sig_malloc((n+1)*sizeof(int)) if (x_minus_y == NULL or x_minus_y_data == NULL or M_c == NULL or G_seen == NULL): sig_free(x_minus_y) sig_free(x_minus_y_data) diff --git a/src/sage/combinat/designs/evenly_distributed_sets.pyx b/src/sage/combinat/designs/evenly_distributed_sets.pyx index e2a4d04b561..510c73d51df 100644 --- a/src/sage/combinat/designs/evenly_distributed_sets.pyx +++ b/src/sage/combinat/designs/evenly_distributed_sets.pyx @@ -228,20 +228,20 @@ cdef class EvenlyDistributedSetsBacktracker: self.m = (q - 1) // e self.K = K - self.diff = check_calloc(q, sizeof(unsigned int *)) - self.diff[0] = check_malloc(q*q*sizeof(unsigned int)) + self.diff = check_calloc(q, sizeof(unsigned int *)) + self.diff[0] = check_malloc(q*q*sizeof(unsigned int)) for i in range(1, self.q): self.diff[i] = self.diff[i-1] + q - self.ratio = check_calloc(q, sizeof(unsigned int *)) - self.ratio[0] = check_malloc(q*q*sizeof(unsigned int)) + self.ratio = check_calloc(q, sizeof(unsigned int *)) + self.ratio[0] = check_malloc(q*q*sizeof(unsigned int)) for i in range(1, self.q): self.ratio[i] = self.ratio[i-1] + q - self.B = check_malloc(k*sizeof(unsigned int)) + self.B = check_malloc(k*sizeof(unsigned int)) self.min_orb = check_malloc(q*sizeof(unsigned int)) - self.cosets = check_malloc(e*sizeof(unsigned int)) - self.t = check_malloc(e*sizeof(unsigned int)) + self.cosets = check_malloc(e*sizeof(unsigned int)) + self.t = check_malloc(e*sizeof(unsigned int)) x = K.multiplicative_generator() list_K = [] diff --git a/src/sage/combinat/designs/subhypergraph_search.pyx b/src/sage/combinat/designs/subhypergraph_search.pyx index 82be44dcd13..6ec0048610f 100644 --- a/src/sage/combinat/designs/subhypergraph_search.pyx +++ b/src/sage/combinat/designs/subhypergraph_search.pyx @@ -178,21 +178,21 @@ cdef hypergraph h_init(int n, list H) noexcept: """ cdef int x,i cdef hypergraph h - h.n = n - h.m = len(H) - h.limbs = (n+63) // 64 # =ceil(n/64) - h.names = sig_malloc(sizeof(int)*n) - h.sets = sig_malloc(h.m*sizeof(uint64_t *)) - h.set_space = sig_calloc(h.m*(h.limbs+1),sizeof(uint64_t)) + h.n = n + h.m = len(H) + h.limbs = (n+63) // 64 # =ceil(n/64) + h.names = sig_malloc(sizeof(int)*n) + h.sets = sig_malloc(h.m*sizeof(uint64_t *)) + h.set_space = sig_calloc(h.m*(h.limbs+1),sizeof(uint64_t)) # Consistency check for S in H: for x in S: - if x<0 or x>=n: + if x < 0 or x >= n: h.n = -1 - if (h.names == NULL or - h.sets == NULL or + if (h.names == NULL or + h.sets == NULL or h.set_space == NULL or h.n == -1): h.n = -1 diff --git a/src/sage/combinat/integer_lists/base.pyx b/src/sage/combinat/integer_lists/base.pyx index d2bd5da3b92..4eaa6c51f58 100644 --- a/src/sage/combinat/integer_lists/base.pyx +++ b/src/sage/combinat/integer_lists/base.pyx @@ -83,7 +83,7 @@ cdef class IntegerListsBackend(): self.max_length = Integer(max_length) if max_length != Infinity else Infinity self.min_slope = Integer(min_slope) if min_slope != -Infinity else -Infinity - self.max_slope = Integer(max_slope) if max_slope != Infinity else Infinity + self.max_slope = Integer(max_slope) if max_slope != Infinity else Infinity self.min_part = Integer(min_part) if min_part != -Infinity else -Infinity self.max_part = Integer(max_part) if max_part != Infinity else Infinity diff --git a/src/sage/games/sudoku_backtrack.pyx b/src/sage/games/sudoku_backtrack.pyx index b9630566cf5..744bafce6be 100644 --- a/src/sage/games/sudoku_backtrack.pyx +++ b/src/sage/games/sudoku_backtrack.pyx @@ -71,7 +71,7 @@ def backtrack_all(n, puzzle): # location as row and column in square # grids are numbered similarly, in row-major order row = level // nsquare - col = level % nsquare + col = level % nsquare grid_corner = (row - (row % n))*nsquare + (col - (col % n)) grid_row = row // n grid_col = col // n @@ -141,7 +141,7 @@ def backtrack_all(n, puzzle): if available[abox][asymbol] == 0: card[abox] += 1 # move sideways in search tree to next available symbol - symbol += 1 + symbol += 1 while (symbol < nsquare) and (available[level][symbol] != 0): symbol += 1 if symbol == nsquare: diff --git a/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx b/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx index f8d9aaf2c1b..6aa7b262712 100644 --- a/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +++ b/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx @@ -529,12 +529,12 @@ cdef aut_gp_and_can_lab *get_aut_gp_and_can_lab(void *S, orbits_of_permutation = work_space.orbits_of_permutation current_indicators = work_space.int_array - first_indicators = work_space.int_array + n - permutation = work_space.int_array + 2*n - id_perm = work_space.int_array + 3*n - cells_to_refine_by = work_space.int_array + 4*n - vertices_determining_current_stack = work_space.int_array + 5*n - label_perm = work_space.int_array + 6*n + first_indicators = work_space.int_array + n + permutation = work_space.int_array + 2 * n + id_perm = work_space.int_array + 3 * n + cells_to_refine_by = work_space.int_array + 4 * n + vertices_determining_current_stack = work_space.int_array + 5 * n + label_perm = work_space.int_array + 6 * n fixed_points_of_generators = work_space.bitset_array minimal_cell_reps_of_generators = work_space.bitset_array + len_of_fp_and_mcr diff --git a/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx b/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx index 2775842c09d..6eeeb69ccbb 100644 --- a/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +++ b/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx @@ -289,15 +289,15 @@ cdef canonical_generator_data *allocate_cgd(int max_depth, int degree) noexcept: if cgd is NULL: sig_free(cgd) return NULL - cgd.object_stack = sig_malloc(max_depth * sizeof(void *)) - cgd.degree_stack = sig_malloc(max_depth * sizeof(int)) - cgd.iterator_stack = sig_malloc(max_depth * sizeof(iterator)) - cgd.aut_gp_stack = sig_malloc(max_depth * sizeof(aut_gp_and_can_lab *)) - cgd.agcl_work_spaces = sig_malloc(max_depth * sizeof(agcl_work_space *)) - cgd.dc_work_spaces = sig_malloc(max_depth * sizeof(dc_work_space *)) - cgd.ps_stack = sig_malloc(max_depth * sizeof(PartitionStack *)) - cgd.aug_stack = sig_malloc(max_depth * sizeof(void *)) - cgd.parent_stack = sig_malloc(max_depth * sizeof(void *)) + cgd.object_stack = sig_malloc(max_depth * sizeof(void *)) + cgd.degree_stack = sig_malloc(max_depth * sizeof(int)) + cgd.iterator_stack = sig_malloc(max_depth * sizeof(iterator)) + cgd.aut_gp_stack = sig_malloc(max_depth * sizeof(aut_gp_and_can_lab *)) + cgd.agcl_work_spaces = sig_malloc(max_depth * sizeof(agcl_work_space *)) + cgd.dc_work_spaces = sig_malloc(max_depth * sizeof(dc_work_space *)) + cgd.ps_stack = sig_malloc(max_depth * sizeof(PartitionStack *)) + cgd.aug_stack = sig_malloc(max_depth * sizeof(void *)) + cgd.parent_stack = sig_malloc(max_depth * sizeof(void *)) part = PS_new(degree, 1) cdef agcl_work_space *agclws = allocate_agcl_work_space(degree) cdef aut_gp_and_can_lab *output = allocate_agcl_output(degree) diff --git a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx index 214e5fda627..cd9bcee07d3 100644 --- a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx +++ b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx @@ -612,7 +612,7 @@ cdef StabilizerChain *SC_new(int n, bint init_gens=True) noexcept: return SC # first level allocations - cdef int *int_array = sig_malloc( (3*n*n + 6*n + 1) * sizeof(int) ) + cdef int *int_array = sig_malloc( (3*n*n + 6*n + 1) * sizeof(int) ) cdef int **int_ptrs = sig_calloc( 5*n, sizeof(int *) ) SC.OP_scratch = OP_new(n) # bitset_init without the MemoryError: @@ -637,21 +637,21 @@ cdef StabilizerChain *SC_new(int n, bint init_gens=True) noexcept: SC.gen_is_id.bits[limbs-1] = 0 SC.orbit_sizes = int_array - SC.num_gens = int_array + n - SC.array_size = int_array + 2*n - SC.perm_scratch = int_array + 3*n # perm_scratch is length 3*n+1 for sorting + SC.num_gens = int_array + n + SC.array_size = int_array + 2 * n + SC.perm_scratch = int_array + 3 * n # perm_scratch is length 3*n+1 for sorting int_array += 6*n + 1 SC.generators = int_ptrs - SC.gen_inverses = int_ptrs + n - SC.base_orbits = int_ptrs + 2*n - SC.parents = int_ptrs + 3*n - SC.labels = int_ptrs + 4*n + SC.gen_inverses = int_ptrs + n + SC.base_orbits = int_ptrs + 2 * n + SC.parents = int_ptrs + 3 * n + SC.labels = int_ptrs + 4 * n for i in range(n): SC.base_orbits[i] = int_array - SC.parents[i] = int_array + n - SC.labels[i] = int_array + 2*n - int_array += 3*n + SC.parents[i] = int_array + n + SC.labels[i] = int_array + 2 * n + int_array += 3 * n # second level allocations if init_gens: @@ -692,7 +692,7 @@ cdef inline int SC_realloc_gens(StabilizerChain *SC, int level, int size) noexce cdef inline void SC_dealloc(StabilizerChain *SC) noexcept: cdef int i, n if SC is not NULL: - n = SC.degree + n = SC.degree if SC.generators is not NULL: for i in range(n): sig_free(SC.generators[i]) @@ -1448,8 +1448,8 @@ def SC_test_list_perms(list L, int n, int limit, bint gap, bint limit_complain, sig_free(perm) SC_dealloc(SC) raise MemoryError - cdef int *perm2 = perm + n - cdef int *perm3 = perm + 2*n + cdef int *perm2 = perm + n + cdef int *perm3 = perm + 2 * n for Lperm in L: for i from 0 <= i < n: perm[i] = Lperm[i] diff --git a/src/sage/groups/perm_gps/partn_ref/double_coset.pyx b/src/sage/groups/perm_gps/partn_ref/double_coset.pyx index d4cedec1f3c..0ee7cf4b486 100644 --- a/src/sage/groups/perm_gps/partn_ref/double_coset.pyx +++ b/src/sage/groups/perm_gps/partn_ref/double_coset.pyx @@ -379,10 +379,10 @@ cdef int double_coset(void *S1, void *S2, PartitionStack *partition1, int *order orbits_of_subgroup = work_space.orbits_of_subgroup indicators = work_space.int_array - permutation = work_space.int_array + n - id_perm = work_space.int_array + 2*n - cells_to_refine_by = work_space.int_array + 3*n - vertices_determining_current_stack = work_space.int_array + 4*n + permutation = work_space.int_array + n + id_perm = work_space.int_array + 2 * n + cells_to_refine_by = work_space.int_array + 3 * n + vertices_determining_current_stack = work_space.int_array + 4 * n fixed_points_of_generators = work_space.bitset_array minimal_cell_reps_of_generators = work_space.bitset_array + len_of_fp_and_mcr diff --git a/src/sage/libs/flint/fq_nmod_mpoly.pxd b/src/sage/libs/flint/fq_nmod_mpoly.pxd index 3e5bb56569b..8daa198212f 100644 --- a/src/sage/libs/flint/fq_nmod_mpoly.pxd +++ b/src/sage/libs/flint/fq_nmod_mpoly.pxd @@ -93,7 +93,7 @@ cdef extern from "flint_wrap.h": void fq_nmod_mpoly_scalar_mul_fq_nmod(fq_nmod_mpoly_t A, const fq_nmod_mpoly_t B, const fq_nmod_t c, const fq_nmod_mpoly_ctx_t ctx) noexcept void fq_nmod_mpoly_make_monic(fq_nmod_mpoly_t A, const fq_nmod_mpoly_t B, const fq_nmod_mpoly_ctx_t ctx) noexcept void fq_nmod_mpoly_derivative(fq_nmod_mpoly_t A, const fq_nmod_mpoly_t B, slong var, const fq_nmod_mpoly_ctx_t ctx) noexcept - void fq_nmod_mpoly_evaluate_all_fq_nmod(fq_nmod_t ev, const fq_nmod_mpoly_t A, fq_nmod_struct * const * vals, const fq_nmod_mpoly_ctx_t ctx) noexcept + void fq_nmod_mpoly_evaluate_all_fq_nmod(fq_nmod_t ev, const fq_nmod_mpoly_t A, fq_nmod_struct * const * vals, const fq_nmod_mpoly_ctx_t ctx) noexcept void fq_nmod_mpoly_evaluate_one_fq_nmod(fq_nmod_mpoly_t A, const fq_nmod_mpoly_t B, slong var, const fq_nmod_t val, const fq_nmod_mpoly_ctx_t ctx) noexcept int fq_nmod_mpoly_compose_fq_nmod_poly(fq_nmod_poly_t A, const fq_nmod_mpoly_t B, fq_nmod_poly_struct * const * C, const fq_nmod_mpoly_ctx_t ctx) noexcept int fq_nmod_mpoly_compose_fq_nmod_mpoly(fq_nmod_mpoly_t A, const fq_nmod_mpoly_t B, fq_nmod_mpoly_struct * const * C, const fq_nmod_mpoly_ctx_t ctxB, const fq_nmod_mpoly_ctx_t ctxAC) noexcept diff --git a/src/sage/libs/linbox/fflas.pxd b/src/sage/libs/linbox/fflas.pxd index 886f5c44cfa..e8e6cd6de40 100644 --- a/src/sage/libs/linbox/fflas.pxd +++ b/src/sage/libs/linbox/fflas.pxd @@ -111,14 +111,14 @@ cdef extern from "fflas-ffpack/fflas-ffpack.h" namespace "FFPACK": size_t s, size_t* P, size_t* Q, bool transform, size_t numthreads) Modular_double.Element* Solve (Modular_double F, size_t M, - Modular_double.Element* A, size_t lda, - Modular_double.Element* x, int incx, - Modular_double.Element* b, int incb) + Modular_double.Element* A, size_t lda, + Modular_double.Element* x, int incx, + Modular_double.Element* b, int incb) Modular_double.Element* pSolve (Modular_double F, size_t M, - Modular_double.Element* A, size_t lda, - Modular_double.Element* x, int incx, - Modular_double.Element* b, int incb, size_t numthreads) + Modular_double.Element* A, size_t lda, + Modular_double.Element* x, int incx, + Modular_double.Element* b, int incb, size_t numthreads) void applyP (Modular_double F, FFLAS_SIDE s, FFLAS_TRANSPOSE tr, @@ -165,14 +165,14 @@ cdef extern from "fflas-ffpack/fflas-ffpack.h" namespace "FFPACK": size_t s, size_t* P, size_t* Q, bool transform, size_t numthreads) Modular_float.Element* Solve (Modular_float F, size_t M, - Modular_float.Element* A, size_t lda, - Modular_float.Element* x, int incx, - Modular_float.Element* b, int incb) + Modular_float.Element* A, size_t lda, + Modular_float.Element* x, int incx, + Modular_float.Element* b, int incb) Modular_float.Element* pSolve (Modular_float F, size_t M, - Modular_float.Element* A, size_t lda, - Modular_float.Element* x, int incx, - Modular_float.Element* b, int incb, size_t numthreads) + Modular_float.Element* A, size_t lda, + Modular_float.Element* x, int incx, + Modular_float.Element* b, int incb, size_t numthreads) void applyP (Modular_float F, FFLAS_SIDE s, FFLAS_TRANSPOSE tr, diff --git a/src/sage/libs/singular/decl.pxd b/src/sage/libs/singular/decl.pxd index d8c6d9a1201..3980a856368 100644 --- a/src/sage/libs/singular/decl.pxd +++ b/src/sage/libs/singular/decl.pxd @@ -131,25 +131,25 @@ cdef extern from "singular/Singular/libsingular.h": number* cfSub(number *, number *, const n_Procs_s* r) number* cfMult(number *, number *, const n_Procs_s* r) # algebraic number multiplication - number* (*cfInit)(int i, const n_Procs_s* r ) # algebraic number from int - number* (*cfInitMPZ)(mpz_t i, const n_Procs_s* r) - number* (*cfParameter)(int i, const n_Procs_s* r) - int (*cfParDeg)(number* n, const n_Procs_s* r) - int (*cfSize)(number* n, const n_Procs_s* r) - int (*cfInt)(number* n, const n_Procs_s* r) - int (*cdDivComp)(number* a,number* b, const n_Procs_s* r) - number* (*cfGetUnit)(number* a, const n_Procs_s* r) - number* (*cfExtGcd)(number* a, number* b, number* *s, number* *t , const n_Procs_s* r) + number* (*cfInit)(int i, const n_Procs_s* r ) # algebraic number from int + number* (*cfInitMPZ)(mpz_t i, const n_Procs_s* r) + number* (*cfParameter)(int i, const n_Procs_s* r) + int (*cfParDeg)(number* n, const n_Procs_s* r) + int (*cfSize)(number* n, const n_Procs_s* r) + int (*cfInt)(number* n, const n_Procs_s* r) + int (*cdDivComp)(number* a,number* b, const n_Procs_s* r) + number* (*cfGetUnit)(number* a, const n_Procs_s* r) + number* (*cfExtGcd)(number* a, number* b, number* *s, number* *t , const n_Procs_s* r) void (*cfDelete)(number **, const n_Procs_s*) - number* (*cfInpNeg)(number* a, const n_Procs_s* r) - number* (*cfInvers)(number* a, const n_Procs_s* r) - number* (*cfCopy)(number* a, const n_Procs_s* r) # deep copy of algebraic number - number* (*cfRePart)(number* a, const n_Procs_s* cf) - number* (*cfImPart)(number* a, const n_Procs_s* cf) - void (*cfWrite)(number* a, const n_Procs_s* r) - void (*cfNormalize)(number* a, const n_Procs_s* r) + number* (*cfInpNeg)(number* a, const n_Procs_s* r) + number* (*cfInvers)(number* a, const n_Procs_s* r) + number* (*cfCopy)(number* a, const n_Procs_s* r) # deep copy of algebraic number + number* (*cfRePart)(number* a, const n_Procs_s* cf) + number* (*cfImPart)(number* a, const n_Procs_s* cf) + void (*cfWrite)(number* a, const n_Procs_s* r) + void (*cfNormalize)(number* a, const n_Procs_s* r) bint (*cfDivBy)(number* a, number* b, const n_Procs_s* r) bint (*cfEqual)(number* a,number* b, const n_Procs_s* ) @@ -164,7 +164,7 @@ cdef extern from "singular/Singular/libsingular.h": mpz_ptr modBase unsigned long modExponent - #n_coeffType type + # n_coeffType type int type # polynomials @@ -209,7 +209,7 @@ cdef extern from "singular/Singular/libsingular.h": int pCompIndex # index of components unsigned long bitmask # mask for getting single exponents - n_Procs_s* cf # coefficient field/ring + n_Procs_s* cf # coefficient field/ring int ref # return total degree of p @@ -333,11 +333,11 @@ cdef extern from "singular/Singular/libsingular.h": TObject *T LObject *L LObject *B - poly* kHEdge - poly* kNoether - poly* t_kHEdge - poly* kNoetherTail() - poly* t_kNoether + poly* kHEdge + poly* kNoether + poly* t_kHEdge + poly* kNoetherTail() + poly* t_kNoether bint *NotUsedAxis bint *pairtest void *R @@ -351,10 +351,10 @@ cdef extern from "singular/Singular/libsingular.h": ctypedef struct attr "sattr": void (*Init)() - char * name - void * data - attr * next - int atyp # the type of the attribute, describes the data field + char * name + void * data + attr * next + int atyp # the type of the attribute, describes the data field void (*Print)() attr *(*Copy)() # copy all arguments @@ -374,9 +374,9 @@ cdef extern from "singular/Singular/libsingular.h": ctypedef struct leftv "sleftv": leftv *next - char *id + char *id void* data - #data is some union, so this might be very dangerous, but I am lazy now + # data is some union, so this might be very dangerous, but I am lazy now attr *attribute void (* Copy)(leftv*) void (* Init)() diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index 766eb8826e1..54b4beb3047 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -808,15 +808,15 @@ cdef class Converter(SageObject): """ Append the number ``n`` to the list. """ - cdef number *_n = sa2si(n, self._singular_ring) + cdef number *_n = sa2si(n, self._singular_ring) return self._append(_n, NUMBER_CMD) cdef leftv *append_ring(self, r) except NULL: """ Append the ring ``r`` to the list. """ - cdef ring *_r = access_singular_ring(r) - _r.ref+=1 + cdef ring *_r = access_singular_ring(r) + _r.ref += 1 return self._append(_r, RING_CMD) cdef leftv *append_matrix(self, mat) except NULL: @@ -838,7 +838,7 @@ cdef class Converter(SageObject): """ Append the integer ``n`` to the list. """ - cdef long _n = n + cdef long _n = n return self._append(_n, INT_CMD) cdef leftv *append_list(self, l) except NULL: diff --git a/src/sage/libs/singular/polynomial.pyx b/src/sage/libs/singular/polynomial.pyx index db4b2ff35e2..a6023aaa2ae 100644 --- a/src/sage/libs/singular/polynomial.pyx +++ b/src/sage/libs/singular/polynomial.pyx @@ -504,7 +504,7 @@ cdef object singular_polynomial_latex(poly *p, ring *r, object base, object late multi = multi.lstrip().rstrip() # Next determine coefficient of multinomial - c = si2sa(p_GetCoeff(p, r), r, base) + c = si2sa(p_GetCoeff(p, r), r, base) if not multi: multi = latex(c) elif c != 1: @@ -573,7 +573,7 @@ cdef long singular_polynomial_deg(poly *p, poly *x, ring *r) noexcept: if p_GetExp(x, i, r): break while p: - _deg = p_GetExp(p,i,r) + _deg = p_GetExp(p, i, r) if _deg > deg: deg = _deg p = pNext(p) diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index fa7343f8dca..1d8dd844385 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -432,7 +432,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: _cfr = rDefault( 0, ngens, _ext_names ) rComplete(_cfr, 1) - trextParam.r = _cfr + trextParam.r = _cfr _cf = nInitChar(n_transExt, &trextParam) @@ -458,7 +458,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: _cfr = rDefault( characteristic, ngens, _ext_names ) rComplete(_cfr, 1) - trextParam.r = _cfr + trextParam.r = _cfr _cf = nInitChar(n_transExt, &trextParam) @@ -483,7 +483,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: _cfr.qideal = idInit(1,1) rComplete(_cfr, 1) _cfr.qideal.m[0] = prCopyR(minpoly._poly, k._ring, _cfr) - extParam.r = _cfr + extParam.r = _cfr # _type = nRegister(n_algExt, naInitChar); _cf = nInitChar( n_algExt, &extParam) # @@ -552,7 +552,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: _cfr.qideal = idInit(1,1) rComplete(_cfr, 1) _cfr.qideal.m[0] = prCopyR(minpoly._poly, k._ring, _cfr) - extParam.r = _cfr + extParam.r = _cfr _cf = nInitChar( n_algExt, &extParam) if (_cf is NULL): diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 813765cff3d..dd1c5a35239 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -1190,7 +1190,7 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring) noexcept: ngens = elem.parent().ngens() - nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function + nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function if nMapFuncPtr is NULL: raise RuntimeError("Failed to determine nMapFuncPtr") @@ -1305,7 +1305,7 @@ cdef number *sa2si_transext_FF(object elem, ring *_ring) noexcept: ngens = elem.parent().ngens() - nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function + nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function if nMapFuncPtr is NULL: raise RuntimeError("Failed to determine nMapFuncPtr") @@ -1405,7 +1405,7 @@ cdef number *sa2si_NF(object elem, ring *_ring) noexcept: cdef nMapFunc nMapFuncPtr = NULL - nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function + nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function if nMapFuncPtr is NULL: raise RuntimeError("Failed to determine nMapFuncPtr") @@ -1432,7 +1432,7 @@ cdef number *sa2si_NF(object elem, ring *_ring) noexcept: rComplete(qqr,1) qqr.ShortOut = 0 - nMapFuncPtr = naSetMap(qqr.cf, _ring.cf) # choose correct mapping function + nMapFuncPtr = naSetMap(qqr.cf, _ring.cf) # choose correct mapping function cdef poly *_p for i from 0 <= i < len(elem): nlCoeff = nlInit2gmp( mpq_numref((elem[i]).value), mpq_denref((elem[i]).value), qqr.cf ) diff --git a/src/sage/libs/symmetrica/symmetrica.pxi b/src/sage/libs/symmetrica/symmetrica.pxi index def9544e2c6..d175de28c38 100644 --- a/src/sage/libs/symmetrica/symmetrica.pxi +++ b/src/sage/libs/symmetrica/symmetrica.pxi @@ -436,7 +436,7 @@ cdef void late_import() noexcept: prod = sage.misc.all.prod import sage.rings.polynomial.polynomial_ring_constructor - PolynomialRing = sage.rings.polynomial.polynomial_ring_constructor.PolynomialRing + PolynomialRing = sage.rings.polynomial.polynomial_ring_constructor.PolynomialRing import sage.rings.all QQ = sage.rings.all.QQ diff --git a/src/sage/matrix/args.pxd b/src/sage/matrix/args.pxd index eda2e428801..ba26cfbafbe 100644 --- a/src/sage/matrix/args.pxd +++ b/src/sage/matrix/args.pxd @@ -12,7 +12,7 @@ cdef enum entries_type: MA_FLAG_SPARSE = 0x20_00 # Sparse by default # types of input entries - MA_ENTRIES_UNKNOWN = 0 # anything + MA_ENTRIES_UNKNOWN = 0 # anything MA_ENTRIES_ZERO = 0x17_01 # zero matrix MA_ENTRIES_SCALAR = 0x17_02 # single scalar value MA_ENTRIES_SEQ_SEQ = 0x10_03 # list of lists diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 615d7ac55f7..0c04c74b4af 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -1019,7 +1019,7 @@ cdef class Matrix(sage.structure.element.Matrix): if ind < 0 or ind >= ncols: raise IndexError("matrix index out of range") elif isinstance(col_index, slice): - col_list = list(range(*col_index.indices(ncols))) + col_list = list(range(*col_index.indices(ncols))) else: if not PyIndex_Check(col_index): raise TypeError("index must be an integer") diff --git a/src/sage/matrix/matrix_gf2e_dense.pyx b/src/sage/matrix/matrix_gf2e_dense.pyx index 431be04a62b..827aa83775d 100644 --- a/src/sage/matrix/matrix_gf2e_dense.pyx +++ b/src/sage/matrix/matrix_gf2e_dense.pyx @@ -908,22 +908,22 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense): if algorithm == 'naive': sig_on() - r = mzed_echelonize_naive(self._entries, full) + r = mzed_echelonize_naive(self._entries, full) sig_off() elif algorithm == 'newton_john': sig_on() - r = mzed_echelonize_newton_john(self._entries, full) + r = mzed_echelonize_newton_john(self._entries, full) sig_off() elif algorithm == 'ple': sig_on() - r = mzed_echelonize_ple(self._entries, full) + r = mzed_echelonize_ple(self._entries, full) sig_off() elif algorithm == 'heuristic': sig_on() - r = mzed_echelonize(self._entries, full) + r = mzed_echelonize(self._entries, full) sig_off() elif algorithm == 'builtin': diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 9ea2335b297..cf4e92b0e52 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -2065,7 +2065,7 @@ cdef class Matrix_integer_dense(Matrix_dense): raise ValueError("ntl only computes HNF for square matrices of full rank.") import sage.libs.ntl.ntl_mat_ZZ - v = sage.libs.ntl.ntl_mat_ZZ.ntl_mat_ZZ(self._nrows,self._ncols) + v = sage.libs.ntl.ntl_mat_ZZ.ntl_mat_ZZ(self._nrows,self._ncols) for i from 0 <= i < self._nrows: for j from 0 <= j < self._ncols: v[i,j] = self.get_unsafe(nr-i-1,nc-j-1) @@ -4954,11 +4954,11 @@ cdef class Matrix_integer_dense(Matrix_dense): row_i = A.row(i) row_n = A.row(n) - ag = a//g - bg = b//g + ag = a // g + bg = b // g - new_top = s*row_i + t*row_n - new_bot = bg*row_i - ag*row_n + new_top = s * row_i + t * row_n + new_bot = bg * row_i - ag * row_n # OK -- now we have to make sure the top part of the matrix # but with row i replaced by @@ -5725,9 +5725,9 @@ cdef class Matrix_integer_dense(Matrix_dense): ri = nr for i from 0 <= i < nr: rj = nc - ri = ri-1 + ri -= 1 for j from 0 <= j < nc: - rj = rj-1 + rj -= 1 fmpz_init_set(fmpz_mat_entry(A._matrix, rj, ri), fmpz_mat_entry(self._matrix, i, j)) sig_off() diff --git a/src/sage/matrix/matrix_mod2_dense.pyx b/src/sage/matrix/matrix_mod2_dense.pyx index 55f39acf67f..772b7f63c83 100644 --- a/src/sage/matrix/matrix_mod2_dense.pyx +++ b/src/sage/matrix/matrix_mod2_dense.pyx @@ -1111,7 +1111,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse self.clear_cache() sig_on() - r = mzd_echelonize(self._entries, full) + r = mzd_echelonize(self._entries, full) sig_off() self.cache('in_echelon_form',True) @@ -1126,14 +1126,14 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse if 'k' in kwds: k = int(kwds['k']) - if k<1 or k>16: + if k < 1 or k > 16: raise RuntimeError("k must be between 1 and 16") k = round(k) else: k = 0 sig_on() - r = mzd_echelonize_m4ri(self._entries, full, k) + r = mzd_echelonize_m4ri(self._entries, full, k) sig_off() self.cache('in_echelon_form',True) @@ -1146,7 +1146,7 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse self.clear_cache() sig_on() - r = mzd_echelonize_pluq(self._entries, full) + r = mzd_echelonize_pluq(self._entries, full) sig_off() self.cache('in_echelon_form',True) diff --git a/src/sage/matrix/matrix_modn_sparse.pyx b/src/sage/matrix/matrix_modn_sparse.pyx index 3334744500c..33056c221ce 100644 --- a/src/sage/matrix/matrix_modn_sparse.pyx +++ b/src/sage/matrix/matrix_modn_sparse.pyx @@ -178,7 +178,7 @@ cdef class Matrix_modn_sparse(Matrix_sparse): cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j): cdef IntegerMod_int n - n = IntegerMod_int.__new__(IntegerMod_int) + n = IntegerMod_int.__new__(IntegerMod_int) IntegerMod_abstract.__init__(n, self._base_ring) n.ivalue = get_entry(&self.rows[i], j) return n diff --git a/src/sage/matrix/misc.pyx b/src/sage/matrix/misc.pyx index 5f8f834b33f..aa1602ff657 100644 --- a/src/sage/matrix/misc.pyx +++ b/src/sage/matrix/misc.pyx @@ -222,7 +222,7 @@ def matrix_rational_echelon_form_multimodular(Matrix self, height_guess=None, pr tm = verbose("height_guess = %s" % height_guess, level=2, caller_name="multimod echelon") if proof: - M = self._ncols * height_guess * height + 1 + M = self._ncols * height_guess * height + 1 else: M = height_guess + 1 diff --git a/src/sage/modules/vector_mod2_dense.pyx b/src/sage/modules/vector_mod2_dense.pyx index 19f3f07d35c..c3af2ad51f8 100644 --- a/src/sage/modules/vector_mod2_dense.pyx +++ b/src/sage/modules/vector_mod2_dense.pyx @@ -418,7 +418,7 @@ cdef class Vector_mod2_dense(free_module_element.FreeModuleElement): cdef IntegerMod_int n cdef Vector_mod2_dense r = right cdef m4ri_word tmp = 0 - n = IntegerMod_int.__new__(IntegerMod_int) + n = IntegerMod_int.__new__(IntegerMod_int) IntegerMod_abstract.__init__(n, self.base_ring()) n.ivalue = 0 cdef m4ri_word *lrow = mzd_row(self._entries, 0) diff --git a/src/sage/modules/vector_modn_dense.pyx b/src/sage/modules/vector_modn_dense.pyx index f129632bd03..936317049b3 100644 --- a/src/sage/modules/vector_modn_dense.pyx +++ b/src/sage/modules/vector_modn_dense.pyx @@ -315,7 +315,7 @@ cdef class Vector_modn_dense(free_module_element.FreeModuleElement): cdef Vector_modn_dense r = right if use_32bit_type(self._p): - n = IntegerMod_int.__new__(IntegerMod_int) + n = IntegerMod_int.__new__(IntegerMod_int) IntegerMod_abstract.__init__(n, self.base_ring()) n.ivalue = 0 for i in range(self._degree): diff --git a/src/sage/numerical/backends/glpk_backend.pyx b/src/sage/numerical/backends/glpk_backend.pyx index 6c6d8dfff90..c70ac0bb0e0 100644 --- a/src/sage/numerical/backends/glpk_backend.pyx +++ b/src/sage/numerical/backends/glpk_backend.pyx @@ -364,7 +364,7 @@ cdef class GLPKBackend(GenericBackend): cdef char * n if name is None: - n = glp_get_prob_name(self.lp) + n = glp_get_prob_name(self.lp) if n == NULL: return "" else: @@ -1446,7 +1446,7 @@ cdef class GLPKBackend(GenericBackend): ... ValueError: invalid row index 2 """ - cdef char * s + cdef char * s if index < 0 or index > (self.nrows() - 1): raise ValueError("invalid row index %d" % index) diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx index f1a9ac7c49b..687335db740 100644 --- a/src/sage/plot/plot3d/base.pyx +++ b/src/sage/plot/plot3d/base.pyx @@ -1108,8 +1108,8 @@ resolution {resolution_x:d} {resolution_y:d} {render_parameters} end_scene""".format( - #render_params.antialiasing, this only provided the default value of 8 - scene = "\n".join(sorted([t.tachyon_str() for t in self.texture_set()])), + # render_params.antialiasing, this only provided the default value of 8 + scene = "\n".join(sorted([t.tachyon_str() for t in self.texture_set()])), render_parameters = "\n".join(flatten_list(self.tachyon_repr(render_params))), viewdir1000=self._tostring(1000*vector(viewdir).normalized().n()), diff --git a/src/sage/rings/complex_interval.pyx b/src/sage/rings/complex_interval.pyx index 60bc5b5abff..c050d794055 100644 --- a/src/sage/rings/complex_interval.pyx +++ b/src/sage/rings/complex_interval.pyx @@ -249,7 +249,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): if not self.real().is_zero(): s = self.real().str(base=base, style=style) if not self.imag().is_zero(): - y = self.imag() + y = self.imag() if s: if y < 0: s += " - " diff --git a/src/sage/rings/complex_mpc.pyx b/src/sage/rings/complex_mpc.pyx index d6bcb664a49..98efcb0b27b 100644 --- a/src/sage/rings/complex_mpc.pyx +++ b/src/sage/rings/complex_mpc.pyx @@ -185,7 +185,7 @@ cpdef inline split_complex_string(string, int base=10): exponent = '[@p]' else: exponent = '@' - exponent += sign + '?' + digit + '+' + exponent += sign + '?' + digit + '+' # Warning: number, imaginary, and complex should be enclosed in parentheses # when used as regexp because of alternatives '|' diff --git a/src/sage/rings/number_field/number_field_element_quadratic.pyx b/src/sage/rings/number_field/number_field_element_quadratic.pyx index a0e90d1d63d..cc2e63ec8e7 100644 --- a/src/sage/rings/number_field/number_field_element_quadratic.pyx +++ b/src/sage/rings/number_field/number_field_element_quadratic.pyx @@ -1515,7 +1515,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): sage: (1+a)*3 # indirect doctest 3*a + 3 """ - cdef Rational c = _c + cdef Rational c = _c cdef NumberFieldElement_quadratic res = self._new() mpz_mul(res.a, self.a, mpq_numref(c.value)) mpz_mul(res.b, self.b, mpq_numref(c.value)) @@ -1532,7 +1532,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): sage: 5*(a-1/5) # indirect doctest 5*a - 1 """ - cdef Rational c = _c + cdef Rational c = _c cdef NumberFieldElement_quadratic res = self._new() mpz_mul(res.a, self.a, mpq_numref(c.value)) mpz_mul(res.b, self.b, mpq_numref(c.value)) diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index 81b164a03f9..7a103be85b3 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -115,7 +115,7 @@ cdef class pAdicGenericElement(LocalGenericElement): m = min(left.precision_absolute(), right.precision_absolute()) x_ordp = left.valuation() - left_zero = bool(x_ordp >= m) + left_zero = bool(x_ordp >= m) y_ordp = right.valuation() right_zero = bool(y_ordp >= m) # handle approximate zeros diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index d86aba9170c..adf3df1cf95 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -4050,7 +4050,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): _p = p_Head(self._poly, _ring) _n = p_GetCoeff(_p, _ring) - ret = si2sa(_n, _ring, self._parent._base) + ret = si2sa(_n, _ring, self._parent._base) p_Delete(&_p, _ring) return ret diff --git a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx index 68605382f1f..7760e5feadf 100644 --- a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx @@ -656,7 +656,7 @@ def small_roots(self, X=None, beta=1.0, epsilon=None, **kwds): for j in range( g[i].degree()+1 ): B[i,j] = g[i][j]*X**j - B = B.LLL(**kwds) + B = B.LLL(**kwds) f = sum([ZZ(B[0,i]//X**i)*x**i for i in range(B.ncols())]) R = f.roots() diff --git a/src/sage/rings/puiseux_series_ring_element.pyx b/src/sage/rings/puiseux_series_ring_element.pyx index 3533c9c4c85..6ce054b27db 100644 --- a/src/sage/rings/puiseux_series_ring_element.pyx +++ b/src/sage/rings/puiseux_series_ring_element.pyx @@ -854,7 +854,7 @@ cdef class PuiseuxSeries(AlgebraElement): sage: p.exponents() [3/4, 4/5, 5/6] """ - return [QQ(n) / self._e for n in self._l.exponents()] + return [QQ(n) / self._e for n in self._l.exponents()] def __setitem__(self, n, value): """ diff --git a/src/sage/stats/hmm/chmm.pyx b/src/sage/stats/hmm/chmm.pyx index 540f91356d0..f345f47f09b 100644 --- a/src/sage/stats/hmm/chmm.pyx +++ b/src/sage/stats/hmm/chmm.pyx @@ -1332,7 +1332,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): # the m-components of the probability. alpha_minus = alpha._values[t*N + j] / prob for m in range(M): - numer = alpha_minus * G.prob_m(obs._values[t], m) * beta._values[t*N + j] + numer = alpha_minus * G.prob_m(obs._values[t], m) * beta._values[t*N + j] mixed_gamma._values[m*T + t] = numer / P return mixed_gamma diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index edcc8e39ea1..13ab0bf6614 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -1971,7 +1971,7 @@ cdef class TimeSeries: mid = n + bin_size/2 right = n + 2*bin_size/3 - rgbcolor = 'blue' if open < close else 'red' + rgbcolor = 'blue' if open < close else 'red' p += line([(mid, low), (mid, high)], rgbcolor=rgbcolor) p += polygon([(left, open), (right, open), (right, close), (left, close)], rgbcolor=rgbcolor) From 4443d7f551e9d823e5e419b4c494d70e594d7a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 30 Dec 2024 21:04:00 +0100 Subject: [PATCH 58/69] refresh MacMahon Omega file --- src/sage/rings/polynomial/omega.py | 92 +++++++++++++++--------------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/src/sage/rings/polynomial/omega.py b/src/sage/rings/polynomial/omega.py index 797200f4e40..3877321d1d1 100644 --- a/src/sage/rings/polynomial/omega.py +++ b/src/sage/rings/polynomial/omega.py @@ -49,11 +49,12 @@ # https://www.gnu.org/licenses/ # **************************************************************************** import operator + from sage.misc.cachefunc import cached_function def MacMahonOmega(var, expression, denominator=None, op=operator.ge, - Factorization_sort=False, Factorization_simplify=True): + Factorization_sort=False, Factorization_simplify=True): r""" Return `\Omega_{\mathrm{op}}` of ``expression`` with respect to ``var``. @@ -221,33 +222,33 @@ def MacMahonOmega(var, expression, denominator=None, op=operator.ge, sage: MacMahonOmega(mu, 1, [1 - x*mu], op=operator.lt) Traceback (most recent call last): ... - NotImplementedError: At the moment, only Omega_ge is implemented. + NotImplementedError: only Omega_ge is implemented sage: MacMahonOmega(mu, 1, Factorization([(1 - x*mu, -1)])) Traceback (most recent call last): ... - ValueError: Factorization (-mu*x + 1)^-1 of the denominator - contains negative exponents. + ValueError: factorization (-mu*x + 1)^-1 of the denominator + contains negative exponents sage: MacMahonOmega(2*mu, 1, [1 - x*mu]) Traceback (most recent call last): ... - ValueError: 2*mu is not a variable. + ValueError: 2*mu is not a variable sage: MacMahonOmega(mu, 1, Factorization([(0, 2)])) Traceback (most recent call last): ... - ZeroDivisionError: Denominator contains a factor 0. + ZeroDivisionError: denominator contains a factor 0 sage: MacMahonOmega(mu, 1, [2 - x*mu]) Traceback (most recent call last): ... - NotImplementedError: Factor 2 - x*mu is not normalized. + NotImplementedError: factor 2 - x*mu is not normalized sage: MacMahonOmega(mu, 1, [1 - x*mu - mu^2]) Traceback (most recent call last): ... - NotImplementedError: Cannot handle factor 1 - x*mu - mu^2. + NotImplementedError: cannot handle factor 1 - x*mu - mu^2 :: @@ -259,12 +260,14 @@ def MacMahonOmega(var, expression, denominator=None, op=operator.ge, from sage.arith.misc import factor from sage.misc.misc_c import prod from sage.rings.integer_ring import ZZ - from sage.rings.polynomial.laurent_polynomial_ring \ - import LaurentPolynomialRing, LaurentPolynomialRing_univariate + from sage.rings.polynomial.laurent_polynomial_ring import ( + LaurentPolynomialRing, + LaurentPolynomialRing_univariate, + ) from sage.structure.factorization import Factorization if op != operator.ge: - raise NotImplementedError('At the moment, only Omega_ge is implemented.') + raise NotImplementedError('only Omega_ge is implemented') if denominator is None: if isinstance(expression, Factorization): @@ -285,9 +288,9 @@ def MacMahonOmega(var, expression, denominator=None, op=operator.ge, if not isinstance(denominator, Factorization): denominator = factor(denominator) if not denominator.is_integral(): - raise ValueError('Factorization {} of the denominator ' - 'contains negative exponents.'.format(denominator)) - numerator *= ZZ(1) / denominator.unit() + raise ValueError(f'factorization {denominator} of ' + 'the denominator contains negative exponents') + numerator *= ZZ.one() / denominator.unit() factors_denominator = tuple(factor for factor, exponent in denominator for _ in range(exponent)) @@ -304,30 +307,30 @@ def MacMahonOmega(var, expression, denominator=None, op=operator.ge, L = LaurentPolynomialRing(L0, var) var = L.gen() else: - raise ValueError('{} is not a variable.'.format(var)) + raise ValueError(f'{var} is not a variable') other_factors = [] to_numerator = [] decoded_factors = [] - for factor in factors_denominator: - factor = L(factor) - D = factor.monomial_coefficients() + for fact in factors_denominator: + fac = L(fact) + D = fac.monomial_coefficients() if not D: - raise ZeroDivisionError('Denominator contains a factor 0.') + raise ZeroDivisionError('denominator contains a factor 0') elif len(D) == 1: exponent, coefficient = next(iter(D.items())) if exponent == 0: - other_factors.append(L0(factor)) + other_factors.append(L0(fac)) else: - to_numerator.append(factor) + to_numerator.append(fac) elif len(D) == 2: if D.get(0, 0) != 1: - raise NotImplementedError('Factor {} is not normalized.'.format(factor)) + raise NotImplementedError(f'factor {fac} is not normalized') D.pop(0) exponent, coefficient = next(iter(D.items())) decoded_factors.append((-coefficient, exponent)) else: - raise NotImplementedError('Cannot handle factor {}.'.format(factor)) + raise NotImplementedError(f'cannot handle factor {fac}') numerator = L(numerator) / prod(to_numerator) result_numerator, result_factors_denominator = \ @@ -336,13 +339,13 @@ def MacMahonOmega(var, expression, denominator=None, op=operator.ge, return Factorization([], unit=result_numerator) return Factorization([(result_numerator, 1)] + - list((f, -1) for f in other_factors) + - list((1-f, -1) for f in result_factors_denominator), + [(f, -1) for f in other_factors] + + [(1 - f, -1) for f in result_factors_denominator], sort=Factorization_sort, simplify=Factorization_simplify) -def _simplify_(numerator, terms): +def _simplify_(numerator, terms) -> tuple: r""" Cancels common factors of numerator and denominator. @@ -438,7 +441,7 @@ def _Omega_(A, decoded_factors): (x + 1) * (-x*y + 1)^-1 """ if not decoded_factors: - return sum(c for a, c in A.items() if a >= 0), tuple() + return sum(c for a, c in A.items() if a >= 0), () # Below we sort to make the caching more efficient. Doing this here # (in contrast to directly in Omega_ge) results in much cleaner @@ -459,7 +462,7 @@ def _Omega_(A, decoded_factors): numerator += c * n.subs(rules) if numerator == 0: - factors_denominator = tuple() + factors_denominator = () return _simplify_(numerator, tuple(f.subs(rules) for f in factors_denominator)) @@ -557,19 +560,18 @@ def Omega_ge(a, exponents): logger.info('Omega_ge: a=%s, exponents=%s', a, exponents) from sage.arith.functions import lcm - from sage.arith.srange import srange from sage.rings.integer_ring import ZZ - from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing from sage.rings.number_field.number_field import CyclotomicField + from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing if not exponents or any(e == 0 for e in exponents): raise NotImplementedError - rou = sorted(set(abs(e) for e in exponents) - set([1])) + rou = sorted({abse for e in exponents if (abse := abs(e)) != 1}) ellcm = lcm(rou) B = CyclotomicField(ellcm, 'zeta') zeta = B.gen() - z_names = tuple('z{}'.format(i) for i in range(len(exponents))) + z_names = tuple(f'z{i}' for i in range(len(exponents))) L = LaurentPolynomialRing(B, ('t',) + z_names, len(z_names) + 1) t = L.gens()[0] Z = LaurentPolynomialRing(ZZ, z_names, len(z_names)) @@ -577,7 +579,7 @@ def Omega_ge(a, exponents): powers[2] = L(-1) powers[1] = L(1) exponents_and_values = tuple( - (e, tuple(powers[abs(e)]**j * z for j in srange(abs(e)))) + (e, tuple(powers[abs(e)]**j * z for j in range(abs(e)))) for z, e in zip(L.gens()[1:], exponents)) x = tuple(v for e, v in exponents_and_values if e > 0) y = tuple(v for e, v in exponents_and_values if e < 0) @@ -597,9 +599,8 @@ def subs_e(e): e[p] = e[p] // exponent return tuple(e) parent = expression.parent() - result = parent({subs_e(e): c - for e, c in expression.monomial_coefficients().items()}) - return result + return parent({subs_e(e): c + for e, c in expression.monomial_coefficients().items()}) def de_power(expression): expression = Z(expression) @@ -719,8 +720,8 @@ def _Omega_numerator_(a, x, y, t): from sage.arith.srange import srange from sage.misc.misc_c import prod - x_flat = sum(x, tuple()) - y_flat = sum(y, tuple()) + x_flat = sum(x, ()) + y_flat = sum(y, ()) n = len(x_flat) m = len(y_flat) xy = x_flat + y_flat @@ -807,12 +808,13 @@ def _Omega_numerator_P_(a, x, y, t): p2 = Pprev.subs({t: x2}) logger.debug('Omega_numerator: P(%s): preparing...', n) dividend = x1 * (1-x2) * prod(1 - x2*yy for yy in y) * p1 - \ - x2 * (1-x1) * prod(1 - x1*yy for yy in y) * p2 + x2 * (1-x1) * prod(1 - x1*yy for yy in y) * p2 logger.debug('Omega_numerator: P(%s): dividing...', n) q, r = dividend.quo_rem(x1 - x2) assert r == 0 result = q - logger.debug('Omega_numerator: P(%s) has %s terms', n, result.number_of_terms()) + logger.debug('Omega_numerator: P(%s) has %s terms', n, + result.number_of_terms()) return result @@ -900,11 +902,11 @@ def _Omega_factors_denominator_(x, y): from sage.misc.misc_c import prod result = tuple(prod(1 - xx for xx in gx) for gx in x) + \ - sum(((prod(1 - xx*yy for xx in gx for yy in gy),) - if len(gx) != len(gy) - else tuple(prod(1 - xx*yy for xx in gx) for yy in gy) - for gx in x for gy in y), - tuple()) + sum(((prod(1 - xx*yy for xx in gx for yy in gy),) + if len(gx) != len(gy) + else tuple(prod(1 - xx*yy for xx in gx) for yy in gy) + for gx in x for gy in y), + ()) logger.info('Omega_denominator: %s factors', len(result)) return result From bab7cd4bc933fc84f449a786459359112363dd25 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Tue, 31 Dec 2024 09:00:53 +0700 Subject: [PATCH 59/69] Add some tests for internal methods --- src/sage/modules/numpy_util.pyx | 42 ++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/sage/modules/numpy_util.pyx b/src/sage/modules/numpy_util.pyx index 30cfdefa859..a20f173a17d 100644 --- a/src/sage/modules/numpy_util.pyx +++ b/src/sage/modules/numpy_util.pyx @@ -69,6 +69,22 @@ cpdef int set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) excep cpdef int _set_matrix_mod2_from_numpy_helper(Matrix_mod2_dense a, np.ndarray[numpy_integral, ndim=2] b) except -1: """ Internal function, helper for :func:`set_matrix_mod2_from_numpy`. + + TESTS:: + + sage: from sage.modules.numpy_util import _set_matrix_mod2_from_numpy_helper + sage: import numpy as np + sage: a = matrix(GF(2), 2, 3) + sage: b = np.array([[1, 0, 1], [0, 1, 0]], dtype=np.int8) + sage: _set_matrix_mod2_from_numpy_helper(a, b) + 1 + sage: a + [1 0 1] + [0 1 0] + sage: _set_matrix_mod2_from_numpy_helper(a, np.array([[1, 0], [0, 1]], dtype=np.int8)) + Traceback (most recent call last): + ... + ValueError: shape mismatch """ if not (a.nrows() == b.shape[0] and a.ncols() == b.shape[1]): raise ValueError("shape mismatch") @@ -87,7 +103,31 @@ cpdef int set_matrix_mod2_from_numpy(Matrix_mod2_dense a, b) except -1: - ``a`` -- the destination matrix - ``b`` -- a numpy array, must have dimension 2 and the same shape as ``a`` - OUTPUT: ``True`` if successful, ``False`` otherwise. May throw ``ValueError``. + OUTPUT: ``True`` (when used as bool) if successful, ``False`` otherwise. May throw ``ValueError``. + + The exact type of the return value is not guaranteed, in the actual current implementation + it is ``1`` for success and ``0`` for failure. + + TESTS:: + + sage: from sage.modules.numpy_util import set_matrix_mod2_from_numpy + sage: import numpy as np + sage: a = matrix(GF(2), 2, 3) + sage: b = np.array([[1, 0, 1], [0, 1, 0]], dtype=np.int8) + sage: set_matrix_mod2_from_numpy(a, b) + 1 + sage: a + [1 0 1] + [0 1 0] + sage: set_matrix_mod2_from_numpy(a, np.array([[1, 0], [0, 1]], dtype=np.int8)) + Traceback (most recent call last): + ... + ValueError: shape mismatch + sage: # unsupported type (may be supported in the future) + sage: set_matrix_mod2_from_numpy(a, np.array([[1, 1, 0], [0, 1, 0]], dtype=np.float64)) + 0 + sage: set_matrix_mod2_from_numpy(a, np.array([1, 0, 0], dtype=np.int8)) # wrong number of dimensions + 0 """ try: return (_set_matrix_mod2_from_numpy_helper)(a, b) # https://github.com/cython/cython/issues/6588 From 9432af7528a40d2cff9436a2b26bd6c78d12e1ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 31 Dec 2024 11:05:15 +0100 Subject: [PATCH 60/69] fix and activate some checks in ruff-minimal --- src/sage/combinat/matrices/latin.py | 3 ++- src/sage/doctest/control.py | 4 ++-- src/sage/functions/airy.py | 8 ++++---- src/sage/functions/log.py | 2 +- src/sage/graphs/generators/random.py | 4 ++-- src/sage/misc/package_dir.py | 2 +- src/sage/modules/with_basis/representation.py | 2 +- .../quadratic_forms/quadratic_form__ternary_Tornaria.py | 3 +-- src/sage/schemes/curves/projective_curve.py | 2 +- src/sage/schemes/elliptic_curves/ell_curve_isogeny.py | 7 ++++--- src/sage/schemes/elliptic_curves/ell_field.py | 2 +- src/sage/tests/arxiv_0812_2725.py | 6 +++--- src/tox.ini | 4 +--- 13 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/sage/combinat/matrices/latin.py b/src/sage/combinat/matrices/latin.py index 29fbe2f960e..18c006e7aed 100644 --- a/src/sage/combinat/matrices/latin.py +++ b/src/sage/combinat/matrices/latin.py @@ -1212,7 +1212,8 @@ def disjoint_mate_dlxcpp_rows_and_map(self, allow_subtrade): dlx_rows.append([c_OFFSET, r_OFFSET, xy_OFFSET]) - max_column_nr = max(max_column_nr, max(c_OFFSET, r_OFFSET, xy_OFFSET)) + max_column_nr = max(max_column_nr, c_OFFSET, + r_OFFSET, xy_OFFSET) # We will have missed some columns. We # have to add 'dummy' rows so that the C++ DLX solver will find diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index 05dde014fec..49df68fe66e 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -1351,12 +1351,12 @@ def run_val_gdb(self, testing=False): opt = self.options if opt.gdb: - cmd = f'''exec gdb --eval-command="run" --args ''' + cmd = '''exec gdb --eval-command="run" --args ''' flags = "" if opt.logfile: sage_cmd += f" --logfile {shlex.quote(opt.logfile)}" elif opt.lldb: - cmd = f'''exec lldb --one-line "process launch" --one-line "cont" -- ''' + cmd = '''exec lldb --one-line "process launch" --one-line "cont" -- ''' flags = "" else: if opt.logfile is None: diff --git a/src/sage/functions/airy.py b/src/sage/functions/airy.py index d8f1a79fa8b..ba1ebe34c91 100644 --- a/src/sage/functions/airy.py +++ b/src/sage/functions/airy.py @@ -241,7 +241,7 @@ def _evalf_(self, x, **kwargs): from sage.rings.real_mpfr import RR from sage.rings.cc import CC from sage.functions.other import real, imag - from scipy.special import airy as airy + from scipy.special import airy if x in RR: y = airy(real(x))[0] if parent is None: @@ -341,7 +341,7 @@ def _evalf_(self, x, **kwargs): from sage.rings.real_mpfr import RR from sage.rings.cc import CC from sage.functions.other import real, imag - from scipy.special import airy as airy + from scipy.special import airy if x in RR: y = airy(real(x))[1] if parent is None: @@ -680,7 +680,7 @@ def _evalf_(self, x, **kwargs): from sage.rings.real_mpfr import RR from sage.rings.cc import CC from sage.functions.other import real, imag - from scipy.special import airy as airy + from scipy.special import airy if x in RR: y = airy(real(x))[2] if parent is None: @@ -782,7 +782,7 @@ def _evalf_(self, x, **kwargs): from sage.rings.real_mpfr import RR from sage.rings.cc import CC from sage.functions.other import real, imag - from scipy.special import airy as airy + from scipy.special import airy if x in RR: y = airy(real(x))[3] if parent is None: diff --git a/src/sage/functions/log.py b/src/sage/functions/log.py index de1db4dcb92..344bff959a3 100644 --- a/src/sage/functions/log.py +++ b/src/sage/functions/log.py @@ -8,7 +8,7 @@ - Tomas Kalvoda (2015-04-01): Add :meth:`exp_polar()` (:issue:`18085`) """ -from sage.misc.functional import log as log +from sage.misc.functional import log from sage.misc.lazy_import import lazy_import from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ diff --git a/src/sage/graphs/generators/random.py b/src/sage/graphs/generators/random.py index 90cd8bceb93..821068763b3 100644 --- a/src/sage/graphs/generators/random.py +++ b/src/sage/graphs/generators/random.py @@ -1709,7 +1709,7 @@ def RandomKTree(n, k, seed=None): # A graph with treewidth 0 has no edges if k == 0: - g = Graph(n, name=f"Random 0-tree") + g = Graph(n, name="Random 0-tree") return g if n < k + 1: @@ -1803,7 +1803,7 @@ def RandomPartialKTree(n, k, x, seed=None): # A graph with treewidth 0 has no edges if k == 0: - g = Graph(n, name=f"Random partial 0-tree") + g = Graph(n, name="Random partial 0-tree") return g if n < k + 1: diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index b15374e3bbc..3ef3adf73be 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -603,7 +603,7 @@ def handle_file(root, file): else: handle_file(*os.path.split(path)) - print(f"sage --fixdistributions: checking consistency") + print("sage --fixdistributions: checking consistency") for package in ordinary_packages: if len(package_distributions_per_directives[package]) > 1: diff --git a/src/sage/modules/with_basis/representation.py b/src/sage/modules/with_basis/representation.py index 09f2cd9d4df..3bdcc165692 100644 --- a/src/sage/modules/with_basis/representation.py +++ b/src/sage/modules/with_basis/representation.py @@ -1895,7 +1895,7 @@ def __init__(self, rep, degree, **options): R = rep.base_ring() dim = rep.dimension() if degree not in ZZ or degree < 0: - raise ValueError(f"the degree must be a nonnegative integer") + raise ValueError("the degree must be a nonnegative integer") self._symalg = PolynomialRing(R, 'e', dim) self._basis_order = list(rep.basis().keys()) G = self._symalg.gens() diff --git a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py index 3922767e870..a8265a5bbe1 100644 --- a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +++ b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py @@ -129,8 +129,7 @@ def adjoint(self): [ * 19 4 ] [ * * 8 ] """ - from sage.quadratic_forms.quadratic_form import QuadraticForm as QuadraticForm - + from sage.quadratic_forms.quadratic_form import QuadraticForm if is_odd(self.dim()): return QuadraticForm(self.matrix().adjoint_classical() * 2) return QuadraticForm(self.matrix().adjoint_classical()) diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index d9a7321ade4..d50ef0063e3 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -2300,7 +2300,7 @@ def __init__(self, A, f): self._open_affine_index = i break else: - assert "no projective curve defined" + raise ValueError("no projective curve defined") def function_field(self): """ diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index f25fbc20a7d..1363543bf3b 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -3319,12 +3319,13 @@ def dual(self): else: # trac 7096 - # this should take care of the case when the isogeny is not normalized. + # this should take care of the case when the isogeny is + # not normalized. u = self.scaling_factor() E2 = E2pr.change_weierstrass_model(u/F(d), 0, 0, 0) phi_hat = EllipticCurveIsogeny(E1, None, E2, d) -# assert phi_hat.scaling_factor() == 1 + # assert phi_hat.scaling_factor() == 1 for pre_iso in self._codomain.isomorphisms(E1): for post_iso in E2.isomorphisms(self._domain): @@ -3335,7 +3336,7 @@ def dual(self): continue break else: - assert "bug in dual()" + raise RuntimeError("bug in dual()") phi_hat._set_pre_isomorphism(pre_iso) phi_hat._set_post_isomorphism(post_iso) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 3ff2826f3e7..920fd99dfed 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1754,7 +1754,7 @@ def kernel_polynomial_from_divisor(self, f, l, *, check=True): if not f.is_irreducible(): raise NotImplementedError('currently, kernel_polynomial_from_divisor() only supports irreducible polynomials') if f.parent().base_ring() != self.base_ring(): - raise TypeError(f'given polynomial is not defined over the base ring of the curve') + raise TypeError('given polynomial is not defined over the base ring of the curve') if self.division_polynomial(l, x=f.parent().quotient_ring(f).gen()): raise ValueError(f'given polynomial does not divide the {l}-division polynomial') diff --git a/src/sage/tests/arxiv_0812_2725.py b/src/sage/tests/arxiv_0812_2725.py index 9bacb5c18aa..25e24ca3735 100644 --- a/src/sage/tests/arxiv_0812_2725.py +++ b/src/sage/tests/arxiv_0812_2725.py @@ -25,7 +25,7 @@ sage: dcrossing([(1,5), (2,4), (4,9), (6,12), (7,10), (10,11)]) 3 """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 Dan Drake # # This program is free software: you can redistribute it and/or modify @@ -34,8 +34,8 @@ # your option) any later version. # # See https://www.gnu.org/licenses/. -#***************************************************************************** -from sage.combinat.set_partition import SetPartitions as SetPartitions +# **************************************************************************** +from sage.combinat.set_partition import SetPartitions def CompleteMatchings(n): diff --git a/src/tox.ini b/src/tox.ini index 68a64b498d5..2f2b0209c23 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -304,16 +304,14 @@ passenv = RUFF_OUTPUT_FORMAT # 7 E743 [ ] Ambiguous function name: `I` # 7 PLR0124 [ ] Name compared with itself, consider replacing `a == a` # 5 PLW0127 [ ] Self-assignment of variable `a` -# 4 F541 [*] f-string without any placeholders # 4 PLW1508 [ ] Invalid type for environment variable default; expected `str` or `None` # 3 PLC3002 [ ] Lambda expression called directly. Execute the expression inline instead. # 2 E742 [ ] Ambiguous class name: `I` # 2 PLE0302 [ ] The special method `__len__` expects 1 parameter, 3 were given -# 2 PLW0129 [ ] Asserting on a non-empty string literal will always pass # 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 E402,E721,E731,E741,E742,E743,F401,F402,F403,F405,F541,F811,F821,F841,I001,PLC0206,PLC0208,PLC0414,PLC2401,PLC3002,PLE0302,PLR0124,PLR0402,PLR0911,PLR0912,PLR0913,PLR0915,PLR1704,PLR1711,PLR1714,PLR1736,PLR2004,PLR5501,PLW0120,PLW0127,PLW0129,PLW0211,PLW0602,PLW0603,PLW0642,PLW1508,PLW1510,PLW2901,PLW3301 {posargs:{toxinidir}/sage/} +commands = ruff check --ignore E402,E721,E731,E741,E742,E743,F401,F402,F403,F405,F811,F821,F841,I001,PLC0206,PLC0208,PLC2401,PLC3002,PLE0302,PLR0124,PLR0402,PLR0911,PLR0912,PLR0913,PLR0915,PLR1704,PLR1711,PLR1714,PLR1736,PLR2004,PLR5501,PLW0120,PLW0127,PLW0211,PLW0602,PLW0603,PLW0642,PLW1508,PLW1510,PLW2901,PLW3301 {posargs:{toxinidir}/sage/} [flake8] rst-roles = From 38441b3d2e9d9e228ce3a2827c48cda66e432703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 31 Dec 2024 11:32:08 +0100 Subject: [PATCH 61/69] minor tweaks in Ore polynomials --- .../rings/polynomial/ore_function_element.py | 9 +- .../rings/polynomial/ore_function_field.py | 65 +++++++------- .../rings/polynomial/ore_polynomial_ring.py | 84 +++++++++---------- 3 files changed, 75 insertions(+), 83 deletions(-) diff --git a/src/sage/rings/polynomial/ore_function_element.py b/src/sage/rings/polynomial/ore_function_element.py index d858838f53c..a97eb60d268 100644 --- a/src/sage/rings/polynomial/ore_function_element.py +++ b/src/sage/rings/polynomial/ore_function_element.py @@ -16,14 +16,13 @@ # https://www.gnu.org/licenses/ # *************************************************************************** -from sage.structure.richcmp import richcmp, op_EQ, op_NE -from sage.misc.cachefunc import cached_method -from sage.misc.latex import latex - +from sage.categories.homset import Hom from sage.categories.map import Map from sage.categories.morphism import Morphism -from sage.categories.homset import Hom +from sage.misc.cachefunc import cached_method +from sage.misc.latex import latex from sage.structure.element import AlgebraElement +from sage.structure.richcmp import op_EQ, op_NE, richcmp class OreFunction(AlgebraElement): diff --git a/src/sage/rings/polynomial/ore_function_field.py b/src/sage/rings/polynomial/ore_function_field.py index 1c78217508b..4b509688450 100644 --- a/src/sage/rings/polynomial/ore_function_field.py +++ b/src/sage/rings/polynomial/ore_function_field.py @@ -128,6 +128,23 @@ sage: g^(-1) * f (d - 1/t)^(-1) * (d + (t^2 - 1)/t) +TESTS: + +The Ore function field is commutative if the twisting morphism is the +identity and the twisting derivation vanishes. :: + + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x', Frob] + sage: K = S.fraction_field() + sage: K.is_commutative() + False + sage: T. = k['y', Frob^3] + sage: L = T.fraction_field() + sage: L.is_commutative() + True + AUTHOR: - Xavier Caruso (2020-05) @@ -144,21 +161,21 @@ # https://www.gnu.org/licenses/ # *************************************************************************** -import sage - -from sage.structure.richcmp import op_EQ -from sage.structure.category_object import normalize_names -from sage.structure.unique_representation import UniqueRepresentation -from sage.structure.parent import Parent from sage.categories.algebras import Algebras +from sage.categories.commutative_rings import CommutativeRings from sage.categories.fields import Fields - -from sage.rings.morphism import RingHomomorphism from sage.categories.homset import Hom from sage.categories.map import Section - +from sage.rings.morphism import RingHomomorphism +from sage.rings.polynomial.ore_function_element import ( + OreFunction_with_large_center, + OreFunctionBaseringInjection, +) from sage.rings.polynomial.ore_polynomial_ring import OrePolynomialRing -from sage.rings.polynomial.ore_function_element import OreFunctionBaseringInjection +from sage.structure.category_object import normalize_names +from sage.structure.parent import Parent +from sage.structure.richcmp import op_EQ +from sage.structure.unique_representation import UniqueRepresentation WORKING_CENTER_MAX_TRIES = 1000 @@ -200,7 +217,10 @@ def __init__(self, ring, category=None): self._simplification = False self._ring = ring base = ring.base_ring() - category = Algebras(base).or_subcategory(category) + if ring in CommutativeRings(): + category = Algebras(base).Commutative().or_subcategory(category) + else: + category = Algebras(base).or_subcategory(category) Parent.__init__(self, base=base, names=ring.variable_name(), normalize=True, category=category) @@ -614,27 +634,6 @@ def random_element(self, degree=2, monic=False, *args, **kwds): denominator = self._ring.random_element(degdenom, True, *args, **kwds) return self(numerator, denominator) - def is_commutative(self) -> bool: - r""" - Return ``True`` if this Ore function field is commutative, i.e. if the - twisting morphism is the identity and the twisting derivation vanishes. - - EXAMPLES:: - - sage: # needs sage.rings.finite_rings - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x', Frob] - sage: K = S.fraction_field() - sage: K.is_commutative() - False - sage: T. = k['y', Frob^3] - sage: L = T.fraction_field() - sage: L.is_commutative() - True - """ - return self._ring.is_commutative() - def is_field(self, proof=False) -> bool: r""" Return always ``True`` since Ore function field are (skew) fields. @@ -892,7 +891,7 @@ def __init__(self, ring, category=None): sage: TestSuite(K).run() """ if self.Element is None: - self.Element = sage.rings.polynomial.ore_function_element.OreFunction_with_large_center + self.Element = OreFunction_with_large_center OreFunctionField.__init__(self, ring, category) self._center = {} self._center_variable_name = 'z' diff --git a/src/sage/rings/polynomial/ore_polynomial_ring.py b/src/sage/rings/polynomial/ore_polynomial_ring.py index f28b90ad198..7866221cfad 100644 --- a/src/sage/rings/polynomial/ore_polynomial_ring.py +++ b/src/sage/rings/polynomial/ore_polynomial_ring.py @@ -7,6 +7,30 @@ which constructs a general dense univariate Ore polynomial ring over a commutative base with equipped with an endomorphism and/or a derivation. +TESTS: + +The Ore polynomial ring is commutative if the twisting morphism is the +identity and the twisting derivation vanishes. :: + + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x', Frob] + sage: S.is_commutative() + False + sage: T. = k['y', Frob^3] + sage: T.is_commutative() + True + + sage: R. = GF(5)[] + sage: der = R.derivation() + sage: A. = R['d', der] + sage: A.is_commutative() + False + sage: B. = R['b', 5*der] + sage: B.is_commutative() + True + AUTHOR: - Xavier Caruso (2020-04) @@ -21,25 +45,21 @@ # https://www.gnu.org/licenses/ # *************************************************************************** -from sage.misc.prandom import randint +from sage.categories.algebras import Algebras +from sage.categories.commutative_rings import CommutativeRings +from sage.categories.morphism import Morphism from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import lazy_import +from sage.misc.prandom import randint from sage.rings.infinity import Infinity +from sage.rings.integer import Integer +from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.ring import _Fields from sage.structure.category_object import normalize_names +from sage.structure.element import Element from sage.structure.parent import Parent - from sage.structure.unique_representation import UniqueRepresentation -from sage.rings.integer import Integer -from sage.structure.element import Element - -from sage.categories.commutative_rings import CommutativeRings -from sage.categories.algebras import Algebras -from sage.rings.ring import _Fields - -from sage.categories.morphism import Morphism - -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection lazy_import('sage.rings.derivation', 'RingDerivation') @@ -421,7 +441,11 @@ def __init__(self, base_ring, morphism, derivation, name, sparse, category=None) self._morphism = morphism self._derivation = derivation self._fraction_field = None - category = Algebras(base_ring).or_subcategory(category) + if morphism is None and derivation is None: + cat = Algebras(base_ring).Commutative() + else: + cat = Algebras(base_ring) + category = cat.or_subcategory(category) Parent.__init__(self, base_ring, names=name, normalize=True, category=category) @@ -506,7 +530,7 @@ def build(check): pass if isinstance(a, str): try: - from sage.misc.parser import Parser, LookupNameMaker + from sage.misc.parser import LookupNameMaker, Parser R = self.base_ring() p = Parser(Integer, R, LookupNameMaker({self.variable_name(): self.gen()}, R)) return self(p.parse(a)) @@ -1095,36 +1119,6 @@ def random_irreducible(self, degree=2, monic=True, *args, **kwds): if irred.is_irreducible(): return irred - def is_commutative(self) -> bool: - r""" - Return ``True`` if this Ore polynomial ring is commutative. - - This holds if the twisting morphism is the identity and the - twisting derivation vanishes. - - EXAMPLES:: - - sage: # needs sage.rings.finite_rings - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x', Frob] - sage: S.is_commutative() - False - sage: T. = k['y', Frob^3] - sage: T.is_commutative() - True - - sage: R. = GF(5)[] - sage: der = R.derivation() - sage: A. = R['d', der] - sage: A.is_commutative() - False - sage: B. = R['b', 5*der] - sage: B.is_commutative() - True - """ - return self._morphism is None and self._derivation is None - def is_field(self, proof=False) -> bool: r""" Return always ``False`` since Ore polynomial rings are never fields. From f04f62589f355e13df961cfd47bba084a1f72292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 31 Dec 2024 13:12:16 +0100 Subject: [PATCH 62/69] suggested details --- src/sage/coding/binary_code.pyx | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index 369a01b0fa4..dd7b017fbe4 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -62,9 +62,9 @@ cdef inline int min(int a, int b) noexcept: else: return a -## NOTE - Since most of the functions are used from within the module, cdef'd -## functions come without an underscore, and the def'd equivalents, which are -## essentially only for doctesting and debugging, have underscores. +# NOTE - Since most of the functions are used from within the module, cdef'd +# functions come without an underscore, and the def'd equivalents, which are +# essentially only for doctesting and debugging, have underscores. cdef int *hamming_weights() noexcept: cdef int *ham_wts @@ -1287,9 +1287,10 @@ cdef class OrbitPartition: self.col_rank = sig_malloc(ncols * sizeof(int)) self.col_min_cell_rep = sig_malloc(ncols * sizeof(int)) self.col_size = sig_malloc(ncols * sizeof(int)) - if self.wd_parent is NULL or self.wd_rank is NULL or self.wd_min_cell_rep is NULL \ - or self.wd_size is NULL or self.col_parent is NULL or self.col_rank is NULL \ - or self.col_min_cell_rep is NULL or self.col_size is NULL: + if (self.wd_parent is NULL or self.wd_rank is NULL + or self.wd_min_cell_rep is NULL or self.wd_size is NULL + or self.col_parent is NULL or self.col_rank is NULL + or self.col_min_cell_rep is NULL or self.col_size is NULL): if self.wd_parent is not NULL: sig_free(self.wd_parent) if self.wd_rank is not NULL: @@ -1613,10 +1614,10 @@ cdef class PartitionStack: self.flag = (1 << (self.radix-1)) # data - self.wd_ents = sig_malloc( self.nwords * sizeof_int ) - self.wd_lvls = sig_malloc( self.nwords * sizeof_int ) - self.col_ents = sig_malloc( self.ncols * sizeof_int ) - self.col_lvls = sig_malloc( self.ncols * sizeof_int ) + self.wd_ents = sig_malloc(self.nwords * sizeof_int) + self.wd_lvls = sig_malloc(self.nwords * sizeof_int) + self.col_ents = sig_malloc(self.ncols * sizeof_int) + self.col_lvls = sig_malloc(self.ncols * sizeof_int) # scratch space self.col_degs = sig_malloc( self.ncols * sizeof_int ) From 9cdc4b0e7a995f972d0cf0df8ea974e9d0bb3b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 1 Jan 2025 09:55:40 +0100 Subject: [PATCH 63/69] fixing a few typos --- docker/.gitpod.Dockerfile | 2 +- .../algebras/hecke_algebras/cubic_hecke_base_ring.py | 2 +- src/sage/categories/finite_enumerated_sets.py | 2 +- src/sage/combinat/designs/difference_family.py | 8 ++++---- src/sage/combinat/matrices/hadamard_matrix.py | 2 +- src/sage/combinat/posets/posets.py | 6 +++--- src/sage/combinat/regular_sequence.py | 4 ++-- src/sage/combinat/specht_module.py | 2 +- src/sage/combinat/t_sequences.py | 12 ++++++------ src/sage/ext_data/valgrind/pyalloc.supp | 2 +- src/sage/geometry/polyhedral_complex.py | 2 +- src/sage/graphs/generators/smallgraphs.py | 2 +- src/sage/graphs/matching_covered_graph.py | 4 ++-- src/sage/interfaces/mathics.py | 2 +- src/sage/knots/knotinfo.py | 6 +++--- src/sage/matrix/matrix2.pyx | 2 +- src/sage/modules/with_basis/cell_module.py | 2 +- src/sage/rings/semirings/tropical_polynomial.py | 2 +- src/sage/rings/valuation/valuation.py | 2 +- src/sage/schemes/elliptic_curves/ell_generic.py | 2 +- src/sage/topology/cell_complex.py | 2 +- 21 files changed, 35 insertions(+), 35 deletions(-) diff --git a/docker/.gitpod.Dockerfile b/docker/.gitpod.Dockerfile index 3ff75298c77..2e4da8ed858 100644 --- a/docker/.gitpod.Dockerfile +++ b/docker/.gitpod.Dockerfile @@ -6,7 +6,7 @@ RUN apt update && apt-get install -yq --no-install-recommends sudo gpg curl lsb- # Make Docker available, like the default gitpod image does # from https://github.com/gitpod-io/workspace-images/blob/main/chunks/tool-docker/Dockerfile @ 3f0988f2d06768d22d0aa1454ef0e963b0db65f3 -# - removed unneccessary "sudo" +# - removed unnecessary "sudo" # - replaced use of "install-packages" (https://github.com/gitpod-io/workspace-images/blob/main/base/install-packages) # https://docs.docker.com/engine/install/ubuntu/ RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \ diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py b/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py index b980e2fa80c..10381f64f35 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py @@ -683,7 +683,7 @@ def create_specialization(self, im_cubic_equation_roots, im_writhe_parameter=Non if len(cyclotomic_roots) > 0: E3 = cyclotomic_roots[0] - verbose('thrird root of unity %s found in %s' % (E3, E3.parent()), level=2) + verbose('third root of unity %s found in %s' % (E3, E3.parent()), level=2) if E3 is None: raise RuntimeError('cannot find a ring containing a third root of unity for the this choice of cubic roots!') diff --git a/src/sage/categories/finite_enumerated_sets.py b/src/sage/categories/finite_enumerated_sets.py index d3438e43d37..e3243937b5a 100644 --- a/src/sage/categories/finite_enumerated_sets.py +++ b/src/sage/categories/finite_enumerated_sets.py @@ -474,7 +474,7 @@ def _random_element_from_unrank(self): sage: n in C True - TODO: implement _test_random which checks uniformness + TODO: implement _test_random which checks uniformity """ from sage.misc.prandom import randint c = self.cardinality() diff --git a/src/sage/combinat/designs/difference_family.py b/src/sage/combinat/designs/difference_family.py index a74634d32cf..83bfce22eb3 100644 --- a/src/sage/combinat/designs/difference_family.py +++ b/src/sage/combinat/designs/difference_family.py @@ -1579,7 +1579,7 @@ def is_relative_difference_set(R, G, H, params, verbose=False): - ``H`` -- list; a submodule of ``G`` of order `n` - ``params`` -- tuple in the form `(m, n, k, d)` - ``verbose`` -- boolean (default: ``False``); if ``True``, the function - will be verbose when the sequences do not satisfy the contraints + will be verbose when the sequences do not satisfy the constraints EXAMPLES:: @@ -1659,7 +1659,7 @@ def is_supplementary_difference_set(Ks, v=None, lmbda=None, G=None, verbose=Fals - ``lmbda`` -- integer; the parameter `\lambda` of the supplementary difference sets - ``G`` -- a group of order `v` - ``verbose`` -- boolean (default: ``False``); if ``True``, the function will - be verbose when the sets do not satisfy the contraints + be verbose when the sets do not satisfy the constraints EXAMPLES:: @@ -1757,7 +1757,7 @@ def supplementary_difference_set_from_rel_diff_set(q, existence=False, check=Tru OUTPUT: If ``existence=False``, the function returns the 4 sets (containing integers), - or raises an error if ``q`` does not satify the constraints. + or raises an error if ``q`` does not satisfy the constraints. If ``existence=True``, the function returns a boolean representing whether supplementary difference sets can be constructed. @@ -3084,7 +3084,7 @@ def are_complementary_difference_sets(G, A, B, verbose=False): - ``A`` -- set of elements of ``G`` - ``B`` -- set of elements of ``G`` - ``verbose`` -- boolean (default: ``False``); if ``True`` the function will - be verbose when the sets do not satisfy the contraints + be verbose when the sets do not satisfy the constraints EXAMPLES:: diff --git a/src/sage/combinat/matrices/hadamard_matrix.py b/src/sage/combinat/matrices/hadamard_matrix.py index 5f9f24239d4..b8124220914 100644 --- a/src/sage/combinat/matrices/hadamard_matrix.py +++ b/src/sage/combinat/matrices/hadamard_matrix.py @@ -1503,7 +1503,7 @@ def hadamard_matrix_spence_construction(n, existence=False, check=True): - ``n`` -- integer; the order of the matrix to be constructed - ``existence`` -- boolean (default: ``False``); if ``True``, only check if the matrix exists - - ``check`` -- bolean (default: ``True``); if ``True``, check that the matrix + - ``check`` -- boolean (default: ``True``); if ``True``, check that the matrix is a Hadamard matrix before returning OUTPUT: diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 2a4b2d24f48..389a3ee0061 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -6530,7 +6530,7 @@ def random_maximal_chain(self): EXAMPLES:: - sage: set_random_seed(0) # results are reproduceable + sage: set_random_seed(0) # results are reproducible sage: P = posets.BooleanLattice(4) sage: P.random_maximal_chain() [0, 4, 5, 7, 15] @@ -6565,7 +6565,7 @@ def random_maximal_antichain(self): EXAMPLES:: - sage: set_random_seed(0) # results are reproduceable + sage: set_random_seed(0) # results are reproducible sage: P = posets.BooleanLattice(4) sage: P.random_maximal_antichain() [1, 8, 2, 4] @@ -6597,7 +6597,7 @@ def random_linear_extension(self): EXAMPLES:: - sage: set_random_seed(0) # results are reproduceable + sage: set_random_seed(0) # results are reproducible sage: P = posets.BooleanLattice(4) sage: P.random_linear_extension() [0, 4, 1, 2, 3, 8, 10, 5, 12, 9, 13, 11, 6, 14, 7, 15] diff --git a/src/sage/combinat/regular_sequence.py b/src/sage/combinat/regular_sequence.py index b57e5ccbf5b..6ad1c12c088 100644 --- a/src/sage/combinat/regular_sequence.py +++ b/src/sage/combinat/regular_sequence.py @@ -335,7 +335,7 @@ def __iter__(self): def is_degenerated(self): r""" Return whether this `k`-regular sequence is degenerated, - i.e., whether this `k`-regular sequence does not satisfiy + i.e., whether this `k`-regular sequence does not satisfy `\mu[0] \mathit{right} = \mathit{right}`. EXAMPLES:: @@ -368,7 +368,7 @@ def is_degenerated(self): def _error_if_degenerated_(self): r""" Raise an error if this `k`-regular sequence is degenerated, - i.e., if this `k`-regular sequence does not satisfiy + i.e., if this `k`-regular sequence does not satisfy `\mu[0] \mathit{right} = \mathit{right}`. TESTS:: diff --git a/src/sage/combinat/specht_module.py b/src/sage/combinat/specht_module.py index e48e34419fe..1f7f15c90d6 100644 --- a/src/sage/combinat/specht_module.py +++ b/src/sage/combinat/specht_module.py @@ -1036,7 +1036,7 @@ def _repr_(self): class SimpleModule(SymmetricGroupRepresentation, QuotientModuleWithBasis): r""" - The simgle `S_n`-module associated with a partition `\lambda`. + The simple `S_n`-module associated with a partition `\lambda`. The simple module `D^{\lambda}` is the quotient of the Specht module `S^{\lambda}` by its :class:`maximal submodule ` diff --git a/src/sage/combinat/t_sequences.py b/src/sage/combinat/t_sequences.py index c78a451f67c..2af7e4b9d1a 100644 --- a/src/sage/combinat/t_sequences.py +++ b/src/sage/combinat/t_sequences.py @@ -84,7 +84,7 @@ def is_skew(seq, verbose=False): - ``seq`` -- the sequence that should be checked - ``verbose`` -- boolean (default: ``False``); if ``True`` the function - will be verbose when the sequences do not satisfy the contraints + will be verbose when the sequences do not satisfy the constraints EXAMPLES:: @@ -130,7 +130,7 @@ def is_symmetric(seq, verbose=False) -> bool: - ``seq`` -- the sequence that should be checked - ``verbose`` -- boolean (default: ``False``); if ``True`` the function will be - verbose when the sequences do not satisfy the contraints + verbose when the sequences do not satisfy the constraints EXAMPLES:: @@ -180,7 +180,7 @@ def is_T_sequences_set(sequences, verbose=False): - ``sequences`` -- list of four sequences - ``verbose`` -- boolean (default: ``False``); if ``True`` the function will be - verbose when the sequences do not satisfy the contraints + verbose when the sequences do not satisfy the constraints EXAMPLES:: @@ -643,7 +643,7 @@ def is_base_sequences_tuple(base_sequences, verbose=False): - ``base_sequences`` -- the list of 4 sequences that should be checked - ``verbose`` -- boolean (default: ``False``); if ``True`` the function - will be verbose when the sequences do not satisfy the contraints + will be verbose when the sequences do not satisfy the constraints EXAMPLES:: @@ -656,7 +656,7 @@ def is_base_sequences_tuple(base_sequences, verbose=False): sage: seqs = [[1, -1], [1, 1], [-1], [2]] sage: is_base_sequences_tuple(seqs, verbose=True) - Base sequences should only contiain -1, +1, found 2 + Base sequences should only contain -1, +1, found 2 False TESTS: @@ -694,7 +694,7 @@ def is_base_sequences_tuple(base_sequences, verbose=False): for el in seq: if abs(el) != 1: if verbose: - print(f'Base sequences should only contiain -1, +1, found {el}') + print(f'Base sequences should only contain -1, +1, found {el}') return False for j in range(1, n+p): diff --git a/src/sage/ext_data/valgrind/pyalloc.supp b/src/sage/ext_data/valgrind/pyalloc.supp index 35ebe0ce1a3..542ab3e5a0f 100644 --- a/src/sage/ext_data/valgrind/pyalloc.supp +++ b/src/sage/ext_data/valgrind/pyalloc.supp @@ -1,4 +1,4 @@ -# Read Misc/README.valgrind in the Python sourcs for a thorough explanation +# Read Misc/README.valgrind in the Python sources for a thorough explanation # # In short: We need these unless we compile python without pyalloc, # but that would be prohibitively slow. diff --git a/src/sage/geometry/polyhedral_complex.py b/src/sage/geometry/polyhedral_complex.py index 539e2021f88..0dc45748578 100644 --- a/src/sage/geometry/polyhedral_complex.py +++ b/src/sage/geometry/polyhedral_complex.py @@ -2271,7 +2271,7 @@ def is_simplicial_fan(self): Test if this polyhedral complex is a simplicial fan. A polyhedral complex is a **simplicial fan** if all of its (maximal) - cells are simplical cones, i.e., every cell is a pointed cone (with + cells are simplicial cones, i.e., every cell is a pointed cone (with vertex being the origin) generated by `d` linearly independent rays, where `d` is the dimension of the cone. diff --git a/src/sage/graphs/generators/smallgraphs.py b/src/sage/graphs/generators/smallgraphs.py index d490eda7830..4fc69e689b6 100644 --- a/src/sage/graphs/generators/smallgraphs.py +++ b/src/sage/graphs/generators/smallgraphs.py @@ -4623,7 +4623,7 @@ def TricornGraph(): The Tricorn graph is obtained by splicing a complete graph `K_4` with the the triangular circular ladder graph `\overline{C_6}`. (Note that this - generates a unqiue graph as both of the graphs `K_4` and `\overline{C_6}` + generates a unique graph as both of the graphs `K_4` and `\overline{C_6}` are vertex-transitive). It is a nonsolid brick. This matching covered graph is one of the ten extremal cubic bricks. (A matching covered graph `G` is *extremal* if `\Phi(G) = dim(\mathcal{Lin}(G))`, where `\Phi(G)` denotes diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 9e06d4ebfca..9544c2e58f9 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2580,7 +2580,7 @@ def remove_loops(self, vertices=None): INPUT: - ``vertices`` -- (default: ``None``) iterator container of vertex - labels correponding to which the looped edges are to be removed. If + labels corresponding to which the looped edges are to be removed. If ``vertices`` is ``None``, remove all loops. OUTPUT: @@ -2750,4 +2750,4 @@ def update_matching(self, matching): raise exception -__doc__ = __doc__.replace('{INDEX_OF_METHODS}', gen_thematic_rest_table_index(MatchingCoveredGraph, only_local_functions=False)) \ No newline at end of file +__doc__ = __doc__.replace('{INDEX_OF_METHODS}', gen_thematic_rest_table_index(MatchingCoveredGraph, only_local_functions=False)) diff --git a/src/sage/interfaces/mathics.py b/src/sage/interfaces/mathics.py index 58a376b9c72..3ca4bee83ef 100644 --- a/src/sage/interfaces/mathics.py +++ b/src/sage/interfaces/mathics.py @@ -397,7 +397,7 @@ def _mathics_sympysage_symbol(self): r""" - Convert a Sympy symbol ``self`` to a correspondig element + Convert a Sympy symbol ``self`` to a corresponding element in Sage's symbolic ring. This function replaces ``_sympysage_symbol`` to diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 8c246ba8097..c57777bb2c2 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -17,7 +17,7 @@ This will install a `Python wrapper `__ for the original databases in Sage. This wrapper perfoms an automatic progress of version numbers. For more details and further install instructions please see -the correspondig web-page. +the corresponding web-page. To perform all the doctests concerning the usage of the database on the installation add the option ``-c``. In this case (for instance ``sage -f -c database_knotinfo``) @@ -218,7 +218,7 @@ - Sebastian Oehms August 2020: initial version - Sebastian Oehms June 2022: add :meth:`conway_polynomial` and :meth:`khovanov_polynomial` (:issue:`33969`) -Thanks to Chuck Livingston and Allison Moore for their support. For further acknowledgments see the correspondig hompages. +Thanks to Chuck Livingston and Allison Moore for their support. For further acknowledgments see the corresponding hompages. """ @@ -229,7 +229,7 @@ # 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/ ############################################################################## diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index dec25a76e54..91ed772cc02 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -14520,7 +14520,7 @@ cdef class Matrix(Matrix1): # Continuing the "else" branch of Higham's Step (1), and # onto B&K's Step (3) where we find the largest - # off-diagonal entry (in magniture) in column "r". Since + # off-diagonal entry (in magnitude) in column "r". Since # the matrix is Hermitian, we need only look at the # above-diagonal entries to find the off-diagonal of # maximal magnitude. diff --git a/src/sage/modules/with_basis/cell_module.py b/src/sage/modules/with_basis/cell_module.py index 7c61057737c..35528c1407e 100644 --- a/src/sage/modules/with_basis/cell_module.py +++ b/src/sage/modules/with_basis/cell_module.py @@ -348,7 +348,7 @@ def _acted_upon_(self, scalar, self_on_left=False): sage: 1/2 * elt W[[1, 2], [3]] + W[[1, 3], [2]] """ - # Check for elements coercable to the base ring first + # Check for elements coercible to the base ring first ret = CombinatorialFreeModule.Element._acted_upon_(self, scalar, self_on_left) if ret is not None: return ret diff --git a/src/sage/rings/semirings/tropical_polynomial.py b/src/sage/rings/semirings/tropical_polynomial.py index 42caa0601f9..ef00b53e4ca 100644 --- a/src/sage/rings/semirings/tropical_polynomial.py +++ b/src/sage/rings/semirings/tropical_polynomial.py @@ -107,7 +107,7 @@ class TropicalPolynomial(Polynomial_generic_sparse): [1, 1] Even though every tropical polynomials have tropical roots, this does not - neccessarily means it can be factored into its linear factors:: + necessarily means it can be factored into its linear factors:: sage: p1.factor() (0) * (0*x^3 + 4*x + 1) diff --git a/src/sage/rings/valuation/valuation.py b/src/sage/rings/valuation/valuation.py index 80f2b7bf939..60c9df824e9 100644 --- a/src/sage/rings/valuation/valuation.py +++ b/src/sage/rings/valuation/valuation.py @@ -395,7 +395,7 @@ def mac_lane_approximants(self, G, assume_squarefree=False, require_final_EF=Tru - ``require_final_EF`` -- boolean (default: ``True``); whether to require the returned key polynomials to be in one-to-one - correspondance to the extensions of this valuation to ``L`` and + correspondence to the extensions of this valuation to ``L`` and require them to have the ramification index and residue degree of the valuations they correspond to. diff --git a/src/sage/schemes/elliptic_curves/ell_generic.py b/src/sage/schemes/elliptic_curves/ell_generic.py index 44f552ae4af..bfecebf1f86 100644 --- a/src/sage/schemes/elliptic_curves/ell_generic.py +++ b/src/sage/schemes/elliptic_curves/ell_generic.py @@ -946,7 +946,7 @@ def lift_x(self, x, all=False, extend=False): b = (a1*x + a3) f = ((x + a2) * x + a4) * x + a6 - # If possible find the associated y coorindates in L: + # If possible find the associated y coordinates in L: if K.characteristic() == 2: R = PolynomialRing(L, 'y') diff --git a/src/sage/topology/cell_complex.py b/src/sage/topology/cell_complex.py index 7b64a3d36dd..e2276fb8839 100644 --- a/src/sage/topology/cell_complex.py +++ b/src/sage/topology/cell_complex.py @@ -544,7 +544,7 @@ def homology(self, dim=None, base_ring=ZZ, subcomplex=None, [0,0] x [0,1] x [0,1] - [0,1] x [0,0] x [0,1] + [0,1] x [0,1] x [0,0] - [0,1] x [0,1] x [1,1] + [0,1] x [1,1] x [0,1] - [1,1] x [0,1] x [0,1])] - Similarly for simpicial sets:: + Similarly for simplicial sets:: sage: S = simplicial_sets.Sphere(2) sage: S.homology(generators=True) # needs sage.modules From b844e8fa2f33b7fad84db197cabf2241c695b2b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 1 Jan 2025 10:38:35 +0100 Subject: [PATCH 64/69] minor details in modular symbols / boundary --- src/sage/modular/modsym/boundary.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/sage/modular/modsym/boundary.py b/src/sage/modular/modsym/boundary.py index 16241c843aa..89e0e6b0aef 100644 --- a/src/sage/modular/modsym/boundary.py +++ b/src/sage/modular/modsym/boundary.py @@ -89,20 +89,16 @@ # **************************************************************************** -from sage.misc.repr import repr_lincomb -from sage.structure.richcmp import richcmp_method, richcmp - -import sage.modules.free_module as free_module -from sage.modules.free_module_element import FreeModuleElement - import sage.modular.arithgroup.all as arithgroup -import sage.modular.cusps as cusps -import sage.modular.dirichlet as dirichlet import sage.modular.hecke.all as hecke +from sage.categories.rings import Rings +from sage.misc.repr import repr_lincomb +from sage.modular import cusps, dirichlet from sage.modular.modsym.manin_symbol import ManinSymbol - +from sage.modules import free_module +from sage.modules.free_module_element import FreeModuleElement from sage.rings.rational_field import Q as QQ -from sage.categories.rings import Rings +from sage.structure.richcmp import richcmp, richcmp_method from . import element @@ -299,7 +295,7 @@ def __init__(self, - ``sign`` -- integer; either -1, 0, or 1 - - ``base_ring`` -- rings.Ring (defaults to the rational numbers) + - ``base_ring`` -- commutative ring (defaults to the rational numbers) EXAMPLES:: @@ -431,7 +427,9 @@ def gen(self, i=0): sage: B.gen(0) Traceback (most recent call last): ... - ValueError: only 0 generators known for Space of Boundary Modular Symbols for Congruence Subgroup Gamma0(24) of weight 4 over Rational Field + ValueError: only 0 generators known for + Space of Boundary Modular Symbols for + Congruence Subgroup Gamma0(24) of weight 4 over Rational Field sage: B(Cusp(1/3)) [1/3] sage: B.gen(0) From 6c6dcec6a491324871241840b6ed2c0a342675d0 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 1 Jan 2025 17:39:12 +0800 Subject: [PATCH 65/69] First try to import Self from typing --- src/sage/repl/rich_output/display_manager.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/repl/rich_output/display_manager.py b/src/sage/repl/rich_output/display_manager.py index 61ea74ef30b..6e282f8aee5 100644 --- a/src/sage/repl/rich_output/display_manager.py +++ b/src/sage/repl/rich_output/display_manager.py @@ -37,7 +37,10 @@ import warnings from typing import Any -from typing_extensions import Self +try: + from typing import Self # type: ignore (Python >= 3.11) +except ImportError: + from typing_extensions import Self # type: ignore (Python 3.9, 3.10) from sage.repl.rich_output.output_basic import ( OutputAsciiArt, From 5863a983f4f7e6cd91949fab4ac7f0cf6ae6a186 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 1 Jan 2025 17:39:38 +0800 Subject: [PATCH 66/69] Specify explicit dependency on typing_extensions in docs --- build/pkgs/sagemath_doc_html/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/sagemath_doc_html/dependencies b/build/pkgs/sagemath_doc_html/dependencies index 40717629a77..ef59cbb539b 100644 --- a/build/pkgs/sagemath_doc_html/dependencies +++ b/build/pkgs/sagemath_doc_html/dependencies @@ -1,4 +1,4 @@ -sagelib sphinx sphinx_copybutton sphinx_inline_tabs pplpy_doc | $(SAGERUNTIME) maxima networkx scipy sympy matplotlib pillow mathjax mpmath ipykernel jupyter_client conway_polynomials tachyon ipywidgets sage_docbuild elliptic_curves furo fpylll graphs +sagelib sphinx sphinx_copybutton sphinx_inline_tabs pplpy_doc | $(SAGERUNTIME) maxima networkx scipy sympy matplotlib pillow mathjax mpmath ipykernel jupyter_client conway_polynomials tachyon ipywidgets sage_docbuild elliptic_curves furo fpylll graphs typing_extensions # Building the documentation has many dependencies, because all # documented modules are imported and because we use matplotlib to From 85c9d741a646c4cae05ee5d82792f221014ac1d1 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 1 Jan 2025 17:18:58 +0700 Subject: [PATCH 67/69] Modify build using meson guideline --- src/doc/en/installation/meson.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/en/installation/meson.rst b/src/doc/en/installation/meson.rst index 196ecc02597..e0051dbbf68 100644 --- a/src/doc/en/installation/meson.rst +++ b/src/doc/en/installation/meson.rst @@ -9,11 +9,12 @@ This is a short guide on how to build the Sage from source using Meson. Walkthrough =========== -Assume we're starting from a clean repo and a fully set up conda environment: +Assume we're starting from a clean repo and a fully set up conda environment +(modify ``-linux`` according to your operating system): .. CODE-BLOCK:: shell-session - $ mamba env create --file src/environment-3.11.yml --name sage-dev + $ mamba env create --file environment-3.11-linux.yml --name sage-dev $ conda activate sage-dev Alternatively, install all build requirements as described in section From d4cd25fb44eb527e4bdb597f7aac9410a92f24b1 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 2 Jan 2025 12:42:45 +0900 Subject: [PATCH 68/69] Improve error messages --- src/sage/databases/cremona.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/databases/cremona.py b/src/sage/databases/cremona.py index c1c97cfac16..9b881ed70ea 100644 --- a/src/sage/databases/cremona.py +++ b/src/sage/databases/cremona.py @@ -1688,7 +1688,7 @@ def CremonaDatabase(name=None, mini=None, set_global=None): sage: C = CremonaDatabase(mini=False) # optional - !database_cremona_ellcurve Traceback (most recent call last): ... - ValueError: full Cremona database is not available; consider using mini Cremona database by mini=True + ValueError: the full Cremona database is not available; consider using the mini Cremona database by setting mini=True """ if set_global is not None: from sage.misc.superseded import deprecation @@ -1706,8 +1706,8 @@ def CremonaDatabase(name=None, mini=None, set_global=None): name = 'cremona mini' else: if not DatabaseCremona().is_present(): - raise ValueError('full Cremona database is not available; ' - 'consider using mini Cremona database by mini=True') + raise ValueError('the full Cremona database is not available; ' + 'consider using the mini Cremona database by setting mini=True') name = 'cremona' elif name == 'cremona mini': mini = True @@ -1715,7 +1715,7 @@ def CremonaDatabase(name=None, mini=None, set_global=None): mini = False else: if mini is None: - raise ValueError('mini must be set as either True or False') + raise ValueError('the mini option must be set to True or False') if mini: return MiniCremonaDatabase(name) From 1be0a58926030043e4f5dbed850b4c3f809f376b Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sat, 4 Jan 2025 18:43:27 +0100 Subject: [PATCH 69/69] Updated SageMath version to 10.6.beta3 --- 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 ae97bd81ee5..9cc52984028 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.6.beta2 +version: 10.6.beta3 doi: 10.5281/zenodo.8042260 -date-released: 2024-12-22 +date-released: 2025-01-04 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index a5da045ce22..7530113eb48 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.6.beta2, Release Date: 2024-12-22 +SageMath version 10.6.beta3, Release Date: 2025-01-04 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 17cdb5b906e..1c872212d2e 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,3 +1,3 @@ tarball=configure-VERSION.tar.gz -sha1=ef4815479e8a4d87305087a4a0356eec92adda02 -sha256=ef3aa92c13dba41315e922678ba1e8c01a85dacc8cdec20f21104b8bd3b7da89 +sha1=852d0d200a6a73aa5ddb9e00874cbe4a61c211e9 +sha256=c4b089d90850dfdf15b905f66e4f6a0d961b96eb0663d8603beaff1a9efb2cbe diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 85e96131ba2..093cb148078 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -c9041d0bda901b83f527a5f1398c690c18fdd935 +a2ba1f943f88775218c385efe55509c4548d1b44 diff --git a/build/pkgs/sage_conf/version_requirements.txt b/build/pkgs/sage_conf/version_requirements.txt index dac4c2ff0f5..89c6b32ac8e 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.6b2 +sage-conf ~= 10.6b3 diff --git a/build/pkgs/sage_docbuild/version_requirements.txt b/build/pkgs/sage_docbuild/version_requirements.txt index 1042c4d84b3..0db09dcea0c 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.6b2 +sage-docbuild ~= 10.6b3 diff --git a/build/pkgs/sage_setup/version_requirements.txt b/build/pkgs/sage_setup/version_requirements.txt index be5c8645b19..48a5d6a2975 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.6b2 +sage-setup ~= 10.6b3 diff --git a/build/pkgs/sage_sws2rst/version_requirements.txt b/build/pkgs/sage_sws2rst/version_requirements.txt index 734ca51955f..10fe0a5d243 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.6b2 +sage-sws2rst ~= 10.6b3 diff --git a/build/pkgs/sagelib/version_requirements.txt b/build/pkgs/sagelib/version_requirements.txt index 9db5148c938..9955b423733 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.6b2 +sagemath-standard ~= 10.6b3 diff --git a/build/pkgs/sagemath_bliss/version_requirements.txt b/build/pkgs/sagemath_bliss/version_requirements.txt index bcd0492a487..07444bffe02 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.6b2 +sagemath-bliss ~= 10.6b3 diff --git a/build/pkgs/sagemath_categories/version_requirements.txt b/build/pkgs/sagemath_categories/version_requirements.txt index 71d3e4365fb..3693bc6b268 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.6b2 +sagemath-categories ~= 10.6b3 diff --git a/build/pkgs/sagemath_coxeter3/version_requirements.txt b/build/pkgs/sagemath_coxeter3/version_requirements.txt index fc343e41411..218445145e4 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.6b2 +sagemath-coxeter3 ~= 10.6b3 diff --git a/build/pkgs/sagemath_environment/version_requirements.txt b/build/pkgs/sagemath_environment/version_requirements.txt index 837e63fe820..f8afafd91b2 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.6b2 +sagemath-environment ~= 10.6b3 diff --git a/build/pkgs/sagemath_mcqd/version_requirements.txt b/build/pkgs/sagemath_mcqd/version_requirements.txt index 21dcc676acf..c2a89dc2f8b 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.6b2 +sagemath-mcqd ~= 10.6b3 diff --git a/build/pkgs/sagemath_meataxe/version_requirements.txt b/build/pkgs/sagemath_meataxe/version_requirements.txt index 510a8736cf5..2347bb33a2a 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.6b2 +sagemath-meataxe ~= 10.6b3 diff --git a/build/pkgs/sagemath_objects/version_requirements.txt b/build/pkgs/sagemath_objects/version_requirements.txt index b5877570307..f332b86d4c1 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.6b2 +sagemath-objects ~= 10.6b3 diff --git a/build/pkgs/sagemath_repl/version_requirements.txt b/build/pkgs/sagemath_repl/version_requirements.txt index 8d7fca3395c..334e1a9cd4c 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.6b2 +sagemath-repl ~= 10.6b3 diff --git a/build/pkgs/sagemath_sirocco/version_requirements.txt b/build/pkgs/sagemath_sirocco/version_requirements.txt index 18111e8fa2d..83304b67094 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.6b2 +sagemath-sirocco ~= 10.6b3 diff --git a/build/pkgs/sagemath_tdlib/version_requirements.txt b/build/pkgs/sagemath_tdlib/version_requirements.txt index b297935ac75..162e0933241 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.6b2 +sagemath-tdlib ~= 10.6b3 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/src/VERSION.txt b/src/VERSION.txt index 61117e46f91..4b1bf4be363 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.6.beta2 +10.6.beta3 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index c21005c7881..873f0e5daf9 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.6.beta2' -SAGE_RELEASE_DATE='2024-12-22' -SAGE_VERSION_BANNER='SageMath version 10.6.beta2, Release Date: 2024-12-22' +SAGE_VERSION='10.6.beta3' +SAGE_RELEASE_DATE='2025-01-04' +SAGE_VERSION_BANNER='SageMath version 10.6.beta3, Release Date: 2025-01-04' diff --git a/src/sage/version.py b/src/sage/version.py index 73436924039..b25d448757f 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.6.beta2' -date = '2024-12-22' -banner = 'SageMath version 10.6.beta2, Release Date: 2024-12-22' +version = '10.6.beta3' +date = '2025-01-04' +banner = 'SageMath version 10.6.beta3, Release Date: 2025-01-04'