From 123f88bb25154a9f34a36807cf6570d4d6a16f94 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Wed, 16 Oct 2024 09:59:02 -0700 Subject: [PATCH 001/175] Add ability to alter individual edge thicknesses and styles of graph plots. In addition added label font sizes and allowed for shifting vertex labels when printing in a circular manner --- .vscode/settings.json | 5 +- src/sage/graphs/graph_plot.py | 127 ++++++++++++++++++++++++---------- 2 files changed, 96 insertions(+), 36 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 86eac03ffe9..f0af83697ef 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -31,5 +31,8 @@ "Cython" ], "editor.formatOnType": true, - "esbonio.sphinx.confDir": "" + "esbonio.sphinx.confDir": "", + "flake8.args": [ + "--select=E111,E21,E221,E222,E225,E227,E228,E25,E271,E303,E305,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605" + ] } diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 40b6ecc764d..25bfee7b4e4 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -181,6 +181,9 @@ 'a dictionary keyed by vertices and associating to each vertex ' 'a label string, or a function taking as input a vertex and returning ' 'a label string.', + 'vertex_label_shift': + 'If layout is circular and we have vertex labels, will shift vertices ' + 'away from center of circle in coordinate fashion `(x, y)`.', 'vertex_color': 'Default color for vertices not listed ' 'in vertex_colors dictionary.', @@ -197,10 +200,19 @@ 'Whether or not to draw edge labels.', 'edge_style': 'The linestyle of the edges. It should be ' - 'one of "solid", "dashed", "dotted", dashdot", ' + 'one of "solid", "dashed", "dotted", "dashdot", ' 'or "-", "--", ":", "-.", respectively. ', + 'edge_styles': + 'A dictionary specifying edge styles: ' + 'each key is an edge or a label (all same) and value is the linestyle ' + 'of the edge. It should be one of "solid", "dashed", "dotted", ' + '"dashdot", or "-", "--", ":", "-.", respectively.', 'edge_thickness': 'The thickness of the edges.', + 'edge_thicknesses': + 'A dictionary specifying edge thicknesses: ' + 'each key is an edge or a label (all same) and thickness of the ' + 'corresponding edge.', 'edge_color': 'The default color for edges not listed in edge_colors.', 'edge_colors': @@ -221,6 +233,8 @@ 'The max distance range to allow multiedges.', 'talk': 'Whether to display the vertices in talk mode (larger and white).', + 'label_fontsize': + 'font size of all labels', 'graph_border': 'Whether or not to draw a frame around the graph.', 'edge_labels_background': @@ -238,9 +252,12 @@ DEFAULT_PLOT_OPTIONS = { 'vertex_size' : 200, 'vertex_labels' : True, + 'vertex_label_shift' : None, 'layout' : None, 'edge_style' : 'solid', + 'edge_styles' : None, 'edge_thickness' : 1, + 'edge_thicknesses' : None, 'edge_color' : 'black', 'edge_colors' : None, 'edge_labels' : False, @@ -253,6 +270,7 @@ 'partition' : None, 'dist' : .075, 'max_dist' : 1.5, + 'label_fontsize' : 12, 'loop_size' : .075, 'edge_labels_background' : 'white'} @@ -568,9 +586,26 @@ def vfun(x): return vlabels.get(x, "") else: vfun = vlabels + # TODO: allow text options - self._plot_components['vertex_labels'] = [text(vfun(v), self._pos[v], color='black', zorder=8) - for v in self._nodelist] + if self._options['layout'] == 'circular' and self._options['vertex_label_shift'] is not None: + def pos_shift(v, shift): + return (v[0] + (v[0] * shift[0])/100, v[1] + (v[1] * shift[1])/100) + self._plot_components['vertex_labels'] = [ + text( + vfun(v), + pos_shift(self._pos[v], self._options['vertex_label_shift']), + fontsize=self._options['label_fontsize'], + color='black', + zorder=8 + ) + for v in self._nodelist + ] + else: + self._plot_components['vertex_labels'] = [ + text(vfun(v), self._pos[v], color='black', zorder=8, fontsize=self._options['label_fontsize']) + for v in self._nodelist + ] def set_edges(self, **edge_options): """ @@ -709,15 +744,20 @@ def set_edges(self, **edge_options): if self._options['edge_labels_background'] == "transparent": self._options['edge_labels_background'] = "None" - # Handle base edge options: thickness, linestyle - eoptions = {} - if 'edge_style' in self._options: - from sage.plot.misc import get_matplotlib_linestyle - eoptions['linestyle'] = get_matplotlib_linestyle( - self._options['edge_style'], - return_type='long') - if 'edge_thickness' in self._options: - eoptions['thickness'] = self._options['edge_thickness'] + # Whether a key is an edge or not: + # None => edge_x is not set + # True => keys are edges + # False => keys are labels + style_key_edges = None + thickness_key_edges = None + if isinstance(self._options['edge_styles'], dict): + for k in self._options['edge_styles']: + style_key_edges = k in self._graph.edges() + break + if isinstance(self._options['edge_thicknesses'], dict): + for k in self._options['edge_thicknesses']: + thickness_key_edges = k in self._graph.edges() + break # Set labels param to add labels on the fly labels = False @@ -812,12 +852,12 @@ def set_edges(self, **edge_options): # Now add all the loops at this vertex, varying their size for lab, col, _ in local_labels: x, y = self._pos[a][0], self._pos[a][1] - loop_size - c = circle((x, y), loop_size, rgbcolor=col, **eoptions) + c = circle((x, y), loop_size, rgbcolor=col) self._plot_components['edges'].append(c) if labels: bg = self._options['edge_labels_background'] y -= loop_size # place label at bottom of loop - t = text(lab, (x, y), background_color=bg) + t = text(lab, (x, y), background_color=bg, fontsize=self._options['label_fontsize']) self._plot_components['edge_labels'].append(t) loop_size += loop_size_increment elif len(edges_to_draw[a, b]) > 1: @@ -893,70 +933,87 @@ def even_xy(d): self._plot_components['edges'].append( arrow(path=[[odd_start, odd_xy(k), odd_end]], head=local_labels[2 * i][2], zorder=1, - rgbcolor=local_labels[2 * i][1], - **eoptions)) + rgbcolor=local_labels[2 * i][1] + )) self._plot_components['edges'].append( arrow(path=[[even_start, even_xy(k), even_end]], head=local_labels[2 * i + 1][2], zorder=1, - rgbcolor=local_labels[2 * i + 1][1], - **eoptions)) + rgbcolor=local_labels[2 * i + 1][1] + )) else: self._plot_components['edges'].append( bezier_path([[p1, odd_xy(k), p2]], zorder=1, - rgbcolor=local_labels[2 * i][1], - **eoptions)) + rgbcolor=local_labels[2 * i][1] + )) self._plot_components['edges'].append( bezier_path([[p1, even_xy(k), p2]], zorder=1, - rgbcolor=local_labels[2 * i + 1][1], - **eoptions)) + rgbcolor=local_labels[2 * i + 1][1] + )) if labels: j = k / 2.0 bg = self._options['edge_labels_background'] self._plot_components['edge_labels'].append( text(local_labels[2 * i][0], odd_xy(j), - background_color=bg)) + background_color=bg, fontsize=self._options['label_fontsize'])) self._plot_components['edge_labels'].append( text(local_labels[2 * i + 1][0], even_xy(j), - background_color=bg)) + background_color=bg, fontsize=self._options['label_fontsize'])) if len_local_labels % 2: # draw line for last odd edges_to_draw[a, b] = [local_labels[-1]] is_directed = self._graph.is_directed() for a, b in edges_to_draw: + elabel = edges_to_draw[a, b][0][0] + ecolor = edges_to_draw[a, b][0][1] + ehead = edges_to_draw[a, b][0][2] + e = (a, b, elabel) + + estyle = self._options['edge_style'] + ethickness = self._options['edge_thickness'] + if style_key_edges is not None and ((style_key_edges and e in self._options['edge_styles']) or (not style_key_edges and elabel in self._options['edge_styles'])): + estyle = style_key_edges and self._options['edge_styles'][e] or self._options['edge_styles'][elabel] + if thickness_key_edges is not None and ((thickness_key_edges and e in self._options['edge_thicknesses']) or (not thickness_key_edges and elabel in self._options['edge_thicknesses'])): + ethickness = thickness_key_edges and self._options['edge_thicknesses'][e] or self._options['edge_thicknesses'][elabel] + if self._arcdigraph: ph = self._polar_hack_for_multidigraph C, D = ph(self._pos[a], self._pos[b], self._vertex_radius) self._plot_components['edges'].append( arrow(C, D, - rgbcolor=edges_to_draw[a, b][0][1], - head=edges_to_draw[a, b][0][2], - **eoptions)) + rgbcolor=ecolor, + head=ehead, + linestyle=estyle, + thickness=ethickness)) if labels: bg = self._options['edge_labels_background'] self._plot_components['edge_labels'].append( - text(str(edges_to_draw[a, b][0][0]), + text(str(elabel), [(C[0] + D[0]) / 2., (C[1] + D[1]) / 2.], - background_color=bg)) + background_color=bg, + fontsize=self._options['label_fontsize'])) elif is_directed: self._plot_components['edges'].append( arrow(self._pos[a], self._pos[b], - rgbcolor=edges_to_draw[a, b][0][1], + rgbcolor=ecolor, arrowshorten=self._arrowshorten, - head=edges_to_draw[a, b][0][2], - **eoptions)) + head=ehead, + linestyle=estyle, + thickness=ethickness)) else: self._plot_components['edges'].append( line([self._pos[a], self._pos[b]], - rgbcolor=edges_to_draw[a, b][0][1], - **eoptions)) + rgbcolor=ecolor, + linestyle=estyle, + thickness=ethickness)) if labels and not self._arcdigraph: bg = self._options['edge_labels_background'] self._plot_components['edge_labels'].append( text(str(edges_to_draw[a, b][0][0]), [(self._pos[a][0] + self._pos[b][0]) / 2., (self._pos[a][1] + self._pos[b][1]) / 2.], - background_color=bg)) + background_color=bg, + fontsize=self._options['label_fontsize'])) def _polar_hack_for_multidigraph(self, A, B, VR): """ From 7390933191930e67e35e9157383438f0e844ede4 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Wed, 16 Oct 2024 12:19:06 -0700 Subject: [PATCH 002/175] allow style/thickness on multi-edges --- src/sage/graphs/graph_plot.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 25bfee7b4e4..fa88402c1ee 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -852,7 +852,15 @@ def set_edges(self, **edge_options): # Now add all the loops at this vertex, varying their size for lab, col, _ in local_labels: x, y = self._pos[a][0], self._pos[a][1] - loop_size - c = circle((x, y), loop_size, rgbcolor=col) + + estyle = self._options['edge_style'] + ethickness = self._options['edge_thickness'] + if style_key_edges is not None and ((style_key_edges and (x, y) in self._options['edge_styles']) or (not style_key_edges and lab in self._options['edge_styles'])): + estyle = style_key_edges and self._options['edge_styles'][(x, y)] or self._options['edge_styles'][lab] + if thickness_key_edges is not None and ((thickness_key_edges and (x, y) in self._options['edge_thicknesses']) or (not thickness_key_edges and lab in self._options['edge_thicknesses'])): + ethickness = thickness_key_edges and self._options['edge_thicknesses'][(x, y)] or self._options['edge_thicknesses'][lab] + + c = circle((x, y), loop_size, rgbcolor=col, linestyle=estyle, thickness=ethickness) self._plot_components['edges'].append(c) if labels: bg = self._options['edge_labels_background'] @@ -923,6 +931,9 @@ def even_xy(d): distance = float(max_dist) / len_local_labels for i in range(len_local_labels // 2): k = (i + 1.0) * distance + estyle = self._options['edge_style'] + ethickness = self._options['edge_thickness'] + if self._arcdigraph: vr = self._vertex_radius ph = self._polar_hack_for_multidigraph @@ -930,24 +941,33 @@ def even_xy(d): odd_end = ph(odd_xy(k), p2, vr)[1] even_start = ph(p1, even_xy(k), vr)[0] even_end = ph(even_xy(k), p2, vr)[1] + self._plot_components['edges'].append( arrow(path=[[odd_start, odd_xy(k), odd_end]], head=local_labels[2 * i][2], zorder=1, - rgbcolor=local_labels[2 * i][1] + rgbcolor=local_labels[2 * i][1], + linestyle=estyle, + thickness=ethickness )) self._plot_components['edges'].append( arrow(path=[[even_start, even_xy(k), even_end]], head=local_labels[2 * i + 1][2], zorder=1, - rgbcolor=local_labels[2 * i + 1][1] + rgbcolor=local_labels[2 * i + 1][1], + linestyle=estyle, + thickness=ethickness )) else: self._plot_components['edges'].append( bezier_path([[p1, odd_xy(k), p2]], zorder=1, - rgbcolor=local_labels[2 * i][1] + rgbcolor=local_labels[2 * i][1], + linestyle=estyle, + thickness=ethickness )) self._plot_components['edges'].append( bezier_path([[p1, even_xy(k), p2]], zorder=1, - rgbcolor=local_labels[2 * i + 1][1] + rgbcolor=local_labels[2 * i + 1][1], + linestyle=estyle, + thickness=ethickness )) if labels: j = k / 2.0 From ff7ea6456bb321379c7f23493b17c55ca909e4ee Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Thu, 17 Oct 2024 09:07:59 -0700 Subject: [PATCH 003/175] Add some examples: --- src/sage/graphs/graph_plot.py | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index fa88402c1ee..57e3fe6fe4c 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -497,6 +497,18 @@ def set_vertices(self, **vertex_options): g = graphs.PathGraph(4) P = g.graphplot(vertex_labels=lambda x: str(x % 2)) sphinx_plot(P) + + For circular layout graphs, you may shift the vertex label using coordinates:: + + sage: g = graphs.CubeGraph(4) + sage: g.plot(layout='circular', vertex_label_shift=(15, 10)) + Launched png viewer for Graphics object consisting of 49 graphics primitives + + .. PLOT:: + + g = graphs.CubeGraph(4) + P = g.graphplot(layout='circular', vertex_label_shift=(15, 10)) + sphinx_plot(P) """ # Handle base vertex options voptions = {} @@ -1422,6 +1434,18 @@ def plot(self, **kwds): D = DiGraph({0:[1,2,3], 2:[1,4], 3:[0]}) sphinx_plot(D.graphplot()) + :: + + sage: D = DiGraph({0:[1,2,3], 2:[1,4], 3:[0]}) + sage: D.graphplot(label_fontsize=20).show() + Graphics object consisting of 8 graphics primitives + + .. PLOT:: + + D = DiGraph({0:[1,2,3], 2:[1,4], 3:[0]}) + sphinx_plot(D.graphplot(label_fontsize=20)) + + :: sage: D = DiGraph(multiedges=True, sparse=True) @@ -1472,6 +1496,26 @@ def plot(self, **kwds): ....: ).plot() Graphics object consisting of 22 graphics primitives + The ``edge_styles`` option may be provided if you need only certain edges + to have certain styles:: + + sage: GP.set_edges(edge_styles={'a':'dashed', 'g':'dotted'}) + sage: GP.plot() + Graphics object consisting of 22 graphics primitives + + .. PLOT:: + + g = Graph(loops=True, multiedges=True, sparse=True) + g.add_edges([(0, 0, 'a'), (0, 0, 'b'), (0, 1, 'c'), + (0, 1, 'd'), (0, 1, 'e'), (0, 1, 'f'), + (0, 1, 'f'), (2, 1, 'g'), (2, 2, 'h')]) + GP = g.graphplot(vertex_size=100, edge_labels=True, + color_by_label=True, edge_style='dashed') + GP.set_edges(edge_style='solid') + GP.set_edges(edge_color='black') + GP.set_edges(edge_styles={'a':'dashed', 'g':'dotted'}) + sphinx_plot(GP) + TESTS: Make sure that show options work with plot also:: From 78d701b139ba5d6b940c85b5a4eb4991c161d197 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Thu, 17 Oct 2024 09:41:30 -0700 Subject: [PATCH 004/175] Add arrow size --- src/sage/graphs/graph_plot.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 57e3fe6fe4c..5b92ebbfd7c 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -227,6 +227,8 @@ 'cell in a different color; vertex_colors takes precedence.', 'loop_size': 'The radius of the smallest loop.', + 'arrowsize': + 'Size of arrows.', 'dist': 'The distance between multiedges.', 'max_dist': @@ -771,6 +773,10 @@ def set_edges(self, **edge_options): thickness_key_edges = k in self._graph.edges() break + eoptions = {} + if 'arrowsize' in self._options: + eoptions['arrowsize'] = self._options['arrowsize'] + # Set labels param to add labels on the fly labels = False if self._options['edge_labels']: @@ -959,14 +965,16 @@ def even_xy(d): head=local_labels[2 * i][2], zorder=1, rgbcolor=local_labels[2 * i][1], linestyle=estyle, - thickness=ethickness + width=ethickness, + **eoptions )) self._plot_components['edges'].append( arrow(path=[[even_start, even_xy(k), even_end]], head=local_labels[2 * i + 1][2], zorder=1, rgbcolor=local_labels[2 * i + 1][1], linestyle=estyle, - thickness=ethickness + width=ethickness, + **eoptions )) else: self._plot_components['edges'].append( @@ -1016,7 +1024,9 @@ def even_xy(d): rgbcolor=ecolor, head=ehead, linestyle=estyle, - thickness=ethickness)) + width=ethickness, + **eoptions + )) if labels: bg = self._options['edge_labels_background'] self._plot_components['edge_labels'].append( @@ -1031,7 +1041,9 @@ def even_xy(d): arrowshorten=self._arrowshorten, head=ehead, linestyle=estyle, - thickness=ethickness)) + width=ethickness, + **eoptions + )) else: self._plot_components['edges'].append( line([self._pos[a], self._pos[b]], From 20bd134ea6373a02e2f88e72f4f28a1f68c1c7b9 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Thu, 17 Oct 2024 13:49:42 -0700 Subject: [PATCH 005/175] Reorder examples and add planar layout example --- src/sage/graphs/graph_plot.py | 48 ++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 5b92ebbfd7c..46458de9efa 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -499,18 +499,6 @@ def set_vertices(self, **vertex_options): g = graphs.PathGraph(4) P = g.graphplot(vertex_labels=lambda x: str(x % 2)) sphinx_plot(P) - - For circular layout graphs, you may shift the vertex label using coordinates:: - - sage: g = graphs.CubeGraph(4) - sage: g.plot(layout='circular', vertex_label_shift=(15, 10)) - Launched png viewer for Graphics object consisting of 49 graphics primitives - - .. PLOT:: - - g = graphs.CubeGraph(4) - P = g.graphplot(layout='circular', vertex_label_shift=(15, 10)) - sphinx_plot(P) """ # Handle base vertex options voptions = {} @@ -1248,6 +1236,31 @@ def plot(self, **kwds): for u, v, l in D.edges(sort=True): D.set_edge_label(u, v, f'({u},{v})') sphinx_plot(D.graphplot(edge_labels=True, layout='circular')) + + For graphs with ``circular`` layouts, one may shift the vertex labels by + specifying coordinates to shift by:: + + sage: D = DiGraph({ + ....: 0: [1, 10, 19], 1: [8, 2], 2: [3, 6], 3: [19, 4], + ....: 4: [17, 5], 5: [6, 15], 6: [7], 7: [8, 14], 8: [9], + ....: 9: [10, 13], 10: [11], 11: [12, 18], 12: [16, 13], + ....: 13: [14], 14: [15], 15: [16], 16: [17], 17: [18], + ....: 18: [19], 19: []}) + sage: for u, v, l in D.edges(sort=True): + ....: D.set_edge_label(u, v, f'({u},{v})') + sage: D.graphplot(edge_labels=True, layout='circular', vertex_label_shift=(15,10)).show() + + .. PLOT:: + + D = DiGraph({ + 0: [1, 10, 19], 1: [8, 2], 2: [3, 6], 3: [19, 4], + 4: [17, 5], 5: [6, 15], 6: [7], 7: [8, 14], 8: [9], + 9: [10, 13], 10: [11], 11: [12, 18], 12: [16, 13], + 13: [14], 14: [15], 15: [16], 16: [17], 17: [18], + 18: [19], 19: []}) + for u, v, l in D.edges(sort=True): + D.set_edge_label(u, v, f'({u},{v})') + sphinx_plot(D.graphplot(edge_labels=True, layout='circular', vertex_label_shift=(15,10))) This example shows off the coloring of edges:: @@ -1338,6 +1351,17 @@ def plot(self, **kwds): P = g.graphplot(pos=pos, layout='spring', iterations=0).plot() sphinx_plot(P) + :: + + sage: D = graphs.CubeGraph(3) + sage: D.graphplot(layout='planar').plot() + Launched png viewer for Graphics object consisting of 21 graphics primitives + + .. PLOT:: + + D = graphs.CubeGraph(3) + sphinx_plot(D.graphplot(layout='planar')) + :: sage: G = Graph() From 53cc4e28b00820e56233202c644044b15cdaf016 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sat, 19 Oct 2024 14:26:24 +0200 Subject: [PATCH 006/175] avoid some long braid computations --- src/sage/schemes/curves/zariski_vankampen.py | 73 +++++++++++++------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/src/sage/schemes/curves/zariski_vankampen.py b/src/sage/schemes/curves/zariski_vankampen.py index f410a73f8fc..9a287cc9e4b 100755 --- a/src/sage/schemes/curves/zariski_vankampen.py +++ b/src/sage/schemes/curves/zariski_vankampen.py @@ -44,6 +44,7 @@ import itertools from copy import copy +from datetime import datetime from itertools import combinations from sage.combinat.permutation import Permutation @@ -1444,33 +1445,55 @@ def conjugate_positive_form(braid): """ B = braid.parent() d = B.strands() - braid1 = braid.super_summit_set()[0] - L1 = braid1.Tietze() - sg0 = braid.conjugating_braid(braid1) - gns = set(L1) - cuts = [j for j in range(d + 1) if j not in gns] - blocks = [] - for i in range(len(cuts) - 1): - block = [j for j in L1 if cuts[i] < j < cuts[i + 1]] - if block: - blocks.append(block) + rnf= rightnormalform(braid) + ex = rnf[-1][0] + if ex >= 0: + A1 = [B(a) for a in rnf[:-1]] + braid1 = prod(A1, B.delta() ** ex) + sg0 = B.one() + else: + A = braid.super_summit_set() + braid1 = A[0] + sg0 = braid.conjugating_braid(braid1) + if ex > 0: + blocks = list(braid1.Tietze()) + else: + L1 = braid1.Tietze() + gns = set(L1) + cuts = [j for j in range(d + 1) if j not in gns] + blocks = [] + for i in range(len(cuts) - 1): + block = [j for j in L1 if cuts[i] < j < cuts[i + 1]] + if block: + blocks.append(block) shorts = [] + oneblock = len(blocks) == 1 for a in blocks: - A = B(a).super_summit_set() - res = None - for tau in A: - sg = (sg0 * B(a) / sg0).conjugating_braid(tau) - A1 = rightnormalform(sg) - par = A1[-1][0] % 2 - A1 = [B(a) for a in A1[:-1]] - b = prod(A1, B.one()) - b1 = len(b.Tietze()) / (len(A1) + 1) - if res is None or b1 < res[3]: - res = [tau, A1, par, b1] - if res[2] == 1: - r0 = res[0].Tietze() - res[0] = B([i.sign() * (d - abs(i)) for i in r0]) - res0 = res[:2] + if sg0 == B.one(): + res0 = [B(a), []] + else: + if not oneblock: + A = B(a).super_summit_set() + res = None + t0 = datetime.now() + for j, tau in enumerate(A): + if j == 1: + sg = sg0 + else: + sg = (sg0 * B(a) / sg0).conjugating_braid(tau) + A1 = rightnormalform(sg) + par = A1[-1][0] % 2 + A1 = [B(a) for a in A1[:-1]] + b = prod(A1, B.one()) + b1 = len(b.Tietze()) / (len(A1) + 1) + if res is None or b1 < res[3]: + res = [tau, A1, par, b1] + if (datetime.now() - t0).total_seconds() > 60: + break + if res[2] == 1: + r0 = res[0].Tietze() + res[0] = B([i.sign() * (d - abs(i)) for i in r0]) + res0 = res[:2] shorts.append(res0) return shorts From 9ef96e033ed0cfabc9d4396f6f7461f811e03135 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sat, 19 Oct 2024 14:57:25 +0200 Subject: [PATCH 007/175] typo --- src/sage/schemes/curves/zariski_vankampen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/curves/zariski_vankampen.py b/src/sage/schemes/curves/zariski_vankampen.py index 9a287cc9e4b..cbba0a9ef9a 100755 --- a/src/sage/schemes/curves/zariski_vankampen.py +++ b/src/sage/schemes/curves/zariski_vankampen.py @@ -1445,7 +1445,7 @@ def conjugate_positive_form(braid): """ B = braid.parent() d = B.strands() - rnf= rightnormalform(braid) + rnf = rightnormalform(braid) ex = rnf[-1][0] if ex >= 0: A1 = [B(a) for a in rnf[:-1]] From a3ea70b5d22bd745e50739181be23b6722a82376 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Wed, 30 Oct 2024 21:32:35 +0100 Subject: [PATCH 008/175] typo in conjugate_positive_braid --- src/sage/schemes/curves/zariski_vankampen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/curves/zariski_vankampen.py b/src/sage/schemes/curves/zariski_vankampen.py index ff27d8ede58..f4b3f958575 100755 --- a/src/sage/schemes/curves/zariski_vankampen.py +++ b/src/sage/schemes/curves/zariski_vankampen.py @@ -1456,7 +1456,7 @@ def conjugate_positive_form(braid): braid1 = A[0] sg0 = braid.conjugating_braid(braid1) if ex > 0: - blocks = list(braid1.Tietze()) + blocks = [list(braid1.Tietze())] else: L1 = braid1.Tietze() gns = set(L1) From d53dccdb5210fdc129cf7875e757aa42dc430e03 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 1 Nov 2024 21:30:34 +0100 Subject: [PATCH 009/175] provide a class for partitions with bounded length and minimal part --- src/sage/combinat/partition.py | 311 ++++++++++++++++++++++++--------- 1 file changed, 233 insertions(+), 78 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 6b6a7edfa4c..d39bd9acf32 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -169,7 +169,7 @@ that the difference between two consecutive parts is between `-3` and `-1`:: - sage: Partitions(11,min_slope=-3,max_slope=-1,min_length=2,max_length=4).list() + sage: Partitions(11, min_slope=-3, max_slope=-1, min_length=2, max_length=4).list() [[7, 4], [6, 5], [6, 4, 1], [6, 3, 2], [5, 4, 2], [5, 3, 2, 1]] Partition objects can also be created individually with :class:`Partition`:: @@ -1716,24 +1716,22 @@ def next_within_bounds(self, min=[], max=None, partition_type=None): def condition(a, b): if partition_type in ('strict', 'strictly decreasing'): return a < b - 1 - elif partition_type in (None, 'weak', 'weakly decreasing'): + if partition_type in (None, 'weak', 'weakly decreasing'): return a < b - else: - raise ValueError('unrecognized partition type') + raise ValueError('unrecognized partition type') + for r in range(len(p) - 1, -1, -1): - if r == 0: - if (max is None or p[r] < max[r]): - next_p[r] += 1 - break - else: - return None - else: - if (max is None or p[r] < max[r]) and condition(p[r], p[r-1]): + if not r: + if max is None or p[r] < max[r]: next_p[r] += 1 break - else: - next_p[r] = min[r] - continue + return None + elif (max is None or p[r] < max[r]) and condition(p[r], p[r-1]): + next_p[r] += 1 + break + next_p[r] = min[r] + continue + return _Partitions(next_p) def row_standard_tableaux(self): @@ -5319,7 +5317,10 @@ def character_polynomial(self): # Replace each p_i by i*x_i-1 items = ps_mu.monomial_coefficients().items() # items contains a list of (partition, coeff) pairs - partition_to_monomial = lambda part: prod([i*x[i-1] - 1 for i in part]) + + def partition_to_monomial(part): + return prod([i*x[i-1] - 1 for i in part]) + res = [[partition_to_monomial(mc[0]), mc[1]] for mc in items] # Write things in the monomial basis @@ -5420,40 +5421,40 @@ def dimension(self, smaller=None, k=1): smaller = Partition([]) if k == 1: if smaller == Partition([]): # In this case, use the hook dimension formula - return factorial(larger.size())/prod(larger.hooks()) - else: - if not larger.contains(smaller): # easy case - return 0 - else: - # relative dimension - # Uses a formula of Olshanski, Regev, Vershik (see reference) - def inv_factorial(i): - if i < 0: - return 0 - return 1/factorial(i) - - len_range = range(larger.length()) - from sage.matrix.constructor import matrix - M = matrix(QQ, [[inv_factorial(larger.get_part(i)-smaller.get_part(j)-i+j) for i in len_range] for j in len_range]) - return factorial(larger.size()-smaller.size())*M.determinant() - else: - larger_core = larger.core(k) - smaller_core = smaller.core(k) - if smaller_core != larger_core: # easy case + return factorial(larger.size()) / prod(larger.hooks()) + if not larger.contains(smaller): # easy case return 0 - larger_quotients = larger.quotient(k) - smaller_quotients = smaller.quotient(k) - def multinomial_with_partitions(sizes, path_counts): - # count the number of ways of performing the k paths in parallel, - # if we know the total length allotted for each of the paths (sizes), and the number - # of paths for each component. A multinomial picks the ordering of the components where - # each step is taken. - return prod(path_counts) * multinomial(sizes) + # relative dimension + # Uses a formula of Olshanski, Regev, Vershik (see reference) + def inv_factorial(i): + if i < 0: + return 0 + return 1 / factorial(i) + + len_range = range(larger.length()) + from sage.matrix.constructor import matrix + M = matrix(QQ, [[inv_factorial(larger.get_part(i) - smaller.get_part(j) - i + j) + for i in len_range] for j in len_range]) + return factorial(larger.size() - smaller.size()) * M.determinant() - sizes = [larger_quotients[i].size()-smaller_quotients[i].size() for i in range(k)] - path_counts = [larger_quotients[i].dimension(smaller_quotients[i]) for i in range(k)] - return multinomial_with_partitions(sizes, path_counts) + larger_core = larger.core(k) + smaller_core = smaller.core(k) + if smaller_core != larger_core: # easy case + return 0 + larger_quotients = larger.quotient(k) + smaller_quotients = smaller.quotient(k) + + def multinomial_with_partitions(sizes, path_counts): + # count the number of ways of performing the k paths in parallel, + # if we know the total length allotted for each of the paths (sizes), and the number + # of paths for each component. A multinomial picks the ordering of the components where + # each step is taken. + return prod(path_counts) * multinomial(sizes) + + sizes = [larger_quotients[i].size() - smaller_quotients[i].size() for i in range(k)] + path_counts = [larger_quotients[i].dimension(smaller_quotients[i]) for i in range(k)] + return multinomial_with_partitions(sizes, path_counts) def plancherel_measure(self): r""" @@ -5484,7 +5485,7 @@ def plancherel_measure(self): sage: all(sum(mu.plancherel_measure() for mu in Partitions(n))==1 for n in range(10)) True """ - return self.dimension()**2/factorial(self.size()) + return self.dimension()**2 / factorial(self.size()) def outline(self, variable=None): r""" @@ -5500,7 +5501,7 @@ def outline(self, variable=None): EXAMPLES:: sage: # needs sage.symbolic - sage: [Partition([5,4]).outline()(x=i) for i in range(-10,11)] + sage: [Partition([5,4]).outline()(x=i) for i in range(-10, 11)] [10, 9, 8, 7, 6, 5, 6, 5, 6, 5, 4, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10] sage: Partition([]).outline() abs(x) @@ -5513,7 +5514,7 @@ def outline(self, variable=None): TESTS:: - sage: integrate(Partition([1]).outline()-abs(x),(x,-10,10)) # needs sage.symbolic + sage: integrate(Partition([1]).outline() - abs(x), (x, -10, 10)) # needs sage.symbolic 2 """ if variable is None: @@ -5533,7 +5534,7 @@ def dual_equivalence_graph(self, directed=False, coloring=None): following two conditions are satisfied: - In the one-line notation of the permutation `p`, the letter - `i` does not appear inbetween `i-1` and `i+1`. + `i` does not appear between `i-1` and `i+1`. - The permutation `q` is obtained from `p` by switching two of the three letters `i-1, i, i+1` (in its one-line @@ -5938,7 +5939,7 @@ class Partitions(UniqueRepresentation, Parent): and ``length``:: sage: Partitions(5, min_part=2) - Partitions of the integer 5 satisfying constraints min_part=2 + Partitions of 5 having parts at least 2 sage: Partitions(5, min_part=2).list() [[5], [3, 2]] @@ -6028,8 +6029,8 @@ class Partitions(UniqueRepresentation, Parent): sage: TestSuite(Partitions(5)).run() # needs sage.libs.flint sage: TestSuite(Partitions(5, min_part=2)).run() # needs sage.libs.flint - sage: repr( Partitions(5, min_part=2) ) - 'Partitions of the integer 5 satisfying constraints min_part=2' + sage: repr(Partitions(5, min_part=2)) + 'Partitions of 5 having parts at least 2' sage: P = Partitions(5, min_part=2) sage: P.first().parent() @@ -6067,18 +6068,26 @@ class Partitions(UniqueRepresentation, Parent): Check :issue:`15467`:: - sage: Partitions(5,parts_in=[1,2,3,4], length=4) + sage: Partitions(5, parts_in=[1,2,3,4], length=4) Traceback (most recent call last): ... - ValueError: the parameters 'parts_in', 'starting' and 'ending' cannot be combined with anything else - sage: Partitions(5,starting=[3,2], length=2) + ValueError: the parameters 'parts_in', 'starting', 'ending', 'regular' and 'restricted' cannot be combined with anything else + sage: Partitions(5, starting=[3,2], length=2) Traceback (most recent call last): ... - ValueError: the parameters 'parts_in', 'starting' and 'ending' cannot be combined with anything else - sage: Partitions(5,ending=[3,2], length=2) + ValueError: the parameters 'parts_in', 'starting', 'ending', 'regular' and 'restricted' cannot be combined with anything else + sage: Partitions(5, ending=[3,2], length=2) Traceback (most recent call last): ... - ValueError: the parameters 'parts_in', 'starting' and 'ending' cannot be combined with anything else + ValueError: the parameters 'parts_in', 'starting', 'ending', 'regular' and 'restricted' cannot be combined with anything else + sage: Partitions(5, restricted=2, length=2) + Traceback (most recent call last): + ... + ValueError: the parameters 'parts_in', 'starting', 'ending', 'regular' and 'restricted' cannot be combined with anything else + sage: Partitions(5, regular=5, length=2) + Traceback (most recent call last): + ... + ValueError: the parameters 'parts_in', 'starting', 'ending', 'regular' and 'restricted' cannot be combined with anything else sage: Partitions(NN, length=2) Traceback (most recent call last): ... @@ -6110,6 +6119,24 @@ class Partitions(UniqueRepresentation, Parent): Partitions of the integer 5 satisfying constraints inner=[2, 1], outer=[3, 2] sage: P.list() [[3, 2]] + + Check that contradictory length requirements are handled correctly:: + + sage: list(Partitions(5, max_length=1, length=3)) + Traceback (most recent call last): + ... + ValueError: do not specify the length together with the minimal or maximal length + + sage: list(Partitions(5, min_length=2, max_length=1)) + [] + + Check that :issue:`38897` is fixed:: + + sage: Partitions(40, min_length=10).cardinality() + 24000 + + sage: Partitions(40, max_length=10).cardinality() + 16928 """ @staticmethod def __classcall_private__(cls, n=None, **kwargs): @@ -6139,21 +6166,26 @@ def __classcall_private__(cls, n=None, **kwargs): if n == infinity: raise ValueError("n cannot be infinite") if isinstance(n, (int, Integer)): - if len(kwargs) == 0: + if not kwargs: return Partitions_n(n) if len(kwargs) == 1: if 'max_part' in kwargs: return PartitionsGreatestLE(n, kwargs['max_part']) + if 'min_part' in kwargs: + return PartitionsSmallestGE(n, kwargs['min_part'], 0, n) if 'length' in kwargs: return Partitions_nk(n, kwargs['length']) if (len(kwargs) > 1 and ('parts_in' in kwargs or 'starting' in kwargs or - 'ending' in kwargs)): - raise ValueError("the parameters 'parts_in', 'starting' and " + - "'ending' cannot be combined with anything else") + 'ending' in kwargs or + 'regular' in kwargs or + 'restricted' in kwargs)): + raise ValueError("the parameters 'parts_in', 'starting', " + + "'ending', 'regular' and 'restricted' " + + "cannot be combined with anything else") if 'parts_in' in kwargs: return Partitions_parts_in(n, kwargs['parts_in']) @@ -6166,6 +6198,19 @@ def __classcall_private__(cls, n=None, **kwargs): elif 'restricted' in kwargs: return RestrictedPartitions_n(n, kwargs['restricted']) + if 'length' in kwargs and ('min_length' in kwargs or 'max_length' in kwargs): + raise ValueError("do not specify the length together with the minimal or maximal length") + + if set(kwargs).issubset(['length', 'min_part', + 'min_length', 'max_length']): + if 'length' in kwargs: + return PartitionsSmallestGE(n, kwargs.get('min_part', 1), + kwargs['length'], + kwargs['length']) + return PartitionsSmallestGE(n, kwargs.get('min_part', 1), + kwargs.get('min_length', 0), + kwargs.get('max_length', n)) + # FIXME: should inherit from IntegerListLex, and implement repr, or _name as a lazy attribute kwargs['name'] = "Partitions of the integer {} satisfying constraints {}".format(n, ", ".join(["{}={}".format(key, kwargs[key]) for key in sorted(kwargs)])) @@ -7967,9 +8012,9 @@ class PartitionsInBox(Partitions): EXAMPLES:: - sage: PartitionsInBox(2,2) + sage: PartitionsInBox(2, 2) Integer partitions which fit in a 2 x 2 box - sage: PartitionsInBox(2,2).list() + sage: PartitionsInBox(2, 2).list() [[], [1], [1, 1], [2], [2, 1], [2, 2]] """ @@ -8044,7 +8089,10 @@ def list(self): return [self.element_class(self, [])] else: l = [[i] for i in range(w + 1)] - add = lambda x: [x + [i] for i in range(x[-1] + 1)] + + def add(x): + return [x + [i] for i in range(x[-1] + 1)] + for i in range(h-1): new_list = [] for element in l: @@ -8670,7 +8718,6 @@ class OrderedPartitions(Partitions): sage: OrderedPartitions(4).list() # needs sage.libs.gap [[4], [3, 1], [2, 2], [2, 1, 1], [1, 3], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]] """ - @staticmethod def __classcall_private__(cls, n, k=None): """ @@ -8784,14 +8831,123 @@ def cardinality(self): return ZZ(ans) +########################## +# Partitions Smallest GE # +########################## + +class PartitionsSmallestGE(UniqueRepresentation, IntegerListsLex): + r""" + The class of all partitions of the integer `n` having parts + at least `k` and restricted length. + + EXAMPLES:: + + sage: from sage.combinat.partition import PartitionsSmallestGE + sage: PartitionsSmallestGE(10, 2, 0, 10) + Partitions of 10 having parts at least 2 + sage: list(PartitionsSmallestGE(9, 2, 3, 4)) + [[5, 2, 2], [4, 3, 2], [3, 3, 3], [3, 2, 2, 2]] + + sage: [4,3,2,1] in PartitionsSmallestGE(10, 2, 0, 10) + False + sage: [2,2,2,2,2] in PartitionsSmallestGE(10, 2, 0, 10) + True + """ + @staticmethod + def __classcall_private__(cls, n, min_part, min_length, max_length): + """ + Normalize the input to ensure a unique representation. + + TESTS:: + + sage: from sage.combinat.partition import PartitionsSmallestGE + sage: P1 = PartitionsSmallestGE(9, 0, -1, 10) + sage: P2 = PartitionsSmallestGE(9, 1, 0, 10) + sage: P1 is P2 + True + """ + n = ZZ(n) + min_part = max(min_part, ZZ.one()) + min_length = max(min_length, ZZ.zero()) + max_length = min(max_length, n) + return super().__classcall__(cls, n, min_part, min_length, max_length) + + def __init__(self, n, min_part, min_length, max_length): + """ + Initialize ``self``. + + TESTS:: + + sage: from sage.combinat.partition import PartitionsSmallestGE + sage: p = PartitionsSmallestGE(10, 2, 0, 10) + sage: TestSuite(p).run() + """ + self._n = n + self._min_part = min_part + self._min_length = min_length + self._max_length = max_length + + IntegerListsLex.__init__(self, self._n, max_slope=0, + min_part=self._min_part, + min_length=self._min_length, + max_length=self._max_length) + + def _repr_(self): + """ + Return a string representation of ``self``. + + TESTS:: + + sage: from sage.combinat.partition import PartitionsSmallestGE + sage: PartitionsSmallestGE(9, 2, 0, 10) + Partitions of 9 having parts at least 2 + sage: PartitionsSmallestGE(9, 2, 3, 5) + Partitions of 9 having length between 3 and 5 and parts at least 2 + """ + if self._min_length == self._max_length: + return f"Partitions of {self._n} having length {self._min_length} and parts at least {self._min_part}" + if not self._min_length or (self._n and self._min_length == 1): + if self._max_length >= self._n: + return f"Partitions of {self._n} having parts at least {self._min_part}" + return f"Partitions of {self._n} having length at most {self._max_length} and parts at least {self._min_part}" + if self._max_length >= self._n: + return f"Partitions of {self._n} having length at least {self._min_length} and parts at least {self._min_part}" + return f"Partitions of {self._n} having length between {self._min_length} and {self._max_length} and parts at least {self._min_part}" + + def cardinality(self): + """ + Return the cardinality of ``self``. + + EXAMPLES:: + + sage: from sage.combinat.partition import PartitionsSmallestGE + sage: list(PartitionsSmallestGE(9, 3, 0, 2)) + [[9], [6, 3], [5, 4]] + sage: PartitionsSmallestGE(9, 3, 0, 2).cardinality() + 3 + + TESTS:: + + sage: all(PartitionsSmallestGE(n, a, b, c).cardinality() == + ....: len(list(PartitionsSmallestGE(n, a, b, c))) + ....: for n in range(6) for a in range(1, 6) for b in range(6) for c in range(6)) + True + """ + return sum(number_of_partitions_length(self._n - (self._min_part-1)*ell, ell) + for ell in range(self._min_length, self._max_length + 1)) + + Element = Partition + options = Partitions.options + + ########################## # Partitions Greatest LE # ########################## class PartitionsGreatestLE(UniqueRepresentation, IntegerListsLex): - """ - The class of all (unordered) "restricted" partitions of the integer `n` - having parts less than or equal to the integer `k`. + r""" + The class of all (unordered) "restricted" partitions of the + integer `n` having parts less than or equal to the integer `k`. EXAMPLES:: @@ -8812,7 +8968,6 @@ class PartitionsGreatestLE(UniqueRepresentation, IntegerListsLex): sage: PartitionsGreatestLE(10, 2).first().parent() Partitions... """ - def __init__(self, n, k): """ Initialize ``self``. @@ -8850,12 +9005,12 @@ def cardinality(self): TESTS:: - sage: all(PartitionsGreatestLE(n, a).cardinality() == # needs sage.libs.gap - ....: len(PartitionsGreatestLE(n, a).list()) + sage: all(PartitionsGreatestLE(n, a).cardinality() == + ....: len(list(PartitionsGreatestLE(n, a))) ....: for n in range(20) for a in range(6)) True """ - return sum(number_of_partitions_length(self.n, i) for i in range(self.k+1)) + return sum(number_of_partitions_length(self.n, i) for i in range(self.k + 1)) Element = Partition options = Partitions.options @@ -9056,9 +9211,9 @@ def _fast_iterator(self, n, max_part): sage: for n in range(10): ....: for ell in range(2, n): - ....: Pres = Partitions(n, restricted=ell) - ....: Preg = Partitions(n, regular=ell) - ....: assert set(Pres) == set(p.conjugate() for p in Preg) + ....: P_res = Partitions(n, restricted=ell) + ....: P_reg = Partitions(n, regular=ell) + ....: assert set(P_res) == set(p.conjugate() for p in P_reg) """ if n == 0: yield [] From 3578e9fd4349e0e19d3a15b8e4dc36cd5b786197 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 3 Nov 2024 22:20:47 +0100 Subject: [PATCH 010/175] update libsemigroup --- build/pkgs/libsemigroups/checksums.ini | 4 ++-- build/pkgs/libsemigroups/package-version.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/pkgs/libsemigroups/checksums.ini b/build/pkgs/libsemigroups/checksums.ini index e258d4f2058..f34a1ed428d 100644 --- a/build/pkgs/libsemigroups/checksums.ini +++ b/build/pkgs/libsemigroups/checksums.ini @@ -1,4 +1,4 @@ tarball=libsemigroups-VERSION.tar.gz -sha1=86375824b47ce4b0e23570122e873f67136d0c0a -sha256=6214fd9e87af3834ff5eb6377cde1cbef76c74b233e1b0c4d15af1d2311692b4 +sha1=9c8e73b18a4964135b63e03b2f36b874742edd62 +sha256=d4d88a11651c7d7d497f847fea97e3ff60a39b25b851c1d0d7ccf41e052612be upstream_url=https://github.com/libsemigroups/libsemigroups/releases/download/vVERSION/libsemigroups-VERSION.tar.gz diff --git a/build/pkgs/libsemigroups/package-version.txt b/build/pkgs/libsemigroups/package-version.txt index f90b1afc082..2c9b4ef42ec 100644 --- a/build/pkgs/libsemigroups/package-version.txt +++ b/build/pkgs/libsemigroups/package-version.txt @@ -1 +1 @@ -2.3.2 +2.7.3 From 7ab446e3e31c2a3e7fb7cf104dbd14ed9d0f2831 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Fri, 8 Nov 2024 17:59:49 -0700 Subject: [PATCH 011/175] Formatting --- src/sage/graphs/graph_plot.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 46458de9efa..8df71128e63 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -861,9 +861,13 @@ def set_edges(self, **edge_options): estyle = self._options['edge_style'] ethickness = self._options['edge_thickness'] - if style_key_edges is not None and ((style_key_edges and (x, y) in self._options['edge_styles']) or (not style_key_edges and lab in self._options['edge_styles'])): + if (style_key_edges is not None + and ((style_key_edges and (x, y) in self._options['edge_styles']) + or (not style_key_edges and lab in self._options['edge_styles']))): estyle = style_key_edges and self._options['edge_styles'][(x, y)] or self._options['edge_styles'][lab] - if thickness_key_edges is not None and ((thickness_key_edges and (x, y) in self._options['edge_thicknesses']) or (not thickness_key_edges and lab in self._options['edge_thicknesses'])): + if (thickness_key_edges is not None + and ((thickness_key_edges and (x, y) in self._options['edge_thicknesses']) + or (not thickness_key_edges and lab in self._options['edge_thicknesses']))): ethickness = thickness_key_edges and self._options['edge_thicknesses'][(x, y)] or self._options['edge_thicknesses'][lab] c = circle((x, y), loop_size, rgbcolor=col, linestyle=estyle, thickness=ethickness) @@ -999,9 +1003,13 @@ def even_xy(d): estyle = self._options['edge_style'] ethickness = self._options['edge_thickness'] - if style_key_edges is not None and ((style_key_edges and e in self._options['edge_styles']) or (not style_key_edges and elabel in self._options['edge_styles'])): + if (style_key_edges is not None + and ((style_key_edges and e in self._options['edge_styles']) + or (not style_key_edges and elabel in self._options['edge_styles']))): estyle = style_key_edges and self._options['edge_styles'][e] or self._options['edge_styles'][elabel] - if thickness_key_edges is not None and ((thickness_key_edges and e in self._options['edge_thicknesses']) or (not thickness_key_edges and elabel in self._options['edge_thicknesses'])): + if (thickness_key_edges is not None + and ((thickness_key_edges and e in self._options['edge_thicknesses']) + or (not thickness_key_edges and elabel in self._options['edge_thicknesses']))): ethickness = thickness_key_edges and self._options['edge_thicknesses'][e] or self._options['edge_thicknesses'][elabel] if self._arcdigraph: From 039c06bfd90bcb40c4591655812cf7a0c73e701e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 13 Nov 2024 22:01:22 +0100 Subject: [PATCH 012/175] adding an example of semiring --- src/sage/categories/examples/semirings.py | 186 ++++++++++++++++++++++ src/sage/categories/semirings.py | 20 ++- 2 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 src/sage/categories/examples/semirings.py diff --git a/src/sage/categories/examples/semirings.py b/src/sage/categories/examples/semirings.py new file mode 100644 index 00000000000..16fa6895b48 --- /dev/null +++ b/src/sage/categories/examples/semirings.py @@ -0,0 +1,186 @@ +# sage_setup: distribution = sagemath-categories +r""" +Examples of semigroups +""" +# **************************************************************************** +# Copyright (C) 2008-2009 Nicolas M. Thiery +# +# Distributed under the terms of the GNU General Public License (GPL) +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation +from sage.structure.element import Element +from sage.categories.semirings import Semirings + + +# semantic : inside NN ; +# 0 => 0, empty; +# 1 => 1, unique; +# 2 => at least 2 +_ADD = [[0, 1, 2], [1, 2, 2], [2, 2, 2]] +_PROD = [[0, 0, 0], [0, 1, 2], [0, 2, 2]] + + +class Ternary(Element): + """ + Elements of the Ternary-logic ring. + """ + def __init__(self, parent, n): + if n not in [0, 1, 2]: + raise ValueError + self._n = n + Element.__init__(self, parent) + + def _repr_(self): + return ["0", "1", "many"][self._n] + + def __eq__(self, other): + if not isinstance(other, Ternary): + return False + return self._n == other._n + + def __ne__(self, other): + return not (self == other) + + +class TernaryLogic(UniqueRepresentation, Parent): + r""" + An example of a semiring. + + This class illustrates a minimal implementation of a semiring. + + EXAMPLES:: + + sage: S = Semirings().example(); S + An example of a semiring: the ternary-logic semiring + + This is the semigroup that contains 3 objects:: + + sage: S.some_elements() + [0, 1, many] + + The product rule is as expected:: + + sage: S(1) * S(1) + 1 + sage: S(1) + S(1) + many + + TESTS:: + + sage: TestSuite(S).run(verbose=True) + running ._test_additive_associativity() . . . pass + running ._test_an_element() . . . pass + running ._test_associativity() . . . pass + running ._test_cardinality() . . . pass + running ._test_category() . . . pass + running ._test_construction() . . . pass + running ._test_distributivity() . . . pass + running ._test_elements() . . . + Running the test suite of self.an_element() + running ._test_category() . . . pass + running ._test_eq() . . . pass + running ._test_new() . . . pass + running ._test_nonzero_equal() . . . pass + running ._test_not_implemented_methods() . . . pass + running ._test_pickling() . . . pass + pass + running ._test_elements_eq_reflexive() . . . pass + running ._test_elements_eq_symmetric() . . . pass + running ._test_elements_eq_transitive() . . . pass + running ._test_elements_neq() . . . pass + running ._test_eq() . . . pass + running ._test_new() . . . pass + running ._test_not_implemented_methods() . . . pass + running ._test_one() . . . pass + running ._test_pickling() . . . pass + running ._test_prod() . . . pass + running ._test_some_elements() . . . pass + running ._test_zero() . . . pass + """ + def __init__(self): + r""" + The ternary-logic semiring. + + EXAMPLES:: + + sage: S = Semirings().example(); S + An example of a semiring: the ternary-logic semiring + """ + Parent.__init__(self, category=Semirings()) + + def _repr_(self): + r""" + EXAMPLES:: + + sage: Semirings().example()._repr_() + 'An example of a semiring: the ternary-logic semiring' + """ + return "An example of a semiring: the ternary-logic semiring" + + def __contains__(self, n) -> bool: + if isinstance(n, Ternary): + return True + return n in [0, 1, 2] + + def summation(self, x, y): + r""" + Return the sum of ``x`` and ``y`` in the semiring as per + :meth:`Semirings.ParentMethods.summation`. + + EXAMPLES:: + + sage: S = Semirings().example() + sage: S(1) + S(1) + many + """ + assert x in self + assert y in self + return self(_ADD[x._n][y._n]) + + def one(self): + """ + Return the unit of ``self``. + """ + return self(1) + + def product(self, x, y): + r""" + Return the product of ``x`` and ``y`` in the semiring as per + :meth:`Semirings.ParentMethods.product`. + + EXAMPLES:: + + sage: S = Semirings().example() + sage: S(1) * S(2) + many + """ + assert x in self + assert y in self + return self(_PROD[x._n][y._n]) + + def an_element(self): + r""" + Return an element of the semigroup. + + EXAMPLES:: + + sage: Semirings().example().an_element() + many + """ + return self(2) + + def some_elements(self): + r""" + Return a list of some elements of the semigroup. + + EXAMPLES:: + + sage: Semirings().example().some_elements() + [0, 1, many] + """ + return [self(i) for i in [0, 1, 2]] + + Element = Ternary diff --git a/src/sage/categories/semirings.py b/src/sage/categories/semirings.py index 624a867608a..bb29afe6725 100644 --- a/src/sage/categories/semirings.py +++ b/src/sage/categories/semirings.py @@ -2,12 +2,12 @@ r""" Semirngs """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 Nicolas Borie # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#****************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** from sage.categories.category_with_axiom import CategoryWithAxiom from sage.categories.magmas_and_additive_magmas import MagmasAndAdditiveMagmas @@ -50,3 +50,17 @@ class Semirings(CategoryWithAxiom): sage: TestSuite(Semirings()).run() """ _base_category_class_and_axiom = (MagmasAndAdditiveMagmas.Distributive.AdditiveAssociative.AdditiveCommutative.AdditiveUnital.Associative, "Unital") + + def example(self): + r""" + Return an example of a semiring, as per + :meth:`Category.example() + `. + + EXAMPLES:: + + sage: Semirings().example() + An example of a semiring: the ternary-logic semiring + """ + import sage.categories.examples.semirings as examples + return examples.TernaryLogic() From 553869617ff5fa0d2b4ba56beb6bab192f90653e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 14 Nov 2024 07:45:30 +0100 Subject: [PATCH 013/175] more doc --- src/sage/categories/examples/semirings.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/sage/categories/examples/semirings.py b/src/sage/categories/examples/semirings.py index 16fa6895b48..9df5653cb50 100644 --- a/src/sage/categories/examples/semirings.py +++ b/src/sage/categories/examples/semirings.py @@ -1,6 +1,6 @@ # sage_setup: distribution = sagemath-categories r""" -Examples of semigroups +Examples of semirings """ # **************************************************************************** # Copyright (C) 2008-2009 Nicolas M. Thiery @@ -26,6 +26,20 @@ class Ternary(Element): """ Elements of the Ternary-logic ring. + + The semantic is as follows: + + - 0 -- the integer 0 + - 1 -- the integer 1 + - 2 -- some integer greater than 1 + + An alternative semantic is: + + - 0 -- an empty set + - 1 -- a connected set + - 2 -- a disconnected set + + The same semantic works for graphs instead of sets. """ def __init__(self, parent, n): if n not in [0, 1, 2]: @@ -56,7 +70,7 @@ class TernaryLogic(UniqueRepresentation, Parent): sage: S = Semirings().example(); S An example of a semiring: the ternary-logic semiring - This is the semigroup that contains 3 objects:: + This is the semiring that contains 3 objects:: sage: S.some_elements() [0, 1, many] @@ -163,7 +177,7 @@ def product(self, x, y): def an_element(self): r""" - Return an element of the semigroup. + Return an element of the semiring. EXAMPLES:: @@ -174,7 +188,7 @@ def an_element(self): def some_elements(self): r""" - Return a list of some elements of the semigroup. + Return a list of some elements of the semiring. EXAMPLES:: From ce4f2b53e9e6963fd680ff570afa64bbad39eaa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 14 Nov 2024 08:17:15 +0100 Subject: [PATCH 014/175] some details --- src/sage/categories/examples/semirings.py | 4 ++-- src/sage/categories/semirings.py | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/sage/categories/examples/semirings.py b/src/sage/categories/examples/semirings.py index 9df5653cb50..380502eb489 100644 --- a/src/sage/categories/examples/semirings.py +++ b/src/sage/categories/examples/semirings.py @@ -3,7 +3,7 @@ Examples of semirings """ # **************************************************************************** -# Copyright (C) 2008-2009 Nicolas M. Thiery +# Copyright (C) 2008-2009 F. Chapoton # # Distributed under the terms of the GNU General Public License (GPL) # https://www.gnu.org/licenses/ @@ -25,7 +25,7 @@ class Ternary(Element): """ - Elements of the Ternary-logic ring. + Elements of the ternary-logic ring. The semantic is as follows: diff --git a/src/sage/categories/semirings.py b/src/sage/categories/semirings.py index bb29afe6725..d6a7bb7505e 100644 --- a/src/sage/categories/semirings.py +++ b/src/sage/categories/semirings.py @@ -1,6 +1,6 @@ # sage_setup: distribution = sagemath-categories r""" -Semirngs +Semirings """ # **************************************************************************** # Copyright (C) 2010 Nicolas Borie @@ -32,11 +32,13 @@ class Semirings(CategoryWithAxiom): sage: Semirings() Category of semirings sage: Semirings().super_categories() - [Category of associative additive commutative additive associative additive unital distributive magmas and additive magmas, + [Category of associative additive commutative additive + associative additive unital distributive magmas and additive magmas, Category of monoids] sage: sorted(Semirings().axioms()) - ['AdditiveAssociative', 'AdditiveCommutative', 'AdditiveUnital', 'Associative', 'Distributive', 'Unital'] + ['AdditiveAssociative', 'AdditiveCommutative', 'AdditiveUnital', + 'Associative', 'Distributive', 'Unital'] sage: Semirings() is (CommutativeAdditiveMonoids() & Monoids()).Distributive() True From f6423e9b4f07c1d8c365dcf2093ccf6c9135a26e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 14 Nov 2024 08:40:56 +0100 Subject: [PATCH 015/175] more doc --- src/sage/categories/examples/semirings.py | 26 ++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/sage/categories/examples/semirings.py b/src/sage/categories/examples/semirings.py index 380502eb489..a210da9480d 100644 --- a/src/sage/categories/examples/semirings.py +++ b/src/sage/categories/examples/semirings.py @@ -3,19 +3,18 @@ Examples of semirings """ # **************************************************************************** -# Copyright (C) 2008-2009 F. Chapoton +# Copyright (C) 2024 F. Chapoton # # Distributed under the terms of the GNU General Public License (GPL) # https://www.gnu.org/licenses/ # **************************************************************************** +from sage.categories.semirings import Semirings +from sage.structure.element import Element from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation -from sage.structure.element import Element -from sage.categories.semirings import Semirings - -# semantic : inside NN ; +# semantic : # 0 => 0, empty; # 1 => 1, unique; # 2 => at least 2 @@ -42,20 +41,32 @@ class Ternary(Element): The same semantic works for graphs instead of sets. """ def __init__(self, parent, n): + """ + Initialize one element. + """ if n not in [0, 1, 2]: raise ValueError self._n = n Element.__init__(self, parent) def _repr_(self): + """ + Return the string representation. + """ return ["0", "1", "many"][self._n] def __eq__(self, other): + """ + Test for equality. + """ if not isinstance(other, Ternary): return False return self._n == other._n def __ne__(self, other): + """ + Test for non-equality. + """ return not (self == other) @@ -127,6 +138,8 @@ def __init__(self): def _repr_(self): r""" + Return the string representation. + EXAMPLES:: sage: Semirings().example()._repr_() @@ -135,6 +148,9 @@ def _repr_(self): return "An example of a semiring: the ternary-logic semiring" def __contains__(self, n) -> bool: + """ + Return whether ``self`` contains the element. + """ if isinstance(n, Ternary): return True return n in [0, 1, 2] From 03d2969562ed1a9ed0320899056e24a6023b7c04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 14 Nov 2024 13:54:19 +0100 Subject: [PATCH 016/175] more doc --- src/sage/categories/examples/semirings.py | 50 ++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/sage/categories/examples/semirings.py b/src/sage/categories/examples/semirings.py index a210da9480d..bc4ca15fbcb 100644 --- a/src/sage/categories/examples/semirings.py +++ b/src/sage/categories/examples/semirings.py @@ -43,21 +43,46 @@ class Ternary(Element): def __init__(self, parent, n): """ Initialize one element. + + TESTS:: + + sage: from sage.categories.examples.semirings import TernaryLogic + sage: S = TernaryLogic() + sage: S(4) + Traceback (most recent call last): + ... + ValueError: input not in (0,1,2) """ if n not in [0, 1, 2]: - raise ValueError + raise ValueError("input not in (0,1,2)") self._n = n Element.__init__(self, parent) def _repr_(self): """ Return the string representation. + + TESTS:: + + sage: from sage.categories.examples.semirings import TernaryLogic + sage: S = TernaryLogic() + sage: [S(i) for i in range(3)] + [0, 1, many] """ return ["0", "1", "many"][self._n] def __eq__(self, other): """ Test for equality. + + TESTS:: + + sage: from sage.categories.examples.semirings import TernaryLogic + sage: S = TernaryLogic() + sage: S(1) == S(2) + False + sage: S(0) == 3 + False """ if not isinstance(other, Ternary): return False @@ -66,6 +91,13 @@ def __eq__(self, other): def __ne__(self, other): """ Test for non-equality. + + TESTS:: + + sage: from sage.categories.examples.semirings import TernaryLogic + sage: S = TernaryLogic() + sage: S(1) != S(2) + True """ return not (self == other) @@ -150,6 +182,16 @@ def _repr_(self): def __contains__(self, n) -> bool: """ Return whether ``self`` contains the element. + + EXAMPLES:: + + sage: S = Semirings().example() + sage: S(1) in S + True + sage: 2 in S + True + sage: 4 in S + False """ if isinstance(n, Ternary): return True @@ -173,6 +215,12 @@ def summation(self, x, y): def one(self): """ Return the unit of ``self``. + + EXAMPLES:: + + sage: S = Semirings().example() + sage: S.one() + 1 """ return self(1) From 98e9b4ea3aba7d241d6d8ff42afd5c9296c6a784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 14 Nov 2024 15:00:10 +0100 Subject: [PATCH 017/175] integration in the doc --- src/doc/en/reference/categories/index.rst | 1 + src/sage/categories/semirings.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/en/reference/categories/index.rst b/src/doc/en/reference/categories/index.rst index a40cca76e0f..11fcf9d4cfc 100644 --- a/src/doc/en/reference/categories/index.rst +++ b/src/doc/en/reference/categories/index.rst @@ -268,6 +268,7 @@ Examples of parents using categories sage/categories/examples/posets sage/categories/examples/semigroups sage/categories/examples/semigroups_cython + sage/categories/examples/semirings sage/categories/examples/sets_cat sage/categories/examples/sets_with_grading sage/categories/examples/with_realizations diff --git a/src/sage/categories/semirings.py b/src/sage/categories/semirings.py index d6a7bb7505e..3c90d3cfad7 100644 --- a/src/sage/categories/semirings.py +++ b/src/sage/categories/semirings.py @@ -64,5 +64,5 @@ def example(self): sage: Semirings().example() An example of a semiring: the ternary-logic semiring """ - import sage.categories.examples.semirings as examples - return examples.TernaryLogic() + from sage.categories.examples.semirings import TernaryLogic + return TernaryLogic() From 5149cdc3c3de53a8349a6e647275e0b352748186 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 19 Nov 2024 16:47:53 +0100 Subject: [PATCH 018/175] rename new class to Partitions_parts_length_restricted and generalize it to handle also max_part --- src/sage/combinat/partition.py | 202 ++++++++++++++++++++++----------- 1 file changed, 135 insertions(+), 67 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index d39bd9acf32..523dc3c781b 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -5939,7 +5939,7 @@ class Partitions(UniqueRepresentation, Parent): and ``length``:: sage: Partitions(5, min_part=2) - Partitions of 5 having parts at least 2 + Partitions of 5 whose parts are at least 2 sage: Partitions(5, min_part=2).list() [[5], [3, 2]] @@ -6030,7 +6030,7 @@ class Partitions(UniqueRepresentation, Parent): sage: TestSuite(Partitions(5, min_part=2)).run() # needs sage.libs.flint sage: repr(Partitions(5, min_part=2)) - 'Partitions of 5 having parts at least 2' + 'Partitions of 5 whose parts are at least 2' sage: P = Partitions(5, min_part=2) sage: P.first().parent() @@ -6173,7 +6173,7 @@ def __classcall_private__(cls, n=None, **kwargs): if 'max_part' in kwargs: return PartitionsGreatestLE(n, kwargs['max_part']) if 'min_part' in kwargs: - return PartitionsSmallestGE(n, kwargs['min_part'], 0, n) + return Partitions_parts_length_restricted(n, kwargs['min_part'], n, 0, n) if 'length' in kwargs: return Partitions_nk(n, kwargs['length']) @@ -6201,15 +6201,17 @@ def __classcall_private__(cls, n=None, **kwargs): if 'length' in kwargs and ('min_length' in kwargs or 'max_length' in kwargs): raise ValueError("do not specify the length together with the minimal or maximal length") - if set(kwargs).issubset(['length', 'min_part', + if set(kwargs).issubset(['length', 'min_part', 'max_part', 'min_length', 'max_length']): if 'length' in kwargs: - return PartitionsSmallestGE(n, kwargs.get('min_part', 1), - kwargs['length'], - kwargs['length']) - return PartitionsSmallestGE(n, kwargs.get('min_part', 1), - kwargs.get('min_length', 0), - kwargs.get('max_length', n)) + return Partitions_parts_length_restricted(n, kwargs.get('min_part', 1), + kwargs.get('max_part', n), + kwargs['length'], + kwargs['length']) + return Partitions_parts_length_restricted(n, kwargs.get('min_part', 1), + kwargs.get('max_part', n), + kwargs.get('min_length', 0), + kwargs.get('max_length', n)) # FIXME: should inherit from IntegerListLex, and implement repr, or _name as a lazy attribute kwargs['name'] = "Partitions of the integer {} satisfying constraints {}".format(n, ", ".join(["{}={}".format(key, kwargs[key]) for key in sorted(kwargs)])) @@ -7445,7 +7447,7 @@ def subset(self, **kwargs): sage: P = Partitions(5, length=2); P Partitions of the integer 5 of length 2 sage: P.subset(max_part=3) - Partitions of the integer 5 satisfying constraints length=2, max_part=3 + Partitions of 5 having length 2 and whose parts are at most 3 """ return Partitions(self.n, length=self.k, **kwargs) @@ -8831,66 +8833,87 @@ def cardinality(self): return ZZ(ans) -########################## -# Partitions Smallest GE # -########################## +###################################### +# Partitions_parts_length_restricted # +###################################### -class PartitionsSmallestGE(UniqueRepresentation, IntegerListsLex): +class Partitions_parts_length_restricted(UniqueRepresentation, IntegerListsLex): r""" - The class of all partitions of the integer `n` having parts - at least `k` and restricted length. + The class of all integer partitions having parts and length in a + given range. + + This class is strictly more general than + :class:`PartitionsGreatestLE`. + + INPUT: + + - ``n`` -- the size of the partition + - ``min_part`` -- the bound on the smallest part + - ``max_part`` -- the bound on the largest part + - ``min_length`` -- the lower bound on the number of parts + - ``max_length`` -- the upper bound on the number of parts EXAMPLES:: - sage: from sage.combinat.partition import PartitionsSmallestGE - sage: PartitionsSmallestGE(10, 2, 0, 10) - Partitions of 10 having parts at least 2 - sage: list(PartitionsSmallestGE(9, 2, 3, 4)) - [[5, 2, 2], [4, 3, 2], [3, 3, 3], [3, 2, 2, 2]] + sage: from sage.combinat.partition import Partitions_parts_length_restricted + sage: Partitions_parts_length_restricted(10, 2, 5, 0, 10) + Partitions of 10 whose parts are between 2 and 5 + sage: list(Partitions_parts_length_restricted(9, 2, 4, 3, 4)) + [[4, 3, 2], [3, 3, 3], [3, 2, 2, 2]] - sage: [4,3,2,1] in PartitionsSmallestGE(10, 2, 0, 10) + sage: [4,3,2,1] in Partitions_parts_length_restricted(10, 2, 10, 0, 10) False - sage: [2,2,2,2,2] in PartitionsSmallestGE(10, 2, 0, 10) + sage: [2,2,2,2,2] in Partitions_parts_length_restricted(10, 2, 10, 0, 10) True """ @staticmethod - def __classcall_private__(cls, n, min_part, min_length, max_length): + def __classcall_private__(cls, n, min_part, max_part, min_length, max_length): """ Normalize the input to ensure a unique representation. TESTS:: - sage: from sage.combinat.partition import PartitionsSmallestGE - sage: P1 = PartitionsSmallestGE(9, 0, -1, 10) - sage: P2 = PartitionsSmallestGE(9, 1, 0, 10) + sage: from sage.combinat.partition import Partitions_parts_length_restricted + sage: P1 = Partitions_parts_length_restricted(9, 0, 20, -1, 10) + sage: P2 = Partitions_parts_length_restricted(9, 1, 9, 0, 9) sage: P1 is P2 True """ n = ZZ(n) - min_part = max(min_part, ZZ.one()) - min_length = max(min_length, ZZ.zero()) - max_length = min(max_length, n) - return super().__classcall__(cls, n, min_part, min_length, max_length) - - def __init__(self, n, min_part, min_length, max_length): + if min_part <= 0: + min_part = ZZ.one() + if max_part > n: + max_part = n + if max_part < 0: + max_part = ZZ.zero() + if min_length < 0: + min_length = ZZ.zero() + if max_length > n: + max_length = n + return super().__classcall__(cls, n, min_part, max_part, min_length, max_length) + + def __init__(self, n, min_part, max_part, min_length, max_length): """ Initialize ``self``. TESTS:: - sage: from sage.combinat.partition import PartitionsSmallestGE - sage: p = PartitionsSmallestGE(10, 2, 0, 10) + sage: from sage.combinat.partition import Partitions_parts_length_restricted + sage: p = Partitions_parts_length_restricted(10, 2, 5, 3, 4) sage: TestSuite(p).run() """ self._n = n - self._min_part = min_part - self._min_length = min_length - self._max_length = max_length IntegerListsLex.__init__(self, self._n, max_slope=0, - min_part=self._min_part, - min_length=self._min_length, - max_length=self._max_length) + min_part=min_part, + max_part=max_part, + min_length=min_length, + max_length=max_length) + + self._min_part = ZZ.one() if min_part is None else min_part + self._max_part = self._n if max_part is None else max_part + self._min_length = ZZ.zero() if min_length is None else min_length + self._max_length = self._n if max_length is None else max_length def _repr_(self): """ @@ -8898,21 +8921,41 @@ def _repr_(self): TESTS:: - sage: from sage.combinat.partition import PartitionsSmallestGE - sage: PartitionsSmallestGE(9, 2, 0, 10) - Partitions of 9 having parts at least 2 - sage: PartitionsSmallestGE(9, 2, 3, 5) - Partitions of 9 having length between 3 and 5 and parts at least 2 - """ - if self._min_length == self._max_length: - return f"Partitions of {self._n} having length {self._min_length} and parts at least {self._min_part}" - if not self._min_length or (self._n and self._min_length == 1): - if self._max_length >= self._n: - return f"Partitions of {self._n} having parts at least {self._min_part}" - return f"Partitions of {self._n} having length at most {self._max_length} and parts at least {self._min_part}" - if self._max_length >= self._n: - return f"Partitions of {self._n} having length at least {self._min_length} and parts at least {self._min_part}" - return f"Partitions of {self._n} having length between {self._min_length} and {self._max_length} and parts at least {self._min_part}" + sage: from sage.combinat.partition import Partitions_parts_length_restricted + sage: Partitions_parts_length_restricted(9, 2, 9, 0, 10) + Partitions of 9 whose parts are at least 2 + sage: Partitions_parts_length_restricted(9, 2, 9, 3, 5) + Partitions of 9 having length between 3 and 5 and whose parts are at least 2 + """ + if not self._min_length and self._max_length == self._n: + length_str = "" + elif self._min_length == self._max_length: + length_str = f"having length {self._min_length}" + elif not self._min_length: + length_str = f"having length at most {self._max_length}" + elif self._max_length == self._n: + length_str = f"having length at least {self._min_length}" + else: + length_str = f"having length between {self._min_length} and {self._max_length}" + + if self._min_part == ZZ.one() and self._max_part == self._n: + parts_str = "" + elif self._min_part == self._max_part: + parts_str = f"having parts equal to {self._min_part}" + elif self._min_part == ZZ.one(): + parts_str = f"whose parts are at most {self._max_part}" + elif self._max_part == self._n: + parts_str = f"whose parts are at least {self._min_part}" + else: + parts_str = f"whose parts are between {self._min_part} and {self._max_part}" + + if length_str: + if parts_str: + return f"Partitions of {self._n} " + length_str + " and " + parts_str + return f"Partitions of {self._n} " + length_str + if parts_str: + return f"Partitions of {self._n} " + parts_str + return f"Partitions of {self._n}" def cardinality(self): """ @@ -8920,21 +8963,46 @@ def cardinality(self): EXAMPLES:: - sage: from sage.combinat.partition import PartitionsSmallestGE - sage: list(PartitionsSmallestGE(9, 3, 0, 2)) + sage: from sage.combinat.partition import Partitions_parts_length_restricted + sage: list(Partitions_parts_length_restricted(9, 3, 9, 0, 2)) [[9], [6, 3], [5, 4]] - sage: PartitionsSmallestGE(9, 3, 0, 2).cardinality() + sage: Partitions_parts_length_restricted(9, 3, 9, 0, 2).cardinality() 3 TESTS:: - sage: all(PartitionsSmallestGE(n, a, b, c).cardinality() == - ....: len(list(PartitionsSmallestGE(n, a, b, c))) - ....: for n in range(6) for a in range(1, 6) for b in range(6) for c in range(6)) - True - """ - return sum(number_of_partitions_length(self._n - (self._min_part-1)*ell, ell) - for ell in range(self._min_length, self._max_length + 1)) + sage: from itertools import product + sage: P = Partitions_parts_length_restricted + sage: all(P(n, a, b, k, m).cardinality() == len(list(P(n, a, b, k, m))) + ....: for n, a, b, k, m in product(range(-1, 5), repeat=5)) + True + """ + if not self._min_length and self._max_length == self._n and self._min_part == 1: + # unrestricted length, parts smaller max_part + return ZZ.sum(number_of_partitions_length(self._n, i) + for i in range(self._max_part + 1)) + + def partitions_len_max_part(n, b, l): + r""" + Return the number of partitions of `n` with exactly `l` parts and + the largest part at most `b`. + """ + if not n: + if not l: + return ZZ.one() + return ZZ.zero() + if not l or l > n or n > b * l: + return ZZ.zero() + if b >= n: + return number_of_partitions_length(n, l) + + return ZZ.sum(partitions_len_max_part(n - m, m, l - 1) + for m in range(1, b+1)) + + return ZZ.sum(partitions_len_max_part(self._n - (self._min_part-1)*ell, + self._max_part - self._min_part + 1, + ell) + for ell in range(self._min_length, self._max_length + 1)) Element = Partition options = Partitions.options From 1dbea255ffc5d62980662566dad50f74da06c9c4 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 19 Nov 2024 18:16:29 +0100 Subject: [PATCH 019/175] factor out number_of_partitions_length_max_part and further speedups --- src/sage/combinat/partition.py | 154 +++++++++++++++------------------ 1 file changed, 68 insertions(+), 86 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 523dc3c781b..aff55ffab91 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6173,7 +6173,7 @@ def __classcall_private__(cls, n=None, **kwargs): if 'max_part' in kwargs: return PartitionsGreatestLE(n, kwargs['max_part']) if 'min_part' in kwargs: - return Partitions_parts_length_restricted(n, kwargs['min_part'], n, 0, n) + return Partitions_parts_length_restricted(n, kwargs['min_part'], n, ZZ.zero(), n) if 'length' in kwargs: return Partitions_nk(n, kwargs['length']) @@ -6203,15 +6203,16 @@ def __classcall_private__(cls, n=None, **kwargs): if set(kwargs).issubset(['length', 'min_part', 'max_part', 'min_length', 'max_length']): + + min_part = max(kwargs.get('min_part', ZZ.one()), ZZ.one()) + max_part = max(min(kwargs.get('max_part', n), n), ZZ.zero()) if 'length' in kwargs: - return Partitions_parts_length_restricted(n, kwargs.get('min_part', 1), - kwargs.get('max_part', n), - kwargs['length'], - kwargs['length']) - return Partitions_parts_length_restricted(n, kwargs.get('min_part', 1), - kwargs.get('max_part', n), - kwargs.get('min_length', 0), - kwargs.get('max_length', n)) + k = ZZ(kwargs['length']) + return Partitions_parts_length_restricted(n, min_part, max_part, k, k) + + min_length = max(kwargs.get('min_length', ZZ.zero()), ZZ.zero()) + max_length = min(kwargs.get('max_length', n), n) + return Partitions_parts_length_restricted(n, min_part, max_part, min_length, max_length) # FIXME: should inherit from IntegerListLex, and implement repr, or _name as a lazy attribute kwargs['name'] = "Partitions of the integer {} satisfying constraints {}".format(n, ", ".join(["{}={}".format(key, kwargs[key]) for key in sorted(kwargs)])) @@ -8866,32 +8867,6 @@ class Partitions_parts_length_restricted(UniqueRepresentation, IntegerListsLex): sage: [2,2,2,2,2] in Partitions_parts_length_restricted(10, 2, 10, 0, 10) True """ - @staticmethod - def __classcall_private__(cls, n, min_part, max_part, min_length, max_length): - """ - Normalize the input to ensure a unique representation. - - TESTS:: - - sage: from sage.combinat.partition import Partitions_parts_length_restricted - sage: P1 = Partitions_parts_length_restricted(9, 0, 20, -1, 10) - sage: P2 = Partitions_parts_length_restricted(9, 1, 9, 0, 9) - sage: P1 is P2 - True - """ - n = ZZ(n) - if min_part <= 0: - min_part = ZZ.one() - if max_part > n: - max_part = n - if max_part < 0: - max_part = ZZ.zero() - if min_length < 0: - min_length = ZZ.zero() - if max_length > n: - max_length = n - return super().__classcall__(cls, n, min_part, max_part, min_length, max_length) - def __init__(self, n, min_part, max_part, min_length, max_length): """ Initialize ``self``. @@ -8903,17 +8878,12 @@ def __init__(self, n, min_part, max_part, min_length, max_length): sage: TestSuite(p).run() """ self._n = n - IntegerListsLex.__init__(self, self._n, max_slope=0, min_part=min_part, max_part=max_part, min_length=min_length, - max_length=max_length) - - self._min_part = ZZ.one() if min_part is None else min_part - self._max_part = self._n if max_part is None else max_part - self._min_length = ZZ.zero() if min_length is None else min_length - self._max_length = self._n if max_length is None else max_length + max_length=max_length, + check=False) def _repr_(self): """ @@ -8922,32 +8892,32 @@ def _repr_(self): TESTS:: sage: from sage.combinat.partition import Partitions_parts_length_restricted - sage: Partitions_parts_length_restricted(9, 2, 9, 0, 10) + sage: Partitions_parts_length_restricted(9, 2, 9, 0, 9) Partitions of 9 whose parts are at least 2 sage: Partitions_parts_length_restricted(9, 2, 9, 3, 5) Partitions of 9 having length between 3 and 5 and whose parts are at least 2 """ - if not self._min_length and self._max_length == self._n: + if not self.min_length and self.max_length == self._n: length_str = "" - elif self._min_length == self._max_length: - length_str = f"having length {self._min_length}" - elif not self._min_length: - length_str = f"having length at most {self._max_length}" - elif self._max_length == self._n: - length_str = f"having length at least {self._min_length}" + elif self.min_length == self.max_length: + length_str = f"having length {self.min_length}" + elif not self.min_length: + length_str = f"having length at most {self.max_length}" + elif self.max_length == self._n: + length_str = f"having length at least {self.min_length}" else: - length_str = f"having length between {self._min_length} and {self._max_length}" + length_str = f"having length between {self.min_length} and {self.max_length}" - if self._min_part == ZZ.one() and self._max_part == self._n: + if self.min_part == ZZ.one() and self.max_part == self._n: parts_str = "" - elif self._min_part == self._max_part: - parts_str = f"having parts equal to {self._min_part}" - elif self._min_part == ZZ.one(): - parts_str = f"whose parts are at most {self._max_part}" - elif self._max_part == self._n: - parts_str = f"whose parts are at least {self._min_part}" + elif self.min_part == self.max_part: + parts_str = f"having parts equal to {self.min_part}" + elif self.min_part == ZZ.one(): + parts_str = f"whose parts are at most {self.max_part}" + elif self.max_part == self._n: + parts_str = f"whose parts are at least {self.min_part}" else: - parts_str = f"whose parts are between {self._min_part} and {self._max_part}" + parts_str = f"whose parts are between {self.min_part} and {self.max_part}" if length_str: if parts_str: @@ -8972,37 +8942,22 @@ def cardinality(self): TESTS:: sage: from itertools import product - sage: P = Partitions_parts_length_restricted - sage: all(P(n, a, b, k, m).cardinality() == len(list(P(n, a, b, k, m))) + sage: P = Partitions + sage: all(P(n, min_part=a, max_part=b, min_length=k, max_length=m).cardinality() + ....: == len(list(P(n, min_part=a, max_part=b, min_length=k, max_length=m))) ....: for n, a, b, k, m in product(range(-1, 5), repeat=5)) True """ - if not self._min_length and self._max_length == self._n and self._min_part == 1: + n = self._n + a = self.min_part - 1 + if not self.min_length and self.max_length == n and not a: # unrestricted length, parts smaller max_part - return ZZ.sum(number_of_partitions_length(self._n, i) - for i in range(self._max_part + 1)) - - def partitions_len_max_part(n, b, l): - r""" - Return the number of partitions of `n` with exactly `l` parts and - the largest part at most `b`. - """ - if not n: - if not l: - return ZZ.one() - return ZZ.zero() - if not l or l > n or n > b * l: - return ZZ.zero() - if b >= n: - return number_of_partitions_length(n, l) - - return ZZ.sum(partitions_len_max_part(n - m, m, l - 1) - for m in range(1, b+1)) - - return ZZ.sum(partitions_len_max_part(self._n - (self._min_part-1)*ell, - self._max_part - self._min_part + 1, - ell) - for ell in range(self._min_length, self._max_length + 1)) + return ZZ.sum(number_of_partitions_length(n, i) + for i in range(self.max_part + 1)) + + m = self.max_part - self.min_part + 1 + return ZZ.sum(number_of_partitions_length_max_part(n - a * ell, ell, m) + for ell in range(self.min_length, self.max_length + 1)) Element = Partition options = Partitions.options @@ -9629,6 +9584,33 @@ def number_of_partitions_length(n, k, algorithm='hybrid'): return ZZ(libgap.NrPartitions(ZZ(n), ZZ(k))) +@cached_function +def number_of_partitions_length_max_part(n, k, b): + r""" + Return the number of partitions of `n` with exactly `k` parts and + the largest part at most `b`. + + EXAMPLES:: + + sage: from sage.combinat.partition import number_of_partitions_length_max_part + sage: number_of_partitions_length_max_part(10, 5, 3) + 3 + sage: list(Partitions(10, length=5, max_part=3)) + [[3, 3, 2, 1, 1], [3, 2, 2, 2, 1], [2, 2, 2, 2, 2]] + """ + if not n: + if not k: + return ZZ.one() + return ZZ.zero() + if not k or k > n or n > b * k: + return ZZ.zero() + if b >= n: + return number_of_partitions_length(n, k) + + return ZZ.sum(number_of_partitions_length_max_part(n - m, k - 1, m) + for m in range(1, b+1)) + + ########## # issue 14225: Partitions() is frequently used, but only weakly cached. # Hence, establish a strong reference to it. From 2b6bd44575a9e6a2420f0b141ed125d5a4d5393a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Nov 2024 17:34:13 +0800 Subject: [PATCH 020/175] Add Meson-specific settings to vscode settings By default, the Meson VS Code extension changes the paths in `settings.json` so that C++ intellisense is working. Here we set it up correctly and prevent further overwrites. --- .vscode/settings.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index bf6ab3e7c3a..4471f876f9f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -30,5 +30,11 @@ "Cython" ], "editor.formatOnType": true, - "esbonio.sphinx.confDir": "" + "esbonio.sphinx.confDir": "", + // Don't update the settings.json file with values inferred from Meson (we provide them manually) + "mesonbuild.modifySettings": false, + // Use the Meson build system for C/C++ files + "C_Cpp.default.configurationProvider": "mesonbuild.mesonbuild", + // Use the compile_commands.json file generated by Meson for IntelliSense + "C_Cpp.default.compileCommands": "${workspaceFolder}/builddir/compile_commands.json" } From f8497e93f212f5c4514fced3ffd3b038a0a7ebb3 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 20 Nov 2024 14:52:20 +0100 Subject: [PATCH 021/175] do not inherit from IntegerListsLex --- src/sage/combinat/partition.py | 100 +++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 31 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index aff55ffab91..581953e4cf1 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -8838,7 +8838,7 @@ def cardinality(self): # Partitions_parts_length_restricted # ###################################### -class Partitions_parts_length_restricted(UniqueRepresentation, IntegerListsLex): +class Partitions_parts_length_restricted(Partitions): r""" The class of all integer partitions having parts and length in a given range. @@ -8877,13 +8877,12 @@ def __init__(self, n, min_part, max_part, min_length, max_length): sage: p = Partitions_parts_length_restricted(10, 2, 5, 3, 4) sage: TestSuite(p).run() """ + Partitions.__init__(self) self._n = n - IntegerListsLex.__init__(self, self._n, max_slope=0, - min_part=min_part, - max_part=max_part, - min_length=min_length, - max_length=max_length, - check=False) + self._min_part = min_part + self._max_part = max_part + self._min_length = min_length + self._max_length = max_length def _repr_(self): """ @@ -8897,27 +8896,27 @@ def _repr_(self): sage: Partitions_parts_length_restricted(9, 2, 9, 3, 5) Partitions of 9 having length between 3 and 5 and whose parts are at least 2 """ - if not self.min_length and self.max_length == self._n: + if not self._min_length and self._max_length == self._n: length_str = "" - elif self.min_length == self.max_length: - length_str = f"having length {self.min_length}" - elif not self.min_length: - length_str = f"having length at most {self.max_length}" - elif self.max_length == self._n: - length_str = f"having length at least {self.min_length}" + elif self._min_length == self._max_length: + length_str = f"having length {self._min_length}" + elif not self._min_length: + length_str = f"having length at most {self._max_length}" + elif self._max_length == self._n: + length_str = f"having length at least {self._min_length}" else: - length_str = f"having length between {self.min_length} and {self.max_length}" + length_str = f"having length between {self._min_length} and {self._max_length}" - if self.min_part == ZZ.one() and self.max_part == self._n: + if self._min_part == ZZ.one() and self._max_part == self._n: parts_str = "" - elif self.min_part == self.max_part: - parts_str = f"having parts equal to {self.min_part}" - elif self.min_part == ZZ.one(): - parts_str = f"whose parts are at most {self.max_part}" - elif self.max_part == self._n: - parts_str = f"whose parts are at least {self.min_part}" + elif self._min_part == self._max_part: + parts_str = f"having parts equal to {self._min_part}" + elif self._min_part == ZZ.one(): + parts_str = f"whose parts are at most {self._max_part}" + elif self._max_part == self._n: + parts_str = f"whose parts are at least {self._min_part}" else: - parts_str = f"whose parts are between {self.min_part} and {self.max_part}" + parts_str = f"whose parts are between {self._min_part} and {self._max_part}" if length_str: if parts_str: @@ -8927,6 +8926,48 @@ def _repr_(self): return f"Partitions of {self._n} " + parts_str return f"Partitions of {self._n}" + def __contains__(self, x): + """ + Check if ``x`` is contained in ``self``. + + TESTS:: + + sage: P = Partitions(10, min_part=2, max_part=5, min_length=2, max_length=4) + sage: Partition([]) in P + False + + sage: Partition([3]) in P + False + + sage: Partition([5, 3, 2]) in P + True + """ + try: + mu = Partition(x) + except ValueError: + return False + return (mu.size() == self._n + and (not mu + or (min(mu) >= self._min_part + and max(mu) <= self._max_part + and self._min_length <= len(mu) <= self._max_length))) + + def __iter__(self): + """ + Iterator over the set of partitions in ``self``. + + EXAMPLES:: + + sage: list(Partitions(9, min_part=2, max_part=4, min_length=3, max_length=4)) + [[4, 3, 2], [3, 3, 3], [3, 2, 2, 2]] + """ + yield from IntegerListsLex(self._n, max_slope=0, + min_part=self._min_part, + max_part=self._max_part, + min_length=self._min_length, + max_length=self._max_length, + element_constructor=Partition) + def cardinality(self): """ Return the cardinality of ``self``. @@ -8949,18 +8990,15 @@ def cardinality(self): True """ n = self._n - a = self.min_part - 1 - if not self.min_length and self.max_length == n and not a: + a = self._min_part - 1 + if not self._min_length and self._max_length == n and not a: # unrestricted length, parts smaller max_part return ZZ.sum(number_of_partitions_length(n, i) - for i in range(self.max_part + 1)) + for i in range(self._max_part + 1)) - m = self.max_part - self.min_part + 1 + m = self._max_part - a return ZZ.sum(number_of_partitions_length_max_part(n - a * ell, ell, m) - for ell in range(self.min_length, self.max_length + 1)) - - Element = Partition - options = Partitions.options + for ell in range(self._min_length, self._max_length + 1)) ########################## From e14fd4ade71edf02442af4c893e194e386e47cb4 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 22 Nov 2024 10:17:27 +0100 Subject: [PATCH 022/175] micro optimisations in Partitions.__classcall_private__ --- src/sage/combinat/partition.py | 90 +++++++++++++++++----------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 581953e4cf1..c1e0dbf94c0 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6171,39 +6171,39 @@ def __classcall_private__(cls, n=None, **kwargs): if len(kwargs) == 1: if 'max_part' in kwargs: - return PartitionsGreatestLE(n, kwargs['max_part']) + return Partitions_parts_length_restricted(n, ZZ.one(), kwargs['max_part'], + ZZ.zero(), n) if 'min_part' in kwargs: - return Partitions_parts_length_restricted(n, kwargs['min_part'], n, ZZ.zero(), n) + return Partitions_parts_length_restricted(n, kwargs['min_part'], n, + ZZ.zero(), n) if 'length' in kwargs: return Partitions_nk(n, kwargs['length']) + if 'parts_in' in kwargs: + return Partitions_parts_in(n, kwargs['parts_in']) + if 'starting' in kwargs: + return Partitions_starting(n, kwargs['starting']) + if 'ending' in kwargs: + return Partitions_ending(n, kwargs['ending']) + if 'regular' in kwargs: + return RegularPartitions_n(n, kwargs['regular']) + if 'restricted' in kwargs: + return RestrictedPartitions_n(n, kwargs['restricted']) - if (len(kwargs) > 1 and - ('parts_in' in kwargs or - 'starting' in kwargs or - 'ending' in kwargs or - 'regular' in kwargs or - 'restricted' in kwargs)): - raise ValueError("the parameters 'parts_in', 'starting', " - + "'ending', 'regular' and 'restricted' " - + "cannot be combined with anything else") - - if 'parts_in' in kwargs: - return Partitions_parts_in(n, kwargs['parts_in']) - elif 'starting' in kwargs: - return Partitions_starting(n, kwargs['starting']) - elif 'ending' in kwargs: - return Partitions_ending(n, kwargs['ending']) - elif 'regular' in kwargs: - return RegularPartitions_n(n, kwargs['regular']) - elif 'restricted' in kwargs: - return RestrictedPartitions_n(n, kwargs['restricted']) - - if 'length' in kwargs and ('min_length' in kwargs or 'max_length' in kwargs): - raise ValueError("do not specify the length together with the minimal or maximal length") + else: + if ('parts_in' in kwargs or + 'starting' in kwargs or + 'ending' in kwargs or + 'regular' in kwargs or + 'restricted' in kwargs): + raise ValueError("the parameters 'parts_in', 'starting', " + + "'ending', 'regular' and 'restricted' " + + "cannot be combined with anything else") + + if 'length' in kwargs and ('min_length' in kwargs or 'max_length' in kwargs): + raise ValueError("do not specify the length together with the minimal or maximal length") if set(kwargs).issubset(['length', 'min_part', 'max_part', 'min_length', 'max_length']): - min_part = max(kwargs.get('min_part', ZZ.one()), ZZ.one()) max_part = max(min(kwargs.get('max_part', n), n), ZZ.zero()) if 'length' in kwargs: @@ -6240,25 +6240,27 @@ def __classcall_private__(cls, n=None, **kwargs): kwargs.get('min_length', 0)) del kwargs['inner'] return Partitions_with_constraints(n, **kwargs) - elif n is None or n is NN or n is NonNegativeIntegers(): - if len(kwargs) > 0: - if len(kwargs) == 1: + + if n is None or n is NN or n is NonNegativeIntegers(): + if not kwargs: + return Partitions_all() + + if len(kwargs) == 1: + if 'max_part' in kwargs: + return Partitions_all_bounded(kwargs['max_part']) + if 'regular' in kwargs: + return RegularPartitions_all(kwargs['regular']) + if 'restricted' in kwargs: + return RestrictedPartitions_all(kwargs['restricted']) + elif len(kwargs) == 2: + if 'regular' in kwargs: + if kwargs['regular'] < 1 or kwargs['regular'] not in ZZ: + raise ValueError("the regularity must be a positive integer") if 'max_part' in kwargs: - return Partitions_all_bounded(kwargs['max_part']) - if 'regular' in kwargs: - return RegularPartitions_all(kwargs['regular']) - if 'restricted' in kwargs: - return RestrictedPartitions_all(kwargs['restricted']) - elif len(kwargs) == 2: - if 'regular' in kwargs: - if kwargs['regular'] < 1 or kwargs['regular'] not in ZZ: - raise ValueError("the regularity must be a positive integer") - if 'max_part' in kwargs: - return RegularPartitions_bounded(kwargs['regular'], kwargs['max_part']) - if 'max_length' in kwargs: - return RegularPartitions_truncated(kwargs['regular'], kwargs['max_length']) - raise ValueError("the size must be specified with any keyword argument") - return Partitions_all() + return RegularPartitions_bounded(kwargs['regular'], kwargs['max_part']) + if 'max_length' in kwargs: + return RegularPartitions_truncated(kwargs['regular'], kwargs['max_length']) + raise ValueError("the size must be specified with any keyword argument") raise ValueError("n must be an integer or be equal to one of " "None, NN, NonNegativeIntegers()") From 4f42af7c142f7446025f47c4b0dbc2ac8146063b Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 22 Nov 2024 11:12:02 +0100 Subject: [PATCH 023/175] provide a catch-all class for partitions with unrestricted size, make PartitionsInBox accessible --- .../algebras/quantum_groups/fock_space.py | 2 +- src/sage/combinat/partition.py | 80 +++++++++++++++++-- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/sage/algebras/quantum_groups/fock_space.py b/src/sage/algebras/quantum_groups/fock_space.py index d1d98d3c184..605ed217f2f 100644 --- a/src/sage/algebras/quantum_groups/fock_space.py +++ b/src/sage/algebras/quantum_groups/fock_space.py @@ -1751,7 +1751,7 @@ def __init__(self, F): self._removable = lambda la,i: [x for x in la.corners() if la.content(*x, multicharge=F._multicharge) == i] - indices = Partitions(F._n, max_length=F._k) + indices = Partitions(max_length=F._k) CombinatorialFreeModule.__init__(self, F.base_ring(), indices, prefix='', bracket=['|', '>'], latex_bracket=['\\lvert', '\\rangle'], diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index c1e0dbf94c0..afb48c33800 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6056,7 +6056,7 @@ class Partitions(UniqueRepresentation, Parent): sage: Partitions(length=2, max_slope=-1).list() Traceback (most recent call last): ... - ValueError: the size must be specified with any keyword argument + NotImplementedError: cannot list an infinite set sage: Partitions(max_part=3) 3-Bounded Partitions @@ -6089,9 +6089,8 @@ class Partitions(UniqueRepresentation, Parent): ... ValueError: the parameters 'parts_in', 'starting', 'ending', 'regular' and 'restricted' cannot be combined with anything else sage: Partitions(NN, length=2) - Traceback (most recent call last): - ... - ValueError: the size must be specified with any keyword argument + Partitions satisfying constraints length=2 + sage: Partitions(('la','la','laaaa'), max_part=8) Traceback (most recent call last): ... @@ -6260,7 +6259,10 @@ def __classcall_private__(cls, n=None, **kwargs): return RegularPartitions_bounded(kwargs['regular'], kwargs['max_part']) if 'max_length' in kwargs: return RegularPartitions_truncated(kwargs['regular'], kwargs['max_length']) - raise ValueError("the size must be specified with any keyword argument") + elif 'max_part' in kwargs and 'max_length' in kwargs: + return PartitionsInBox(kwargs['max_length'], kwargs['max_part']) + + return Partitions_all_restricted(**kwargs) raise ValueError("n must be an integer or be equal to one of " "None, NN, NonNegativeIntegers()") @@ -6778,6 +6780,70 @@ def from_core_and_quotient(self, core, quotient): return self.element_class(self, [new_w[i]+i for i in range(len(new_w))]) +class Partitions_all_restricted(Partitions): + def __init__(self, **kwargs): + """ + TESTS:: + + sage: TestSuite(sage.combinat.partition.Partitions_all_restricted(max_length=3)).run() # long time + """ + self._restrictions = kwargs + Partitions.__init__(self, is_infinite=True) + + def __contains__(self, x): + """ + TESTS:: + + sage: P = Partitions(max_part=3, max_length=2) + sage: Partition([2,1]) in P + True + sage: [2,1] in P + True + sage: [3,2,1] in P + False + sage: [1,2] in P + False + sage: [5,1] in P + False + sage: [0] in P + True + sage: [] in P + True + """ + try: + mu = Partition(x) + except ValueError: + return False + return mu in Partitions(mu.size(), **self._restrictions) + + def _repr_(self): + """ + EXAMPLES:: + + sage: Partitions(max_part=3, max_length=4, min_length=2) + Partitions satisfying constraints max_length=4, max_part=3, min_length=2 + """ + return "Partitions satisfying constraints " + ", ".join(["{}={}".format(key, value) + for key, value in sorted(self._restrictions.items())]) + + def __iter__(self): + """ + An iterator for partitions with various restrictions. + + EXAMPLES:: + + sage: P = Partitions(max_length=2) + sage: it = iter(P) + sage: [next(it) for i in range(10)] + [[], [1], [2], [1, 1], [3], [2, 1], [4], [3, 1], [2, 2], [5]] + """ + n = 0 + while True: + for p in Partitions(n, **self._restrictions): + yield self.element_class(self, p) + n += 1 + + class Partitions_all_bounded(Partitions): def __init__(self, k): """ @@ -8021,8 +8087,10 @@ class PartitionsInBox(Partitions): Integer partitions which fit in a 2 x 2 box sage: PartitionsInBox(2, 2).list() [[], [1], [1, 1], [2], [2, 1], [2, 2]] - """ + sage: Partitions(max_part=2, max_length=3) + Integer partitions which fit in a 3 x 2 box + """ def __init__(self, h, w): """ Initialize ``self``. From 7f3dc93c862dd651e2e09b02732c5d4d1fc0bc30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 28 Nov 2024 15:41:49 +0100 Subject: [PATCH 024/175] manually adding info for meson (damn) --- src/sage/categories/examples/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/categories/examples/meson.build b/src/sage/categories/examples/meson.build index ecb63c913ba..972ad138913 100644 --- a/src/sage/categories/examples/meson.build +++ b/src/sage/categories/examples/meson.build @@ -28,6 +28,7 @@ py.install_sources( 'monoids.py', 'posets.py', 'semigroups.py', + 'semirings.py', 'sets_cat.py', 'sets_with_grading.py', 'with_realizations.py', From 5ad673fbe02ed5626d63f9247550d9f87651a2c4 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 30 Nov 2024 20:54:27 +0100 Subject: [PATCH 025/175] make helper function compute partitions with bounded parts and bounded length, better naming, better classcall_private --- src/sage/combinat/partition.py | 216 ++++++++++++++++++++++----------- 1 file changed, 146 insertions(+), 70 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index afb48c33800..5b96245234a 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6162,19 +6162,29 @@ def __classcall_private__(cls, n=None, **kwargs): sage: list(P) [[5], [1, 1, 1, 1, 1]] """ - if n == infinity: + if n is infinity: raise ValueError("n cannot be infinite") if isinstance(n, (int, Integer)): if not kwargs: return Partitions_n(n) + if n < 0: + return Partitions_n(-1) if len(kwargs) == 1: if 'max_part' in kwargs: - return Partitions_parts_length_restricted(n, ZZ.one(), kwargs['max_part'], - ZZ.zero(), n) + if not n: + return Partitions_n(0) + max_part = min(kwargs['max_part'], n) + if max_part < 1: + return Partitions_n(-1) + return Partitions_length_and_parts_restricted(n, 1, n, 1, max_part) if 'min_part' in kwargs: - return Partitions_parts_length_restricted(n, kwargs['min_part'], n, - ZZ.zero(), n) + if not n: + return Partitions_n(0) + min_part = max(kwargs['min_part'], 1) + if min_part > n: + return Partitions_n(-1) + return Partitions_length_and_parts_restricted(n, 1, n, min_part, n) if 'length' in kwargs: return Partitions_nk(n, kwargs['length']) if 'parts_in' in kwargs: @@ -6203,15 +6213,31 @@ def __classcall_private__(cls, n=None, **kwargs): if set(kwargs).issubset(['length', 'min_part', 'max_part', 'min_length', 'max_length']): - min_part = max(kwargs.get('min_part', ZZ.one()), ZZ.one()) - max_part = max(min(kwargs.get('max_part', n), n), ZZ.zero()) if 'length' in kwargs: - k = ZZ(kwargs['length']) - return Partitions_parts_length_restricted(n, min_part, max_part, k, k) - - min_length = max(kwargs.get('min_length', ZZ.zero()), ZZ.zero()) - max_length = min(kwargs.get('max_length', n), n) - return Partitions_parts_length_restricted(n, min_part, max_part, min_length, max_length) + min_length = max_length = kwargs['length'] + if not n: + if min_length: + return Partitions_n(-1) + return Partitions_n(0) + if not (1 <= min_length <= n): + return Partitions_n(-1) + else: + max_length = min(kwargs.get('max_length', n), n) + if not n: + min_length = max(kwargs.get('min_length', 0), 0) + if min_length <= 0 <= max_length: + return Partitions_n(0) + return Partitions_n(-1) + min_length = max(kwargs.get('min_length', 1), 1) + if min_length > max_length: + return Partitions_n(-1) + + min_part = max(kwargs.get('min_part', 1), 1) + max_part = min(kwargs.get('max_part', n), n) + if min_part > max_part: + return Partitions_n(-1) + + return Partitions_length_and_parts_restricted(n, min_length, max_length, min_part, max_part) # FIXME: should inherit from IntegerListLex, and implement repr, or _name as a lazy attribute kwargs['name'] = "Partitions of the integer {} satisfying constraints {}".format(n, ", ".join(["{}={}".format(key, kwargs[key]) for key in sorted(kwargs)])) @@ -8904,49 +8930,56 @@ def cardinality(self): return ZZ(ans) -###################################### -# Partitions_parts_length_restricted # -###################################### +########################################## +# Partitions_length_and_parts_restricted # +########################################## -class Partitions_parts_length_restricted(Partitions): +class Partitions_length_and_parts_restricted(Partitions): r""" The class of all integer partitions having parts and length in a given range. This class is strictly more general than - :class:`PartitionsGreatestLE`. + :class:`PartitionsGreatestLE`, except that we insist that the + size of the partition is positive and that neither the + restrictions on the parts not on the length are contradictory. INPUT: - - ``n`` -- the size of the partition - - ``min_part`` -- the bound on the smallest part - - ``max_part`` -- the bound on the largest part - - ``min_length`` -- the lower bound on the number of parts - - ``max_length`` -- the upper bound on the number of parts + - ``n`` -- the size of the partition, positive + - ``min_length`` -- the lower bound on the number of parts, between 1 and n + - ``max_length`` -- the upper bound on the number of parts, between min_length and n + - ``min_part`` -- the bound on the smallest part, between 1 and n + - ``max_part`` -- the bound on the largest part, between min_part and n EXAMPLES:: - sage: from sage.combinat.partition import Partitions_parts_length_restricted - sage: Partitions_parts_length_restricted(10, 2, 5, 0, 10) + sage: from sage.combinat.partition import Partitions_length_and_parts_restricted + sage: Partitions_length_and_parts_restricted(10, 1, 10, 2, 5) Partitions of 10 whose parts are between 2 and 5 - sage: list(Partitions_parts_length_restricted(9, 2, 4, 3, 4)) + sage: list(Partitions_length_and_parts_restricted(9, 3, 4, 2, 4)) [[4, 3, 2], [3, 3, 3], [3, 2, 2, 2]] - sage: [4,3,2,1] in Partitions_parts_length_restricted(10, 2, 10, 0, 10) + sage: [4,3,2,1] in Partitions_length_and_parts_restricted(10, 1, 10, 2, 10) False - sage: [2,2,2,2,2] in Partitions_parts_length_restricted(10, 2, 10, 0, 10) + sage: [2,2,2,2,2] in Partitions_length_and_parts_restricted(10, 1, 10, 2, 10) True + """ - def __init__(self, n, min_part, max_part, min_length, max_length): + def __init__(self, n, min_length, max_length, min_part, max_part): """ Initialize ``self``. TESTS:: - sage: from sage.combinat.partition import Partitions_parts_length_restricted - sage: p = Partitions_parts_length_restricted(10, 2, 5, 3, 4) + sage: from sage.combinat.partition import Partitions_length_and_parts_restricted + sage: p = Partitions_length_and_parts_restricted(10, 2, 5, 3, 4) sage: TestSuite(p).run() """ + if not (1 <= min_part <= max_part <= n): + raise ValueError(f"min_part (={min_part}) and max_part (={max_part}) should satisfy 1 <= min_part <= max_part <= n (={n})") + if not (1 <= min_length <= max_length <= n): + raise ValueError(f"min_length (={min_length}) and max_length (={max_length}) should satisfy 1 <= min_length <= max_length <= n (={n})") Partitions.__init__(self) self._n = n self._min_part = min_part @@ -8960,28 +8993,28 @@ def _repr_(self): TESTS:: - sage: from sage.combinat.partition import Partitions_parts_length_restricted - sage: Partitions_parts_length_restricted(9, 2, 9, 0, 9) + sage: from sage.combinat.partition import Partitions_length_and_parts_restricted + sage: Partitions_length_and_parts_restricted(9, 1, 9, 2, 9) Partitions of 9 whose parts are at least 2 - sage: Partitions_parts_length_restricted(9, 2, 9, 3, 5) + sage: Partitions_length_and_parts_restricted(9, 3, 5, 2, 9) Partitions of 9 having length between 3 and 5 and whose parts are at least 2 """ - if not self._min_length and self._max_length == self._n: + if self._min_length == 1 and self._max_length == self._n: length_str = "" elif self._min_length == self._max_length: length_str = f"having length {self._min_length}" - elif not self._min_length: + elif self._min_length == 1: length_str = f"having length at most {self._max_length}" elif self._max_length == self._n: length_str = f"having length at least {self._min_length}" else: length_str = f"having length between {self._min_length} and {self._max_length}" - if self._min_part == ZZ.one() and self._max_part == self._n: + if self._min_part == 1 and self._max_part == self._n: parts_str = "" elif self._min_part == self._max_part: parts_str = f"having parts equal to {self._min_part}" - elif self._min_part == ZZ.one(): + elif self._min_part == 1: parts_str = f"whose parts are at most {self._max_part}" elif self._max_part == self._n: parts_str = f"whose parts are at least {self._min_part}" @@ -9044,31 +9077,42 @@ def cardinality(self): EXAMPLES:: - sage: from sage.combinat.partition import Partitions_parts_length_restricted - sage: list(Partitions_parts_length_restricted(9, 3, 9, 0, 2)) + sage: from sage.combinat.partition import Partitions_length_and_parts_restricted + sage: list(Partitions_length_and_parts_restricted(9, 1, 2, 3, 9)) [[9], [6, 3], [5, 4]] - sage: Partitions_parts_length_restricted(9, 3, 9, 0, 2).cardinality() + sage: Partitions_length_and_parts_restricted(9, 1, 2, 3, 9).cardinality() 3 TESTS:: sage: from itertools import product sage: P = Partitions - sage: all(P(n, min_part=a, max_part=b, min_length=k, max_length=m).cardinality() - ....: == len(list(P(n, min_part=a, max_part=b, min_length=k, max_length=m))) - ....: for n, a, b, k, m in product(range(-1, 5), repeat=5)) + sage: all(P(n, min_length=k, max_length=m, min_part=a, max_part=b).cardinality() + ....: == len(list(P(n, min_length=k, max_length=m, min_part=a, max_part=b))) + ....: for n, k, m, a, b in product(range(-1, 5), repeat=5)) True """ n = self._n - a = self._min_part - 1 - if not self._min_length and self._max_length == n and not a: - # unrestricted length, parts smaller max_part - return ZZ.sum(number_of_partitions_length(n, i) - for i in range(self._max_part + 1)) + a = self._min_part + b = self._max_part + k = self._min_length + m = self._max_length + if a == 1: + # unrestricted min_part + if k == 1: + if m == n: + # unrestricted length, parts smaller max_part + return ZZ.sum(number_of_partitions_length(n, i) + for i in range(b + 1)) + + return number_of_partitions_max_length_max_part(n, m, b) - m = self._max_part - a - return ZZ.sum(number_of_partitions_length_max_part(n - a * ell, ell, m) - for ell in range(self._min_length, self._max_length + 1)) + return (number_of_partitions_max_length_max_part(n, m, b) + - number_of_partitions_max_length_max_part(n, k - 1, b)) + + d = b - a + return ZZ.sum(number_of_partitions_max_length_max_part(n1, min(ell, n1), min(d, n1)) + for ell in range(k, min(m, n // a) + 1) if (n1 := n - a * ell) is not None) ########################## @@ -9693,30 +9737,62 @@ def number_of_partitions_length(n, k, algorithm='hybrid'): @cached_function -def number_of_partitions_length_max_part(n, k, b): +def number_of_partitions_max_length_max_part(n, k, b): r""" - Return the number of partitions of `n` with exactly `k` parts and - the largest part at most `b`. + Return the number of partitions of `n` with at most `k` + parts, all of which are at most `b`. - EXAMPLES:: + EXAMPLES: - sage: from sage.combinat.partition import number_of_partitions_length_max_part - sage: number_of_partitions_length_max_part(10, 5, 3) - 3 - sage: list(Partitions(10, length=5, max_part=3)) - [[3, 3, 2, 1, 1], [3, 2, 2, 2, 1], [2, 2, 2, 2, 2]] + This could also be computed using the `q`-binomial coefficient:: + + sage: from sage.combinat.partition import number_of_partitions_max_length_max_part as f + sage: all(f(n, k, b) == q_binomial(k + b, b)[n] for n in range(5) for k in range(n+1) for b in range(n+1)) + True + + However, although the `q`-binomial coefficient is faster for + individual invocations, it seems that the caching we use here is + essential for some computations:: + + sage: def A(n): + ....: s1 = number_of_partitions(n) + ....: s2 = sum(Partitions(m, max_part=l, length=k).cardinality() + ....: * Partitions(n-m-l^2, min_length=k+2*l).cardinality() + ....: for l in range(1, (n+1).isqrt()) + ....: for m in range((n-l^2-2*l)*l//(l+1)+1) + ....: for k in range(ceil(m/l), min(m, n-m-l^2-2*l)+1)) + ....: return s1 + s2 + + sage: A(100) + 10934714090 """ + assert n >= 0 and k >= 0 and b >= 0, f"{n, k, b} must be non-negative" if not n: - if not k: - return ZZ.one() - return ZZ.zero() - if not k or k > n or n > b * k: + return ZZ.one() + # for best performance of the cache, it is better to pass bounds + # at most n - internally we make sure that this is the case + b = min(n, b) + k = min(n, k) + if n == k == b: + return number_of_partitions(n) + bk = b * k + if n > bk: return ZZ.zero() - if b >= n: - return number_of_partitions_length(n, k) - - return ZZ.sum(number_of_partitions_length_max_part(n - m, k - 1, m) - for m in range(1, b+1)) + if n == bk: + return ZZ.one() + if k < b: + b, k = k, b + # shortcut if k = n + if n == k: + return number_of_partitions_length(n + b, b) + + # recurse on the size of the maximal part + # for optimal caching it would be nice to keep the second argument larger + # than the third + # since k >= b > 0 we have so min(k - 1, n1) >= min(m, n1) + # except maybe for m == k == b + return sum(number_of_partitions_max_length_max_part(n1, min(k - 1, n1), min(m, n1)) + for m in range(1, b + 1) if (n1 := n - m) is not None) ########## From 95ded0c48274d1637613ae3554c3d8265e6899d9 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 30 Nov 2024 23:36:44 +0100 Subject: [PATCH 026/175] improve computation of partitions with bound on maximal part --- src/sage/combinat/partition.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 5b96245234a..b5537db6626 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -9102,8 +9102,7 @@ def cardinality(self): if k == 1: if m == n: # unrestricted length, parts smaller max_part - return ZZ.sum(number_of_partitions_length(n, i) - for i in range(b + 1)) + return number_of_partitions_length(n + b, b) return number_of_partitions_max_length_max_part(n, m, b) From 0c375f56a1ff75002e86a1ff70fe617ecab5a0d5 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 1 Dec 2024 18:25:34 +0530 Subject: [PATCH 027/175] Created file for Kahler Algebras category --- src/sage/categories/kahler_algebras.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/sage/categories/kahler_algebras.py diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py new file mode 100644 index 00000000000..b0a4802101d --- /dev/null +++ b/src/sage/categories/kahler_algebras.py @@ -0,0 +1,14 @@ +r""" +Category of Kahler Algebras. + +AUTHORS: + +- Shriya M +""" + +from sage.categories.category_types import Category_over_base_ring +class KahlerAlgebras(Category_over_base_ring): + def super_categories(self): + pass + + \ No newline at end of file From 6287bb8d80557cf42e2f14eed4e9e54249867e0a Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 3 Dec 2024 17:57:27 +0530 Subject: [PATCH 028/175] Added poincare_pairing() method --- src/sage/categories/kahler_algebras.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index b0a4802101d..639d334e089 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -7,8 +7,20 @@ """ from sage.categories.category_types import Category_over_base_ring +from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis + class KahlerAlgebras(Category_over_base_ring): - def super_categories(self): - pass + class ParentMethods: + def super_categories(self): + return GradedAlgebrasWithBasis + def poincare_pairing(self, a, b, r): + if (a.homogeneous_degree() <= (r/2)) & (b.homogeneous_degree() == (r - a.homogeneous_degree())): + el = a*b + return el.degree() + + + + + \ No newline at end of file From 880e6ef20b16bf00831422cd9823692ed610aee6 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 9 Dec 2024 21:29:26 +0530 Subject: [PATCH 029/175] Added methods in kahler algebras category --- src/sage/categories/kahler_algebras.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 639d334e089..b42f55e52ae 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -8,6 +8,7 @@ from sage.categories.category_types import Category_over_base_ring from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis +from abc import abstractmethod class KahlerAlgebras(Category_over_base_ring): class ParentMethods: @@ -17,7 +18,20 @@ def poincare_pairing(self, a, b, r): if (a.homogeneous_degree() <= (r/2)) & (b.homogeneous_degree() == (r - a.homogeneous_degree())): el = a*b return el.degree() - + @abstractmethod + def lefschetz_element(self): + pass + + def lefschetz_element(self, el, a, r): + if a.homogeneous_degree() < r/2: + return a*el + + def hodge_riemann_relations(self, el, a, r): + if a.homogeneous_degree() <= r/2: + element = a*(el**(r-(2*a.homogeneous_degree())))*a + return element.degree() + + From ea541dc50c44978f9ff2c4b294f5d28dabba6431 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 10 Dec 2024 12:31:29 +0530 Subject: [PATCH 030/175] Modified super_categories() method --- src/sage/categories/kahler_algebras.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index b42f55e52ae..20d61965107 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -8,24 +8,26 @@ from sage.categories.category_types import Category_over_base_ring from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis -from abc import abstractmethod +from sage.misc.abstract_method import abstract_method class KahlerAlgebras(Category_over_base_ring): class ParentMethods: def super_categories(self): - return GradedAlgebrasWithBasis + return [GradedAlgebrasWithBasis(self.base_ring())] + def poincare_pairing(self, a, b, r): if (a.homogeneous_degree() <= (r/2)) & (b.homogeneous_degree() == (r - a.homogeneous_degree())): el = a*b return el.degree() - @abstractmethod - def lefschetz_element(self): + + @abstract_method + def lefschetz_element(): pass - def lefschetz_element(self, el, a, r): + def lefschetz_element_injection(self, el, a, r): if a.homogeneous_degree() < r/2: return a*el - + def hodge_riemann_relations(self, el, a, r): if a.homogeneous_degree() <= r/2: element = a*(el**(r-(2*a.homogeneous_degree())))*a From d8f514e6cdd180459c4110327e0e729d88fcb028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 10 Dec 2024 11:19:48 +0100 Subject: [PATCH 031/175] suggested simplifications done --- src/sage/categories/examples/semirings.py | 21 +++------------------ src/sage/categories/semirings.py | 16 ++-------------- 2 files changed, 5 insertions(+), 32 deletions(-) diff --git a/src/sage/categories/examples/semirings.py b/src/sage/categories/examples/semirings.py index bc4ca15fbcb..eb5c02c2be7 100644 --- a/src/sage/categories/examples/semirings.py +++ b/src/sage/categories/examples/semirings.py @@ -179,24 +179,6 @@ def _repr_(self): """ return "An example of a semiring: the ternary-logic semiring" - def __contains__(self, n) -> bool: - """ - Return whether ``self`` contains the element. - - EXAMPLES:: - - sage: S = Semirings().example() - sage: S(1) in S - True - sage: 2 in S - True - sage: 4 in S - False - """ - if isinstance(n, Ternary): - return True - return n in [0, 1, 2] - def summation(self, x, y): r""" Return the sum of ``x`` and ``y`` in the semiring as per @@ -262,3 +244,6 @@ def some_elements(self): return [self(i) for i in [0, 1, 2]] Element = Ternary + + +Example = TernaryLogic diff --git a/src/sage/categories/semirings.py b/src/sage/categories/semirings.py index f41bf591d26..2bf0ea988dc 100644 --- a/src/sage/categories/semirings.py +++ b/src/sage/categories/semirings.py @@ -50,19 +50,7 @@ class Semirings(CategoryWithAxiom): TESTS:: sage: TestSuite(Semirings()).run() + sage: Semirings().example() + An example of a semiring: the ternary-logic semiring """ _base_category_class_and_axiom = (MagmasAndAdditiveMagmas.Distributive.AdditiveAssociative.AdditiveCommutative.AdditiveUnital.Associative, "Unital") - - def example(self): - r""" - Return an example of a semiring, as per - :meth:`Category.example() - `. - - EXAMPLES:: - - sage: Semirings().example() - An example of a semiring: the ternary-logic semiring - """ - from sage.categories.examples.semirings import TernaryLogic - return TernaryLogic() From 42cf2db5a69343e779ec3342a9100c0e3e3d4bd6 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 12 Dec 2024 10:11:48 +0530 Subject: [PATCH 032/175] Changed chow_ring() category and modified poincare_pairing() method --- src/sage/categories/kahler_algebras.py | 52 ++++++++++++++++++-------- src/sage/matroids/chow_ring.py | 4 +- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 20d61965107..a7bd1a5a3a4 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -9,29 +9,51 @@ from sage.categories.category_types import Category_over_base_ring from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.misc.abstract_method import abstract_method +from sage.quadratic_forms.quadratic_form import QuadraticForm class KahlerAlgebras(Category_over_base_ring): - class ParentMethods: - def super_categories(self): + r""" + The category of graded algebras satisfying the Kähler package. + + EXAMPLES:: + + sage: C = KahlerAlgebras(QQ); C + Category of kahler algebras over Rational Field + sage: sorted(C.super_categories(), key=str) + [Category of graded algebras with basis over Rational Field] + + TESTS:: + + sage: C = KahlerAlgebras(QQ) + sage: TestSuite(C).run() + """ + def super_categories(self): return [GradedAlgebrasWithBasis(self.base_ring())] - def poincare_pairing(self, a, b, r): - if (a.homogeneous_degree() <= (r/2)) & (b.homogeneous_degree() == (r - a.homogeneous_degree())): - el = a*b - return el.degree() + class ParentMethods: + def poincare_pairing(self, el1, el2, r): + hom_components1 = el1.lift().homogeneous_components() + hom_components2 = el2.lift().homogeneous_components() + new_el = self.base_ring().zero() + for i in hom_components1: + for j in hom_components2: + if i == r - j: + new_el += hom_components1[i] * hom_components2[j] + # the 'else' case is new_el += self.base_ring().zero() + return new_el.degree() @abstract_method def lefschetz_element(): pass - - def lefschetz_element_injection(self, el, a, r): - if a.homogeneous_degree() < r/2: - return a*el - - def hodge_riemann_relations(self, el, a, r): - if a.homogeneous_degree() <= r/2: - element = a*(el**(r-(2*a.homogeneous_degree())))*a - return element.degree() + + def hodge_riemann_relations(self, k, lefschetz_el, r): + basis_k = self.basis(d=k) + coeff = [] + for el, i in enumerate(basis_k): + for j in range(i+1, len(basis_k)): + coeff.append((el*(lefschetz_el**(r-(2*k))*basis_k[j])).degree()) + return QuadraticForm(self.base_ring(), len(basis_k), coeff) + diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 173c8db7f84..a5916991bf2 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -8,7 +8,7 @@ from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug, AugmentedChowRingIdeal_fy, AugmentedChowRingIdeal_atom_free from sage.rings.quotient_ring import QuotientRing_generic -from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis +from sage.categories.kahler_algebras import KahlerAlgebras from sage.categories.commutative_rings import CommutativeRings class ChowRing(QuotientRing_generic): @@ -95,7 +95,7 @@ def __init__(self, R, M, augmented, presentation=None): self._ideal = AugmentedChowRingIdeal_atom_free(M, R) else: self._ideal = ChowRingIdeal_nonaug(M, R) - C = CommutativeRings().Quotients() & GradedAlgebrasWithBasis(R).FiniteDimensional() + C = CommutativeRings().Quotients() & KahlerAlgebras(R).FiniteDimensional() QuotientRing_generic.__init__(self, R=self._ideal.ring(), I=self._ideal, names=self._ideal.ring().variable_names(), From ebc32bab6ee812731820d62bf363e4e124e6089e Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 12 Dec 2024 10:17:15 +0530 Subject: [PATCH 033/175] Formatted kahler_algebras.py document --- src/sage/categories/kahler_algebras.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index a7bd1a5a3a4..640693e0fd6 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -52,13 +52,4 @@ def hodge_riemann_relations(self, k, lefschetz_el, r): for el, i in enumerate(basis_k): for j in range(i+1, len(basis_k)): coeff.append((el*(lefschetz_el**(r-(2*k))*basis_k[j])).degree()) - return QuadraticForm(self.base_ring(), len(basis_k), coeff) - - - - - - - - - \ No newline at end of file + return QuadraticForm(self.base_ring(), len(basis_k), coeff) \ No newline at end of file From 80aa41f856d53d990e843307f5038aa19a1989ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 13 Dec 2024 11:33:33 +0100 Subject: [PATCH 034/175] change ore_algebra package to latest version --- build/pkgs/ore_algebra/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/ore_algebra/requirements.txt b/build/pkgs/ore_algebra/requirements.txt index 3b6d6cc56ff..2df654052a2 100644 --- a/build/pkgs/ore_algebra/requirements.txt +++ b/build/pkgs/ore_algebra/requirements.txt @@ -1 +1 @@ -git+https://github.com/mkauers/ore_algebra@01c357f590685ff362c008229681ee08269457da#egg=ore_algebra +ore_algebra @ git+https://github.com/mkauers/ore_algebra From 086f8190af730358fff901fa2e8a132eb64a9549 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Sat, 14 Dec 2024 14:49:55 -0700 Subject: [PATCH 035/175] Remove vscode settings that I accidentally edited --- .vscode/settings.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5aca26d9dce..c38aafb376d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -110,8 +110,5 @@ "zmin" ], "editor.formatOnType": true, - "esbonio.sphinx.confDir": "", - "flake8.args": [ - "--select=E111,E21,E221,E222,E225,E227,E228,E25,E271,E303,E305,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605" - ] + "esbonio.sphinx.confDir": "" } From 9d78cd4a1dcb3878c9baf91fd8bc6aec411fab1e Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Sat, 14 Dec 2024 15:10:45 -0700 Subject: [PATCH 036/175] Fix code style --- src/sage/graphs/graph_plot.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 8df71128e63..74a41ec9d8c 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -863,13 +863,13 @@ def set_edges(self, **edge_options): ethickness = self._options['edge_thickness'] if (style_key_edges is not None and ((style_key_edges and (x, y) in self._options['edge_styles']) - or (not style_key_edges and lab in self._options['edge_styles']))): + or (not style_key_edges and lab in self._options['edge_styles']))): estyle = style_key_edges and self._options['edge_styles'][(x, y)] or self._options['edge_styles'][lab] - if (thickness_key_edges is not None - and ((thickness_key_edges and (x, y) in self._options['edge_thicknesses']) - or (not thickness_key_edges and lab in self._options['edge_thicknesses']))): + if (thickness_key_edges is not None + and ((thickness_key_edges and (x, y) in self._options['edge_thicknesses']) + or (not thickness_key_edges and lab in self._options['edge_thicknesses']))): ethickness = thickness_key_edges and self._options['edge_thicknesses'][(x, y)] or self._options['edge_thicknesses'][lab] - + c = circle((x, y), loop_size, rgbcolor=col, linestyle=estyle, thickness=ethickness) self._plot_components['edges'].append(c) if labels: @@ -1244,7 +1244,7 @@ def plot(self, **kwds): for u, v, l in D.edges(sort=True): D.set_edge_label(u, v, f'({u},{v})') sphinx_plot(D.graphplot(edge_labels=True, layout='circular')) - + For graphs with ``circular`` layouts, one may shift the vertex labels by specifying coordinates to shift by:: @@ -1364,7 +1364,7 @@ def plot(self, **kwds): sage: D = graphs.CubeGraph(3) sage: D.graphplot(layout='planar').plot() Launched png viewer for Graphics object consisting of 21 graphics primitives - + .. PLOT:: D = graphs.CubeGraph(3) From 3dbe8779b7af730ebcf28091fac33b5b8d26136b Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Sun, 15 Dec 2024 09:39:59 -0700 Subject: [PATCH 037/175] Fix graph_plot docs --- src/sage/graphs/graph_plot.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 74a41ec9d8c..6a73062fbcd 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -1363,7 +1363,7 @@ def plot(self, **kwds): sage: D = graphs.CubeGraph(3) sage: D.graphplot(layout='planar').plot() - Launched png viewer for Graphics object consisting of 21 graphics primitives + Graphics object consisting of 21 graphics primitives .. PLOT:: @@ -1482,7 +1482,6 @@ def plot(self, **kwds): sage: D = DiGraph({0:[1,2,3], 2:[1,4], 3:[0]}) sage: D.graphplot(label_fontsize=20).show() - Graphics object consisting of 8 graphics primitives .. PLOT:: @@ -1534,6 +1533,7 @@ def plot(self, **kwds): The ``edge_style`` option may be provided in the short format too:: + sage: g.graphplot(edge_labels=True, ....: color_by_label=True, ....: edge_style='--' @@ -1543,6 +1543,12 @@ def plot(self, **kwds): The ``edge_styles`` option may be provided if you need only certain edges to have certain styles:: + sage: g = Graph(loops=True, multiedges=True, sparse=True) + sage: g.add_edges([(0, 0, 'a'), (0, 0, 'b'), (0, 1, 'c'), + ....: (0, 1, 'd'), (0, 1, 'e'), (0, 1, 'f'), + ....: (0, 1, 'f'), (2, 1, 'g'), (2, 2, 'h')]) + sage: GP = g.graphplot(vertex_size=100, edge_labels=True, + ....: color_by_label=True, edge_style='dashed') sage: GP.set_edges(edge_styles={'a':'dashed', 'g':'dotted'}) sage: GP.plot() Graphics object consisting of 22 graphics primitives From d11e5c477ef467137859dd32cae45d1e7512ba3a Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Sun, 15 Dec 2024 20:39:04 +0100 Subject: [PATCH 038/175] using new libbraiding --- .../ordered_arrangement.py | 5 +- .../schemes/curves/plane_curve_arrangement.py | 6 +-- src/sage/schemes/curves/projective_curve.py | 5 +- src/sage/schemes/curves/zariski_vankampen.py | 48 +++++++------------ 4 files changed, 24 insertions(+), 40 deletions(-) diff --git a/src/sage/geometry/hyperplane_arrangement/ordered_arrangement.py b/src/sage/geometry/hyperplane_arrangement/ordered_arrangement.py index c0024f4c982..87774ec64ab 100644 --- a/src/sage/geometry/hyperplane_arrangement/ordered_arrangement.py +++ b/src/sage/geometry/hyperplane_arrangement/ordered_arrangement.py @@ -394,7 +394,6 @@ def projective_fundamental_group(self): < x0, x1, x2, x3, x4 | x4^-1*x3^-1*x2^-1*x3*x4*x0*x2*x0^-1, x4^-1*x2^-1*x4*x2, x4^-1*x1^-1*x0^-1*x1*x4*x0, x4^-1*x1^-1*x0^-1*x4*x0*x1, - x4^-1*x1^-1*x3*x0*x1*x3^-1*x2^-1*x4*x0^-1*x2, x3^-1*x2^-1*x1^-1*x0^-1*x3*x0*x1*x2, x3^-1*x1^-1*x3*x1 > sage: G3.abelian_invariants() @@ -406,9 +405,7 @@ def projective_fundamental_group(self): < x0, x1, x2, x3, x4 | x4^-1*x3^-1*x2^-1*x3*x4*x0*x2*x0^-1, x4^-1*x2^-1*x4*x2, x4^-1*x1^-1*x0^-1*x1*x4*x0, x4^-1*x1^-1*x0^-1*x4*x0*x1, - x4^-1*x1^-1*x3*x0*x1*x3^-1*x2^-1*x4*x0^-1*x2, - x3^-1*x2^-1*x1^-1*x0^-1*x3*x0*x1*x2, - x3^-1*x1^-1*x3*x1 > + x3^-1*x2^-1*x1^-1*x0^-1*x3*x0*x1*x2, x3^-1*x1^-1*x3*x1 > sage: G4.abelian_invariants() (0, 0, 0, 0, 0) diff --git a/src/sage/schemes/curves/plane_curve_arrangement.py b/src/sage/schemes/curves/plane_curve_arrangement.py index 63e8d03f556..a13faab50bc 100755 --- a/src/sage/schemes/curves/plane_curve_arrangement.py +++ b/src/sage/schemes/curves/plane_curve_arrangement.py @@ -513,7 +513,7 @@ def fundamental_group(self, simplified=True, vertical=True, {0: [x1, x2], 1: [x0], 2: [x3], 3: [x3^-1*x2^-1*x1^-1*x0^-1]} sage: A.fundamental_group(vertical=False) Finitely presented group - < x0, x1, x2 | x2^-1*x1^-1*x2*x1, x1*x0*x1^-1*x0^-1, (x0*x2)^2*(x0^-1*x2^-1)^2 > + < x0, x1, x2 | x2*x1^-1*x2^-1*x1, x1*x0*x1^-1*x0^-1, (x0*x2)^2*(x0^-1*x2^-1)^2 > sage: A.meridians(vertical=False) {0: [x2, x0*x2*x0^-1], 1: [x1], 2: [x0], 3: [x0*x2^-1*x0^-1*x2^-1*x1^-1*x0^-1]} sage: G = A.fundamental_group(simplified=False, vertical=False) @@ -834,7 +834,7 @@ def fundamental_group(self, simplified=True): sage: A.fundamental_group().sorted_presentation() Finitely presented group < x0, x1 | x1^-1*x0^-1*x1*x0 > sage: A.meridians() - {0: [x1], 1: [x0], 2: [x1^-1*x0^-1*x1^-1]} + {0: [x1], 1: [x0], 2: [x0^-1*x1^-2]} sage: G = A.fundamental_group(simplified=False) sage: G.sorted_presentation() Finitely presented group @@ -945,7 +945,7 @@ def meridians(self, simplified=True): sage: A.fundamental_group().sorted_presentation() Finitely presented group < x0, x1 | x1^-1*x0^-1*x1*x0 > sage: A.meridians() - {0: [x1], 1: [x0], 2: [x1^-1*x0^-1*x1^-1]} + {0: [x1], 1: [x0], 2: [x0^-1*x1^-2]} sage: A = H(y^2 + x*z, z, x) sage: A.fundamental_group() Finitely presented group < x0, x1 | (x1*x0)^2*(x1^-1*x0^-1)^2 > diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index d9a7321ade4..265ff56148d 100755 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -1775,8 +1775,9 @@ def fundamental_group(self): sage: C = P.curve(x^2*z - y^3) sage: C.fundamental_group() # needs sirocco Finitely presented group < x0 | x0^3 > - sage: P.curve(z*(x^2*z - y^3)).fundamental_group() # needs sirocco - Finitely presented group < x0, x1 | x1*x0*x1*x0^-1*x1^-1*x0^-1 > + sage: g = P.curve(z*(x^2*z - y^3)).fundamental_group() # needs sirocco + sage: g.sorted_presentation() # needs sirocco + Finitely presented group < x0, x1 | x1^-1*x0^-1*x1^-1*x0*x1*x0 > In the case of number fields, they need to have an embedding into the algebraic field:: diff --git a/src/sage/schemes/curves/zariski_vankampen.py b/src/sage/schemes/curves/zariski_vankampen.py index f4b3f958575..1a6591d6f9b 100755 --- a/src/sage/schemes/curves/zariski_vankampen.py +++ b/src/sage/schemes/curves/zariski_vankampen.py @@ -44,7 +44,6 @@ import itertools from copy import copy -from datetime import datetime from itertools import combinations from sage.combinat.permutation import Permutation @@ -1417,7 +1416,7 @@ def conjugate_positive_form(braid): A list of `r` lists. Each such list is another list with two elements, a positive braid `\alpha_i` and a list of permutation braids - `\gamma_{1}^{i},\dots,\gamma_{r}^{n_i}` such that if + `\gamma_{1}^{i},\dots,\gamma_{n_i}^{i}` such that if `\gamma_i=\prod_{j=1}^{n_i} \gamma_j^i` then the braids `\tau_i=\gamma_i\alpha_i\gamma_i^{-1}` pairwise commute and `\alpha=\prod_{i=1}^{r} \tau_i`. @@ -1428,11 +1427,11 @@ def conjugate_positive_form(braid): sage: B = BraidGroup(4) sage: t = B((1, 3, 2, -3, 1, 1)) sage: conjugate_positive_form(t) - [[(s1*s0)^2, [s2]]] + [[(s0*s1)^2, [s0*s2*s1*s0]]] sage: B = BraidGroup(5) sage: t = B((1, 2, 3, 4, -1, -2, 3, 3, 2, -4)) sage: L = conjugate_positive_form(t); L - [[s1^2, [s3*s2]], [s1*s2, [s0]]] + [[s0^2, [s0*s1*s2*s1*s3*s2*s1*s0]], [s3*s2, [s0*s1*s2*s1*s3*s2*s1*s0]]] sage: s = B.one() sage: for a, l in L: ....: b = prod(l) @@ -1452,9 +1451,7 @@ def conjugate_positive_form(braid): braid1 = prod(A1, B.delta() ** ex) sg0 = B.one() else: - A = braid.super_summit_set() - braid1 = A[0] - sg0 = braid.conjugating_braid(braid1) + braid1, sg0 = braid.super_summit_set_element() if ex > 0: blocks = [list(braid1.Tietze())] else: @@ -1467,30 +1464,18 @@ def conjugate_positive_form(braid): if block: blocks.append(block) shorts = [] - oneblock = len(blocks) == 1 for a in blocks: if sg0 == B.one(): res0 = [B(a), []] else: - if not oneblock: - A = B(a).super_summit_set() + bra = sg0 * B(a) / sg0 + br1, sg = bra.super_summit_set_element() res = None - t0 = datetime.now() - for j, tau in enumerate(A): - if j == 1: - sg = sg0 - else: - sg = (sg0 * B(a) / sg0).conjugating_braid(tau) - A1 = rightnormalform(sg) - par = A1[-1][0] % 2 - A1 = [B(a) for a in A1[:-1]] - b = prod(A1, B.one()) - b1 = len(b.Tietze()) / (len(A1) + 1) - if res is None or b1 < res[3]: - res = [tau, A1, par, b1] - if (datetime.now() - t0).total_seconds() > 60: - break - if res[2] == 1: + A1 = rightnormalform(sg) + par = A1[-1][0] % 2 + A1 = [B(a0) for a0 in A1[:-1]] + res = [br1, A1, par] + if res[2]: r0 = res[0].Tietze() res[0] = B([i.sign() * (d - abs(i)) for i in r0]) res0 = res[:2] @@ -1619,9 +1604,10 @@ def fundamental_group_from_braid_mon(bm, degree=None, sage: bm = [s1*s2*s0*s1*s0^-1*s1^-1*s0^-1, ....: s0*s1^2*s0*s2*s1*(s0^-1*s1^-1)^2*s0^-1, ....: (s0*s1)^2] - sage: g = fundamental_group_from_braid_mon(bm, projective=True); g # needs sirocco + sage: g = fundamental_group_from_braid_mon(bm, projective=True) # needs sirocco + sage: g.sorted_presentation() # needs sirocco Finitely presented group - < x1, x3 | x3^2*x1^2, x1^-1*x3^-1*x1*x3^-1*x1^-1*x3^-1 > + < x0, x1 | x1^-2*x0^-2, x1^-1*(x0^-1*x1)^2*x0 > sage: print(g.order(), g.abelian_invariants()) # needs sirocco 12 (4,) sage: B2 = BraidGroup(2) @@ -1720,8 +1706,8 @@ def fundamental_group(f, simplified=True, projective=False, puiseux=True): sage: from sage.schemes.curves.zariski_vankampen import fundamental_group, braid_monodromy sage: R. = QQ[] sage: f = x^2 + y^3 - sage: fundamental_group(f) - Finitely presented group < x0, x1 | x0*x1^-1*x0^-1*x1^-1*x0*x1 > + sage: fundamental_group(f).sorted_presentation() + Finitely presented group < x0, x1 | x1^-1*x0^-1*x1^-1*x0*x1*x0 > sage: fundamental_group(f, simplified=False, puiseux=False).sorted_presentation() Finitely presented group < x0, x1, x2 | x2^-1*x1^-1*x0*x1, x2^-1*x0*x1*x0^-1, @@ -1882,7 +1868,7 @@ def fundamental_group_arrangement(flist, simplified=True, projective=False, sage: G.sorted_presentation() Finitely presented group < x0, x1, x2, x3 | x3^-1*x2^-1*x3*x2, x3^-1*x1^-1*x0^-1*x1*x3*x0, - x3^-1*x1^-1*x3*x0*x1*x0^-1, x2^-1*x0^-1*x2*x0 > + x3^-1*x1^-1*x0^-1*x3*x0*x1, x2^-1*x0^-1*x2*x0 > sage: dic {0: [x1], 1: [x3], 2: [x2], 3: [x0], 4: [x3^-1*x2^-1*x1^-1*x0^-1]} sage: fundamental_group_arrangement(L, vertical=True) From 3630649912e2dc58418664ed0d3cee3f483e0818 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Sun, 15 Dec 2024 13:06:26 -0700 Subject: [PATCH 039/175] Fix font size bug --- src/sage/graphs/graph_plot.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 6a73062fbcd..2262b6cc64a 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -236,7 +236,7 @@ 'talk': 'Whether to display the vertices in talk mode (larger and white).', 'label_fontsize': - 'font size of all labels', + 'font size of all labels', 'graph_border': 'Whether or not to draw a frame around the graph.', 'edge_labels_background': @@ -272,7 +272,7 @@ 'partition' : None, 'dist' : .075, 'max_dist' : 1.5, - 'label_fontsize' : 12, + 'label_fontsize' : 10, 'loop_size' : .075, 'edge_labels_background' : 'white'} @@ -1029,7 +1029,8 @@ def even_xy(d): text(str(elabel), [(C[0] + D[0]) / 2., (C[1] + D[1]) / 2.], background_color=bg, - fontsize=self._options['label_fontsize'])) + fontsize=self._options['label_fontsize'] + )) elif is_directed: self._plot_components['edges'].append( arrow(self._pos[a], self._pos[b], @@ -1045,7 +1046,8 @@ def even_xy(d): line([self._pos[a], self._pos[b]], rgbcolor=ecolor, linestyle=estyle, - thickness=ethickness)) + thickness=ethickness + )) if labels and not self._arcdigraph: bg = self._options['edge_labels_background'] self._plot_components['edge_labels'].append( @@ -1053,7 +1055,8 @@ def even_xy(d): [(self._pos[a][0] + self._pos[b][0]) / 2., (self._pos[a][1] + self._pos[b][1]) / 2.], background_color=bg, - fontsize=self._options['label_fontsize'])) + fontsize=self._options['label_fontsize'] + )) def _polar_hack_for_multidigraph(self, A, B, VR): """ From 957aeb9825551ce4329de09d1d45f516b834ffe9 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Sun, 15 Dec 2024 13:32:27 -0700 Subject: [PATCH 040/175] Fix doc lint --- src/sage/graphs/graph_plot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 2262b6cc64a..f927df5a10d 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -1551,7 +1551,7 @@ def plot(self, **kwds): ....: (0, 1, 'd'), (0, 1, 'e'), (0, 1, 'f'), ....: (0, 1, 'f'), (2, 1, 'g'), (2, 2, 'h')]) sage: GP = g.graphplot(vertex_size=100, edge_labels=True, - ....: color_by_label=True, edge_style='dashed') + ....: color_by_label=True, edge_style='dashed') sage: GP.set_edges(edge_styles={'a':'dashed', 'g':'dotted'}) sage: GP.plot() Graphics object consisting of 22 graphics primitives From 437536cf58f3cab03ad5114c50a1da18433956a7 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Tue, 17 Dec 2024 13:56:00 +0100 Subject: [PATCH 041/175] add parameter forbidden_vertices to BFS and DFS --- src/sage/graphs/base/c_graph.pyx | 70 +++++++++++++++++++++++++++++--- src/sage/graphs/connectivity.pyx | 48 +++++++++++++++++----- src/sage/graphs/generic_graph.py | 59 ++++++++++++++++++++++++--- 3 files changed, 155 insertions(+), 22 deletions(-) diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 00a535c3335..c46c60c1a9f 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -4176,7 +4176,8 @@ cdef class CGraphBackend(GenericGraphBackend): # Searching ################################### - def depth_first_search(self, v, reverse=False, ignore_direction=False): + def depth_first_search(self, v, reverse=False, ignore_direction=False, + forbidden_vertices=None): r""" Return a depth-first search from vertex ``v``. @@ -4192,6 +4193,9 @@ cdef class CGraphBackend(GenericGraphBackend): relevant to digraphs. If this is a digraph, ignore all orientations and consider the graph as undirected. + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search. The start vertex ``v`` cannot be in this set. + ALGORITHM: Below is a general template for depth-first search. @@ -4234,7 +4238,7 @@ cdef class CGraphBackend(GenericGraphBackend): Traversing the Petersen graph using depth-first search:: - sage: G = Graph(graphs.PetersenGraph()) + sage: G = graphs.PetersenGraph() sage: list(G.depth_first_search(0)) [0, 5, 8, 6, 9, 7, 2, 3, 4, 1] @@ -4251,14 +4255,33 @@ cdef class CGraphBackend(GenericGraphBackend): ....: "Stuttgart": ["Nurnberg"], "Erfurt": ["Wurzburg"]}) sage: list(G.depth_first_search("Stuttgart")) ['Stuttgart', 'Nurnberg', ...] + + Avoiding some cities: + + sage: list(G.depth_first_search("Stuttgart", + ....: forbidden_vertices=["Frankfurt", "Munchen"])) + ['Stuttgart', 'Nurnberg', 'Wurzburg', 'Erfurt'] + + TESTS: + + The start vertex cannot be forbidden:: + + sage: G = graphs.PetersenGraph() + sage: list(G.depth_first_search(0, forbidden_vertices=[0, 1])) + Traceback (most recent call last): + ... + ValueError: the start vertex is in the set of forbidden vertices """ return Search_iterator(self, v, direction=-1, reverse=reverse, - ignore_direction=ignore_direction) + ignore_direction=ignore_direction, + forbidden_vertices=forbidden_vertices) - def breadth_first_search(self, v, reverse=False, ignore_direction=False, report_distance=False, edges=False): + def breadth_first_search(self, v, reverse=False, ignore_direction=False, + report_distance=False, edges=False, + forbidden_vertices=None): r""" Return a breadth-first search from vertex ``v``. @@ -4286,6 +4309,9 @@ cdef class CGraphBackend(GenericGraphBackend): Note that parameters ``edges`` and ``report_distance`` cannot be ``True`` simultaneously. + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search. The start vertex ``v`` cannot be in this set. + ALGORITHM: Below is a general template for breadth-first search. @@ -4337,6 +4363,22 @@ cdef class CGraphBackend(GenericGraphBackend): sage: G = graphs.EuropeMap(continental=True) sage: list(G.breadth_first_search("Portugal")) ['Portugal', 'Spain', ..., 'Greece'] + + Avoiding some countries: + + sage: list(G.breadth_first_search("Portugal", + ....: forbidden_vertices=["Germany","Italy"])) + ['Portugal', 'Spain', ..., 'Sweden'] + + TESTS: + + The start vertex cannot be forbidden:: + + sage: G = graphs.PetersenGraph() + sage: list(G.breadth_first_search(0, forbidden_vertices=[0])) + Traceback (most recent call last): + ... + ValueError: the start vertex is in the set of forbidden vertices """ return Search_iterator(self, v, @@ -4344,7 +4386,8 @@ cdef class CGraphBackend(GenericGraphBackend): reverse=reverse, ignore_direction=ignore_direction, report_distance=report_distance, - edges=edges) + edges=edges, + forbidden_vertices=forbidden_vertices) ################################### # Connectedness @@ -4720,7 +4763,8 @@ cdef class Search_iterator: cdef in_neighbors def __init__(self, graph, v, direction=0, reverse=False, - ignore_direction=False, report_distance=False, edges=False): + ignore_direction=False, report_distance=False, edges=False, + forbidden_vertices=None): r""" Initialize an iterator for traversing a (di)graph. @@ -4762,11 +4806,16 @@ cdef class Search_iterator: Note that parameters ``edges`` and ``report_distance`` cannot be ``True`` simultaneously. + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search. The start vertex ``v`` cannot be in this set. + EXAMPLES:: sage: g = graphs.PetersenGraph() sage: list(g.breadth_first_search(0)) [0, 1, 4, 5, 2, 6, 3, 9, 7, 8] + sage: list(g.breadth_first_search(0, forbidden_vertices=[1, 2])) + [0, 4, 5, 3, 9, 7, 8, 6] TESTS: @@ -4805,10 +4854,19 @@ cdef class Search_iterator: bitset_set_first_n(self.seen, 0) cdef int v_id = self.graph.get_vertex(v) + cdef int u_id if v_id == -1: raise LookupError("vertex ({0}) is not a vertex of the graph".format(repr(v))) + if forbidden_vertices is not None: + for u in forbidden_vertices: + u_id = self.graph.get_vertex(u) + if u_id != -1: + if u_id == v_id: + raise ValueError(f"the start vertex is in the set of forbidden vertices") + bitset_add(self.seen, u_id) + if direction == 0: self.fifo.push(v_id) self.first_with_new_distance = -1 diff --git a/src/sage/graphs/connectivity.pyx b/src/sage/graphs/connectivity.pyx index 05138c68f49..77dfd4fcf92 100644 --- a/src/sage/graphs/connectivity.pyx +++ b/src/sage/graphs/connectivity.pyx @@ -135,7 +135,7 @@ def is_connected(G): return len(conn_verts) == G.num_verts() -def connected_components(G, sort=None, key=None): +def connected_components(G, sort=None, key=None, forbidden_vertices=None): """ Return the list of connected components. @@ -157,6 +157,9 @@ def connected_components(G, sort=None, key=None): vertex as its one argument and returns a value that can be used for comparisons in the sorting algorithm (we must have ``sort=True``) + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search. The start vertex ``v`` cannot be in this set. + EXAMPLES:: sage: from sage.graphs.connectivity import connected_components @@ -213,14 +216,15 @@ def connected_components(G, sort=None, key=None): cdef list components = [] for v in G: if v not in seen: - c = connected_component_containing_vertex(G, v, sort=sort, key=key) + c = connected_component_containing_vertex(G, v, sort=sort, key=key, + forbidden_vertices=forbidden_vertices) seen.update(c) components.append(c) components.sort(key=lambda comp: -len(comp)) return components -def connected_components_number(G): +def connected_components_number(G, forbidden_vertices=None): """ Return the number of connected components. @@ -228,6 +232,9 @@ def connected_components_number(G): - ``G`` -- the input graph + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search. The start vertex ``v`` cannot be in this set. + EXAMPLES:: sage: from sage.graphs.connectivity import connected_components_number @@ -253,10 +260,17 @@ def connected_components_number(G): return len(connected_components(G, sort=False)) -def connected_components_subgraphs(G): +def connected_components_subgraphs(G, forbidden_vertices=None): """ Return a list of connected components as graph objects. + INPUT: + + - ``G`` -- the input graph + + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search. The start vertex ``v`` cannot be in this set. + EXAMPLES:: sage: from sage.graphs.connectivity import connected_components_subgraphs @@ -283,10 +297,12 @@ def connected_components_subgraphs(G): if not isinstance(G, GenericGraph): raise TypeError("the input must be a Sage graph") - return [G.subgraph(c, inplace=False) for c in connected_components(G, sort=False)] + return [G.subgraph(c, inplace=False) + for c in connected_components(G, sort=False, forbidden_vertices=forbidden_vertices)] -def connected_component_containing_vertex(G, vertex, sort=None, key=None): +def connected_component_containing_vertex(G, vertex, sort=None, key=None, + forbidden_vertices=None): """ Return a list of the vertices connected to vertex. @@ -307,6 +323,9 @@ def connected_component_containing_vertex(G, vertex, sort=None, key=None): vertex as its one argument and returns a value that can be used for comparisons in the sorting algorithm (we must have ``sort=True``) + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search. The start vertex ``v`` cannot be in this set. + EXAMPLES:: sage: from sage.graphs.connectivity import connected_component_containing_vertex @@ -370,21 +389,30 @@ def connected_component_containing_vertex(G, vertex, sort=None, key=None): raise ValueError('sort keyword is False, yet a key function is given') try: - c = list(G._backend.depth_first_search(vertex, ignore_direction=True)) + c = list(G._backend.depth_first_search(vertex, ignore_direction=True, + forbidden_vertices=forbidden_vertices)) except AttributeError: - c = list(G.depth_first_search(vertex, ignore_direction=True)) + c = list(G.depth_first_search(vertex, ignore_direction=True, + forbidden_vertices=forbidden_vertices)) if sort: return sorted(c, key=key) return c -def connected_components_sizes(G): +def connected_components_sizes(G, forbidden_vertices=None): """ Return the sizes of the connected components as a list. The list is sorted from largest to lower values. + INPUT: + + - ``G`` -- the input graph + + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search. The start vertex ``v`` cannot be in this set. + EXAMPLES:: sage: from sage.graphs.connectivity import connected_components_sizes @@ -416,7 +444,7 @@ def connected_components_sizes(G): raise TypeError("the input must be a Sage graph") # connected components are sorted from largest to smallest - return [len(cc) for cc in connected_components(G, sort=False)] + return [len(cc) for cc in connected_components(G, sort=False, forbidden_vertices=forbidden_vertices)] def blocks_and_cut_vertices(G, algorithm='Tarjan_Boost', sort=False, key=None): diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 101952109c3..5c4d3c91643 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -18854,7 +18854,8 @@ def average_distance(self, by_weight=False, algorithm=None, def breadth_first_search(self, start, ignore_direction=False, distance=None, neighbors=None, - report_distance=False, edges=False): + report_distance=False, edges=False, + forbidden_vertices=None): """ Return an iterator over the vertices in a breadth-first ordering. @@ -18889,6 +18890,9 @@ def breadth_first_search(self, start, ignore_direction=False, Note that parameters ``edges`` and ``report_distance`` cannot be ``True`` simultaneously. + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search. The start vertex ``v`` cannot be in this set. + .. SEEALSO:: - :meth:`breadth_first_search ` @@ -18977,6 +18981,12 @@ def breadth_first_search(self, start, ignore_direction=False, sage: list(D.breadth_first_search(1, edges=True)) [(1, 2), (1, 3), (2, 4)] + BFS in a graph with forbidden vertices:: + + sage: G = graphs.PetersenGraph() + sage: list(G.breadth_first_search(0, forbidden_vertices=[1, 2])) + [0, 4, 5, 3, 9, 7, 8, 6] + TESTS:: sage: D = DiGraph({1: [0], 2: [0]}) @@ -18995,6 +19005,14 @@ def breadth_first_search(self, start, ignore_direction=False, Traceback (most recent call last): ... ValueError: parameters edges and report_distance cannot be ``True`` simultaneously + sage: list(G.breadth_first_search(0, forbidden_vertices=[0])) + Traceback (most recent call last): + ... + ValueError: the start vertex is in the set of forbidden vertices + sage: list(G.breadth_first_search([0, 1], forbidden_vertices=[1])) + Traceback (most recent call last): + ... + ValueError: start vertex 1 is in the set of forbidden vertices """ from sage.rings.semirings.non_negative_integer_semiring import NN if (distance is not None and distance not in NN): @@ -19008,17 +19026,23 @@ def breadth_first_search(self, start, ignore_direction=False, and hasattr(self._backend, "breadth_first_search")): yield from self._backend.breadth_first_search( start, ignore_direction=ignore_direction, - report_distance=report_distance, edges=edges) + report_distance=report_distance, edges=edges, + forbidden_vertices=forbidden_vertices) else: if neighbors is None: if not self._directed or ignore_direction: neighbors = self.neighbor_iterator else: neighbors = self.neighbor_out_iterator - seen = set() + seen = set() if forbidden_vertices is None else set(forbidden_vertices) if isinstance(start, list): + for s in start: + if s in seen: + raise ValueError(f"start vertex {s} is in the set of forbidden vertices") queue = [(v, 0) for v in start] else: + if start in seen: + raise ValueError("the start vertex is in the set of forbidden vertices") queue = [(start, 0)] # Non-existing start vertex is detected later if distance > 0. @@ -19050,7 +19074,7 @@ def breadth_first_search(self, start, ignore_direction=False, yield w def depth_first_search(self, start, ignore_direction=False, - neighbors=None, edges=False): + neighbors=None, edges=False, forbidden_vertices=None): """ Return an iterator over the vertices in a depth-first ordering. @@ -19073,6 +19097,9 @@ def depth_first_search(self, start, ignore_direction=False, of the DFS tree in the order of visit or the vertices (default). Edges are directed in root to leaf orientation of the tree. + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search. The start vertex ``v`` cannot be in this set. + .. SEEALSO:: - :meth:`breadth_first_search` @@ -19132,6 +19159,12 @@ def depth_first_search(self, start, ignore_direction=False, sage: list(D.depth_first_search(2, edges=True, ignore_direction=True)) [(2, 3), (3, 4), (2, 1), (1, 0)] + DFS in a graph with forbidden vertices:: + + sage: G = graphs.PetersenGraph() + sage: list(G.depth_first_search(0, forbidden_vertices=[1, 2])) + [0, 5, 8, 6, 9, 7, 4, 3] + TESTS:: sage: D = DiGraph({1: [0], 2: [0]}) @@ -19155,22 +19188,36 @@ def depth_first_search(self, start, ignore_direction=False, [1, 3, 6, 4, 5, 7, 2] sage: list(D.depth_first_search(1, ignore_direction=True, edges=True)) [(1, 3), (3, 6), (6, 7), (7, 5), (5, 4), (1, 2)] + sage: list(G.depth_first_search(0, forbidden_vertices=[0])) + Traceback (most recent call last): + ... + ValueError: the start vertex is in the set of forbidden vertices + sage: list(G.depth_first_search([0, 1], forbidden_vertices=[1])) + Traceback (most recent call last): + ... + ValueError: start vertex 1 is in the set of forbidden vertices """ # Preferably use the Cython implementation if (neighbors is None and not isinstance(start, list) and hasattr(self._backend, "depth_first_search") and not edges): - yield from self._backend.depth_first_search(start, ignore_direction=ignore_direction) + yield from self._backend.depth_first_search(start, ignore_direction=ignore_direction, + forbidden_vertices=forbidden_vertices) else: if neighbors is None: if not self._directed or ignore_direction: neighbors = self.neighbor_iterator else: neighbors = self.neighbor_out_iterator - seen = set() + seen = set() if forbidden_vertices is None else set(forbidden_vertices) if isinstance(start, list): + for s in start: + if s in seen: + raise ValueError(f"start vertex {s} is in the set of forbidden vertices") # Reverse the list so that the initial vertices come out in the same order queue = [(v, 0) for v in reversed(start)] else: + if start in seen: + raise ValueError("the start vertex is in the set of forbidden vertices") queue = [(start, 0)] if not edges: From bf4c4e6edc1c498e0806bf3177eb3b536811200b Mon Sep 17 00:00:00 2001 From: dcoudert Date: Tue, 17 Dec 2024 16:09:31 +0100 Subject: [PATCH 042/175] expose forbidden_vertices in connectivity methods --- src/sage/graphs/base/c_graph.pyx | 31 ++++++++++++-- src/sage/graphs/connectivity.pyx | 73 +++++++++++++++++++++++++------- src/sage/graphs/generic_graph.py | 2 +- 3 files changed, 87 insertions(+), 19 deletions(-) diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index c46c60c1a9f..1cac2f5464d 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -4393,10 +4393,15 @@ cdef class CGraphBackend(GenericGraphBackend): # Connectedness ################################### - def is_connected(self): + def is_connected(self, forbidden_vertices=None): r""" Check whether the graph is connected. + INPUT: + + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search + EXAMPLES: Petersen's graph is connected:: @@ -4414,6 +4419,16 @@ cdef class CGraphBackend(GenericGraphBackend): sage: Graph(graphs.CubeGraph(3)).is_connected() True + A graph with forbidden vertices:: + + sage: G = graphs.PathGraph(5) + sage: G._backend.is_connected() + True + sage: G._backend.is_connected(forbidden_vertices=[1]) + False + sage: G._backend.is_connected(forbidden_vertices=[0, 1]) + True + TESTS:: sage: P = posets.PentagonPoset() # needs sage.modules @@ -4432,8 +4447,18 @@ cdef class CGraphBackend(GenericGraphBackend): if v_int == -1: return True v = self.vertex_label(v_int) - cdef size_t n = 0 - for _ in self.depth_first_search(v, ignore_direction=True): + cdef set forbidden = set(forbidden_vertices) if forbidden_vertices else set() + while v in forbidden: + v_int = bitset_next(cg.active_vertices, v_int + 1) + if v_int == -1: + # The empty is connected. So the graph with only forbidden + # vertices also is + return True + v = self.vertex_label(v_int) + + cdef size_t n = len(forbidden) + for _ in self.depth_first_search(v, ignore_direction=True, + forbidden_vertices=forbidden): n += 1 return n == cg.num_verts diff --git a/src/sage/graphs/connectivity.pyx b/src/sage/graphs/connectivity.pyx index 77dfd4fcf92..66f584fc466 100644 --- a/src/sage/graphs/connectivity.pyx +++ b/src/sage/graphs/connectivity.pyx @@ -75,7 +75,7 @@ from sage.misc.superseded import deprecation from sage.sets.disjoint_set cimport DisjointSet -def is_connected(G): +def is_connected(G, forbidden_vertices=None): """ Check whether the (di)graph is connected. @@ -85,6 +85,9 @@ def is_connected(G): - ``G`` -- the input graph + - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to + avoid during the search + .. SEEALSO:: - :meth:`~Graph.is_biconnected` @@ -100,6 +103,10 @@ def is_connected(G): sage: G.add_edge(0,3) sage: is_connected(G) True + sage: is_connected(G, forbidden_vertices=[3]) + False + sage: is_connected(G, forbidden_vertices=[1]) + True sage: D = DiGraph({0: [1, 2], 1: [2], 3: [4, 5], 4: [5]}) sage: is_connected(D) False @@ -128,11 +135,25 @@ def is_connected(G): return True try: - return G._backend.is_connected() + return G._backend.is_connected(forbidden_vertices=forbidden_vertices) except AttributeError: - v = next(G.vertex_iterator()) - conn_verts = list(G.depth_first_search(v, ignore_direction=True)) - return len(conn_verts) == G.num_verts() + # Search for a vertex in G that is not forbidden + forbidden = set(forbidden_vertices) if forbidden_vertices else set() + if forbidden: + for v in G: + if v not in forbidden: + break + else: + # The empty graph is connected, so the graph with only forbidden + # vertices is also connected + return True + else: + v = next(G.vertex_iterator()) + n = len(forbidden) + for _ in G.depth_first_search(v, ignore_direction=True, + forbidden_vertices=forbidden): + n += 1 + return n == G.num_verts() def connected_components(G, sort=None, key=None, forbidden_vertices=None): @@ -158,7 +179,7 @@ def connected_components(G, sort=None, key=None, forbidden_vertices=None): comparisons in the sorting algorithm (we must have ``sort=True``) - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to - avoid during the search. The start vertex ``v`` cannot be in this set. + avoid during the search EXAMPLES:: @@ -174,6 +195,12 @@ def connected_components(G, sort=None, key=None, forbidden_vertices=None): sage: connected_components(D, sort=True, key=lambda x: -x) [[3, 2, 1, 0], [6, 5, 4]] + Connected components in a graph with forbidden vertices:: + + sage: G = graphs.PathGraph(5) + sage: connected_components(G, sort=True, forbidden_vertices=[2]) + [[0, 1], [3, 4]] + TESTS: If ``G`` is not a Sage graph, an error is raised:: @@ -212,7 +239,7 @@ def connected_components(G, sort=None, key=None, forbidden_vertices=None): if (not sort) and key: raise ValueError('sort keyword is False, yet a key function is given') - cdef set seen = set() + cdef set seen = set(forbidden_vertices) if forbidden_vertices else set() cdef list components = [] for v in G: if v not in seen: @@ -233,7 +260,7 @@ def connected_components_number(G, forbidden_vertices=None): - ``G`` -- the input graph - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to - avoid during the search. The start vertex ``v`` cannot be in this set. + avoid during the search EXAMPLES:: @@ -246,6 +273,8 @@ def connected_components_number(G, forbidden_vertices=None): sage: D = DiGraph({0: [1, 3], 1: [2], 2: [3], 4: [5, 6], 5: [6]}) sage: connected_components_number(D) 2 + sage: connected_components_number(D, forbidden_vertices=[1, 3]) + 3 TESTS: @@ -257,7 +286,8 @@ def connected_components_number(G, forbidden_vertices=None): ... TypeError: the input must be a Sage graph """ - return len(connected_components(G, sort=False)) + return len(connected_components(G, sort=False, + forbidden_vertices=forbidden_vertices)) def connected_components_subgraphs(G, forbidden_vertices=None): @@ -269,7 +299,7 @@ def connected_components_subgraphs(G, forbidden_vertices=None): - ``G`` -- the input graph - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to - avoid during the search. The start vertex ``v`` cannot be in this set. + avoid during the search EXAMPLES:: @@ -277,6 +307,8 @@ def connected_components_subgraphs(G, forbidden_vertices=None): sage: G = Graph({0: [1, 3], 1: [2], 2: [3], 4: [5, 6], 5: [6]}) sage: L = connected_components_subgraphs(G) sage: graphs_list.show_graphs(L) # needs sage.plot + sage: L = connected_components_subgraphs(G, forbidden_vertices=[1, 3]) + sage: graphs_list.show_graphs(L) # needs sage.plot sage: D = DiGraph({0: [1, 3], 1: [2], 2: [3], 4: [5, 6], 5: [6]}) sage: L = connected_components_subgraphs(D) sage: graphs_list.show_graphs(L) # needs sage.plot @@ -298,7 +330,8 @@ def connected_components_subgraphs(G, forbidden_vertices=None): raise TypeError("the input must be a Sage graph") return [G.subgraph(c, inplace=False) - for c in connected_components(G, sort=False, forbidden_vertices=forbidden_vertices)] + for c in connected_components(G, sort=False, + forbidden_vertices=forbidden_vertices)] def connected_component_containing_vertex(G, vertex, sort=None, key=None, @@ -310,7 +343,7 @@ def connected_component_containing_vertex(G, vertex, sort=None, key=None, - ``G`` -- the input graph - - ``v`` -- the vertex to search for + - ``vertex`` -- the vertex to search for - ``sort`` -- boolean (default: ``None``); if ``True``, vertices inside the component are sorted according to the default ordering @@ -324,7 +357,7 @@ def connected_component_containing_vertex(G, vertex, sort=None, key=None, comparisons in the sorting algorithm (we must have ``sort=True``) - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to - avoid during the search. The start vertex ``v`` cannot be in this set. + avoid during the search. The start ``vertex`` cannot be in this set. EXAMPLES:: @@ -334,6 +367,8 @@ def connected_component_containing_vertex(G, vertex, sort=None, key=None, [0, 1, 2, 3] sage: G.connected_component_containing_vertex(0, sort=True) [0, 1, 2, 3] + sage: G.connected_component_containing_vertex(0, sort=True, forbidden_vertices=[1, 3]) + [0] sage: D = DiGraph({0: [1, 3], 1: [2], 2: [3], 4: [5, 6], 5: [6]}) sage: connected_component_containing_vertex(D, 0, sort=True) [0, 1, 2, 3] @@ -411,7 +446,7 @@ def connected_components_sizes(G, forbidden_vertices=None): - ``G`` -- the input graph - ``forbidden_vertices`` -- list (default: ``None``); set of vertices to - avoid during the search. The start vertex ``v`` cannot be in this set. + avoid during the search EXAMPLES:: @@ -428,6 +463,13 @@ def connected_components_sizes(G, forbidden_vertices=None): [2, 1] [3] [3] + sage: G = graphs.PathGraph(5) + sage: G.connected_components_sizes() + [5] + sage: G.connected_components_sizes(forbidden_vertices=[1]) + [3, 1] + sage: G.connected_components_sizes(forbidden_vertices=[1, 3]) + [1, 1, 1] TESTS: @@ -444,7 +486,8 @@ def connected_components_sizes(G, forbidden_vertices=None): raise TypeError("the input must be a Sage graph") # connected components are sorted from largest to smallest - return [len(cc) for cc in connected_components(G, sort=False, forbidden_vertices=forbidden_vertices)] + return [len(cc) for cc in connected_components(G, sort=False, + forbidden_vertices=forbidden_vertices)] def blocks_and_cut_vertices(G, algorithm='Tarjan_Boost', sort=False, key=None): diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 5c4d3c91643..b3056ed1428 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -19208,7 +19208,7 @@ def depth_first_search(self, start, ignore_direction=False, neighbors = self.neighbor_iterator else: neighbors = self.neighbor_out_iterator - seen = set() if forbidden_vertices is None else set(forbidden_vertices) + seen = set(forbidden_vertices) if forbidden_vertices else set() if isinstance(start, list): for s in start: if s in seen: From a2431a35b2a3e6ef2eb4b4a8d621f0a0b7580161 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Tue, 17 Dec 2024 18:27:10 +0100 Subject: [PATCH 043/175] typo --- src/sage/graphs/base/c_graph.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 1cac2f5464d..ca50c0f1166 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -4451,7 +4451,7 @@ cdef class CGraphBackend(GenericGraphBackend): while v in forbidden: v_int = bitset_next(cg.active_vertices, v_int + 1) if v_int == -1: - # The empty is connected. So the graph with only forbidden + # The empty graph is connected. So the graph with only forbidden # vertices also is return True v = self.vertex_label(v_int) From d022820791019243e81c8bb97332b8033e2d20bc Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 18 Dec 2024 09:12:50 +0100 Subject: [PATCH 044/175] Apply suggestions from code review in particular, return elements of the correct parent in `Partitions_length_and_parts_restricted` Co-authored-by: Travis Scrimshaw --- src/sage/combinat/partition.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index b5537db6626..ffec6ef1259 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6837,10 +6837,9 @@ def __contains__(self, x): True """ try: - mu = Partition(x) - except ValueError: + return mu in Partitions(sum(mu), **self._restrictions) + except Exception: return False - return mu in Partitions(mu.size(), **self._restrictions) def _repr_(self): """ @@ -9045,15 +9044,14 @@ def __contains__(self, x): sage: Partition([5, 3, 2]) in P True """ - try: - mu = Partition(x) - except ValueError: + if mu not in _Partitions: return False - return (mu.size() == self._n - and (not mu - or (min(mu) >= self._min_part - and max(mu) <= self._max_part - and self._min_length <= len(mu) <= self._max_length))) + if not self._n: + return not mu + return (sum(mu) == self._n + and mu[-1] >= self._min_part + and mu[0] <= self._max_part + and self._min_length <= len(mu) <= self._max_length) def __iter__(self): """ @@ -9069,7 +9067,7 @@ def __iter__(self): max_part=self._max_part, min_length=self._min_length, max_length=self._max_length, - element_constructor=Partition) + element_constructor=lambda x: self.element_class(self, x)) def cardinality(self): """ From e2c7488699549dd6f43a8eb5874dc4e3cb5602c0 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 18 Dec 2024 09:31:58 +0100 Subject: [PATCH 045/175] fix oversight in previous commit, add some tests, fix typo --- src/sage/combinat/partition.py | 43 +++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index ffec6ef1259..2fd1c799e20 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -8941,15 +8941,15 @@ class Partitions_length_and_parts_restricted(Partitions): This class is strictly more general than :class:`PartitionsGreatestLE`, except that we insist that the size of the partition is positive and that neither the - restrictions on the parts not on the length are contradictory. + restrictions on the parts nor on the length are contradictory. INPUT: - ``n`` -- the size of the partition, positive - - ``min_length`` -- the lower bound on the number of parts, between 1 and n - - ``max_length`` -- the upper bound on the number of parts, between min_length and n - - ``min_part`` -- the bound on the smallest part, between 1 and n - - ``max_part`` -- the bound on the largest part, between min_part and n + - ``min_length`` -- the lower bound on the number of parts, between 1 and ``n`` + - ``max_length`` -- the upper bound on the number of parts, between ``min_length`` and ``n`` + - ``min_part`` -- the bound on the smallest part, between 1 and ``n`` + - ``max_part`` -- the bound on the largest part, between ``min_part`` and ``n`` EXAMPLES:: @@ -8964,6 +8964,19 @@ class Partitions_length_and_parts_restricted(Partitions): sage: [2,2,2,2,2] in Partitions_length_and_parts_restricted(10, 1, 10, 2, 10) True + .. WARNING:: + + If ``min_length`` and ``min_part`` equal 1 and ``max_length`` + and ``max_part`` equal ``n``, this class contains the same + partitions as :class:`~sage.combinat.partition.Partitions`, + but is different from that class. + + :: + + sage: Partitions_length_and_parts_restricted(9, 1, 9, 1, 9) + Partitions of 9 + sage: Partitions_length_and_parts_restricted(9, 1, 9, 1, 9) == Partitions(9) + False """ def __init__(self, n, min_length, max_length, min_part, max_part): """ @@ -8993,8 +9006,16 @@ def _repr_(self): TESTS:: sage: from sage.combinat.partition import Partitions_length_and_parts_restricted + sage: Partitions_length_and_parts_restricted(9, 1, 9, 1, 9) + Partitions of 9 + sage: Partitions_length_and_parts_restricted(9, 1, 3, 1, 9) + Partitions of 9 having length at most 3 + sage: Partitions_length_and_parts_restricted(9, 3, 9, 1, 9) + Partitions of 9 having length at least 3 sage: Partitions_length_and_parts_restricted(9, 1, 9, 2, 9) Partitions of 9 whose parts are at least 2 + sage: Partitions_length_and_parts_restricted(9, 1, 9, 1, 3) + Partitions of 9 whose parts are at most 3 sage: Partitions_length_and_parts_restricted(9, 3, 5, 2, 9) Partitions of 9 having length between 3 and 5 and whose parts are at least 2 """ @@ -9044,14 +9065,14 @@ def __contains__(self, x): sage: Partition([5, 3, 2]) in P True """ - if mu not in _Partitions: + if x not in _Partitions: return False if not self._n: - return not mu - return (sum(mu) == self._n - and mu[-1] >= self._min_part - and mu[0] <= self._max_part - and self._min_length <= len(mu) <= self._max_length) + return not x + return (sum(x) == self._n + and x[-1] >= self._min_part + and x[0] <= self._max_part + and self._min_length <= len(x) <= self._max_length) def __iter__(self): """ From ac1d86163e41bd36d43011edcf92d73d2c20c520 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 18 Dec 2024 16:23:37 +0700 Subject: [PATCH 046/175] Mark test in qqbar.py as random to avoid test failure --- src/sage/rings/qqbar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 3806663eaf0..4c7397ce7e4 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -2711,7 +2711,7 @@ def number_field_elements_from_algebraics(numbers, minimal=False, -1 sage: nfI^2 -1 - sage: sum = nfrt2 + nfrt3 + nfI + nfz3; sum + sage: sum = nfrt2 + nfrt3 + nfI + nfz3; sum # random a^5 + a^4 - a^3 + 2*a^2 - a - 1 sage: hom(sum) 2.646264369941973? + 1.866025403784439?*I From 8f584400693927a490775593e40922fba988650c Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:39:04 +0700 Subject: [PATCH 047/175] Make a few more tests deterministic --- src/sage/rings/number_field/number_field.py | 62 ++++++++++++--------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 2559771ae62..59653381572 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -8662,7 +8662,7 @@ def optimized_subfields(self, degree=0, name=None, both_maps=True): polynomials are supported (:issue:`252`):: sage: K. = NumberField(2*x^4 + 6*x^2 + 1/2) - sage: K.optimized_subfields() + sage: K.optimized_subfields() # random [ (Number Field in a0 with defining polynomial x, Ring morphism: From: Number Field in a0 with defining polynomial x @@ -8774,32 +8774,40 @@ def subfields(self, degree=0, name=None): polynomials are supported (:issue:`252`):: 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) - ] + sage: sorted(K.subfields(), key=lambda x: x[0].discriminant()) + [(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 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 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 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) From 27445df3b9a11da2a1c8078dd465455d80aa0235 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 12:51:53 +0530 Subject: [PATCH 048/175] Added doctests to methods in KahlerAlgebras category --- src/sage/categories/kahler_algebras.py | 90 +++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 8 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 640693e0fd6..0ec85c4fbdb 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -1,5 +1,5 @@ r""" -Category of Kahler Algebras. +Category of Kähler Algebras. AUTHORS: @@ -17,6 +17,8 @@ class KahlerAlgebras(Category_over_base_ring): EXAMPLES:: + sage: from sage.categories.kahler_algebras import KahlerAlgebras + sage: C = KahlerAlgebras(QQ); C Category of kahler algebras over Rational Field sage: sorted(C.super_categories(), key=str) @@ -32,6 +34,21 @@ def super_categories(self): class ParentMethods: def poincare_pairing(self, el1, el2, r): + r""" + Return the Poincaré pairing of any two elements of the + Kähler algebra. + + EXAMPLES:: + + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') + sage: A0, A1, A2, A3, A4, A5, A013, A025, A04, A124, A15, A23, A345, A012345 = ch.gens() + sage: u = ch(-1/6*A2*A012345 + 41/48*A012345^2); u + -1/6*A2*A012345 + 41/48*A012345^2 + sage: v = ch(-A345^2 - 1/4*A345); v + -A345^2 - 1/4*A345 + sage: ch.poincare_pairing(v, u, ch.matroid().rank()) + 3 + """ hom_components1 = el1.lift().homogeneous_components() hom_components2 = el2.lift().homogeneous_components() new_el = self.base_ring().zero() @@ -46,10 +63,67 @@ def poincare_pairing(self, el1, el2, r): def lefschetz_element(): pass - def hodge_riemann_relations(self, k, lefschetz_el, r): - basis_k = self.basis(d=k) - coeff = [] - for el, i in enumerate(basis_k): - for j in range(i+1, len(basis_k)): - coeff.append((el*(lefschetz_el**(r-(2*k))*basis_k[j])).degree()) - return QuadraticForm(self.base_ring(), len(basis_k), coeff) \ No newline at end of file + def hodge_riemann_relations(self, k, r): + r""" + Return the quadratic form for the corresponding k (< r/2) for the + Kähler algebra. + + EXAMPLES:: + + sage: ch = matroids.Uniform(4,6).chow_ring(QQ, False) + sage: ch.hodge_riemann_relations(1, ch.matroid().rank() - 1) + Quadratic form in 36 variables over Rational Field with coefficients: + [ 3 -1 -1 3 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 3 ] + [ * 3 -1 3 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 3 ] + [ * * 3 3 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 3 ] + [ * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * 3 -1 3 -1 3 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 3 ] + [ * * * * * 3 3 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 3 ] + [ * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * 3 3 3 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 ] + [ * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * 3 -1 3 -1 -1 3 -1 -1 3 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 ] + [ * * * * * * * * * * * 3 3 -1 3 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 ] + [ * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * 3 3 3 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 3 ] + [ * * * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * 3 3 3 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 3 ] + [ * * * * * * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * * * 3 -1 3 -1 3 -1 -1 -1 -1 3 -1 -1 -1 3 -1 3 ] + [ * * * * * * * * * * * * * * * * * * * * * 3 3 -1 -1 3 -1 -1 3 -1 -1 -1 3 -1 -1 3 ] + [ * * * * * * * * * * * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * * * * * * 3 3 3 -1 3 -1 -1 -1 3 -1 -1 -1 3 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * * * 3 3 3 3 -1 -1 -1 -1 3 3 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 -1 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 3 3 3 3 3 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 -1 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 ] + [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 ] + sage: ch.hodge_riemann_relations(3, ch.matroid().rank() - 1) + Traceback (most recent call last): + ... + ValueError: k must be less than r < 2 + """ + if k < (r/2): + basis_k = [] + lefschetz_el = self.lefschetz_element() + for b in self.basis(): + if b.homogeneous_degree() == k: + basis_k.append(b) + coeff = [] + for i,el in enumerate(basis_k): + for j in range(i, len(basis_k)): + coeff.append((el*(lefschetz_el**(r-(2*k))*basis_k[j])).degree()) + return QuadraticForm(self.base_ring(), len(basis_k), coeff) + else: + raise ValueError("k must be less than r < 2") \ No newline at end of file From 66b26498ef3a1e41afa484d247bd15180904c1b5 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 12:54:52 +0530 Subject: [PATCH 049/175] Added and formatted lefschetz_element() for ChowRing class --- src/sage/matroids/chow_ring.py | 143 +++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index a5916991bf2..9dac3f1ef66 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -196,6 +196,149 @@ def basis(self): monomial_basis = self._ideal.normal_basis() return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) + def flats_generator(self): + r""" + Return the corresponding generators of flats of the Chow ring. + + EXAMPLES:: + + sage: ch = matroids.catalog.NonFano().chow_ring(ZZ, True, 'atom-free') + sage: ch.flats_generator() + {frozenset({'a'}): Aa, + frozenset({'b'}): Ab, + frozenset({'c'}): Ac, + frozenset({'d'}): Ad, + frozenset({'e'}): Ae, + frozenset({'f'}): Af, + frozenset({'g'}): Ag, + frozenset({'a', 'b', 'f'}): Aabf, + frozenset({'a', 'c', 'e'}): Aace, + frozenset({'a', 'd', 'g'}): Aadg, + frozenset({'b', 'c', 'd'}): Abcd, + frozenset({'b', 'e', 'g'}): Abeg, + frozenset({'c', 'f', 'g'}): Acfg, + frozenset({'d', 'e'}): Ade, + frozenset({'d', 'f'}): Adf, + frozenset({'e', 'f'}): Aef, + frozenset({'a', 'b', 'c', 'd', 'e', 'f', 'g'}): Aabcdefg} + """ + flats = [X for i in range(1, self._matroid.rank() + 1) + for X in self._matroid.flats(i)] + gens = self.gens() + if self._augmented & (self._presentation == 'fy'): + flats_gen = {} + E = list(self.matroid().groundset()) + for i,F in enumerate(flats): + flats_gen[F] = gens[len(E) + i] + return flats_gen + else: + return dict(zip(flats, gens)) + + def lefschetz_element(self): + r""" + Return one Lefschetz element of the given Chow ring. + + EXAMPLES:: + + sage: ch = matroids.catalog.P8pp().chow_ring(QQ, False) + sage: ch.lefschetz_element() + -2*Aab - 2*Aac - 2*Aad - 2*Aae - 2*Aaf - 2*Aag - 2*Aah - 2*Abc + - 2*Abd - 2*Abe - 2*Abf - 2*Abg - 2*Abh - 2*Acd - 2*Ace - 2*Acf + - 2*Acg - 2*Ach - 2*Ade - 2*Adf - 2*Adg - 2*Adh - 2*Aef - 2*Aeg + - 2*Aeh - 2*Afg - 2*Afh - 2*Agh - 6*Aabc - 6*Aabd - 6*Aabe + - 12*Aabfh - 6*Aabg - 6*Aacd - 12*Aacef - 12*Aacgh - 12*Aadeg + - 6*Aadf - 6*Aadh - 6*Aaeh - 6*Aafg - 6*Abcd - 12*Abceg + - 6*Abcf - 6*Abch - 12*Abdeh - 12*Abdfg - 6*Abef - 6*Abgh + - 6*Acde - 12*Acdfh - 6*Acdg - 6*Aceh - 6*Acfg - 6*Adef + - 6*Adgh - 6*Aefg - 6*Aefh - 6*Aegh - 6*Afgh - 56*Aabcdefgh + + The following example finds the Lefschetz element of the Chow ring + of the uniform matroid of rank 4 on 5 elements (non-augmented). + It is then multiplied with the elements of FY-monomial bases of + different degrees:: + + sage: ch = matroids.Uniform(4,5).chow_ring(QQ, False) + sage: basis_deg = {} + sage: for b in ch.basis(): + ....: deg = b.homogeneous_degree() + ....: if deg not in basis_deg: + ....: basis_deg[deg] = [] + ....: basis_deg[deg].append(b) + ....: + sage: basis_deg + {0: [1], 1: [A02, A12, A01, A012, A03, A13, A013, A23, A023, + A123, A04, A14, A014, A24, A024, A124, A34, A034, A134, A234, + A01234], 2: [A02*A01234, A12*A01234, A01*A01234, A012^2, + A03*A01234, A13*A01234, A013^2, A23*A01234, A023^2, A123^2, + A04*A01234, A14*A01234, A014^2, A24*A01234, A024^2, A124^2, + A34*A01234, A034^2, A134^2, A234^2, A01234^2], 3: [A01234^3]} + sage: g_eq_maps = {} + sage: lefschetz_el = ch.lefschetz_element(); lefschetz_el + -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A12 - 2*A13 - 2*A14 - 2*A23 + - 2*A24 - 2*A34 - 6*A012 - 6*A013 - 6*A014 - 6*A023 - 6*A024 + - 6*A034 - 6*A123 - 6*A124 - 6*A134 - 6*A234 - 20*A01234 + sage: for deg in basis_deg: + ....: if deg not in g_eq_maps: + ....: g_eq_maps[deg] = [] + ....: g_eq_maps[deg].extend([i*lefschetz_el for i in basis_deg[deg]]) + ....: + sage: g_eq_maps + {0: [-2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A12 - 2*A13 - 2*A14 + - 2*A23 - 2*A24 - 2*A34 - 6*A012 - 6*A013 - 6*A014 - 6*A023 + - 6*A024 - 6*A034 - 6*A123 - 6*A124 - 6*A134 - 6*A234 + - 20*A01234], 1: [2*A012^2 + 2*A023^2 + 2*A024^2 + - 10*A02*A01234 + 2*A01234^2, 2*A012^2 + 2*A123^2 + 2*A124^2 + - 10*A12*A01234 + 2*A01234^2, 2*A012^2 + 2*A013^2 + 2*A014^2 + - 10*A01*A01234 + 2*A01234^2, -6*A012^2 + 2*A01*A01234 + + 2*A02*A01234 + 2*A12*A01234, 2*A013^2 + 2*A023^2 + 2*A034^2 + - 10*A03*A01234 + 2*A01234^2, 2*A013^2 + 2*A123^2 + 2*A134^2 + - 10*A13*A01234 + 2*A01234^2, -6*A013^2 + 2*A01*A01234 + + 2*A03*A01234 + 2*A13*A01234, 2*A023^2 + 2*A123^2 + 2*A234^2 + - 10*A23*A01234 + 2*A01234^2, -6*A023^2 + 2*A02*A01234 + + 2*A03*A01234 + 2*A23*A01234, -6*A123^2 + 2*A12*A01234 + + 2*A13*A01234 + 2*A23*A01234, 2*A014^2 + 2*A024^2 + 2*A034^2 + - 10*A04*A01234 + 2*A01234^2, 2*A014^2 + 2*A124^2 + 2*A134^2 + - 10*A14*A01234 + 2*A01234^2, -6*A014^2 + 2*A01*A01234 + + 2*A04*A01234 + 2*A14*A01234, 2*A024^2 + 2*A124^2 + 2*A234^2 + - 10*A24*A01234 + 2*A01234^2, -6*A024^2 + 2*A02*A01234 + + 2*A04*A01234 + 2*A24*A01234, -6*A124^2 + 2*A12*A01234 + + 2*A14*A01234 + 2*A24*A01234, 2*A034^2 + 2*A134^2 + 2*A234^2 + - 10*A34*A01234 + 2*A01234^2, -6*A034^2 + 2*A03*A01234 + + 2*A04*A01234 + 2*A34*A01234, -6*A134^2 + 2*A13*A01234 + + 2*A14*A01234 + 2*A34*A01234, -6*A234^2 + 2*A23*A01234 + + 2*A24*A01234 + 2*A34*A01234, -2*A01*A01234 - 2*A02*A01234 + - 2*A03*A01234 - 2*A04*A01234 - 2*A12*A01234 - 2*A13*A01234 + - 2*A14*A01234 - 2*A23*A01234 - 2*A24*A01234 - 2*A34*A01234 + - 20*A01234^2], 2: [2*A01234^3, 2*A01234^3, 2*A01234^3, + 6*A01234^3, 2*A01234^3, 2*A01234^3, 6*A01234^3, 2*A01234^3, + 6*A01234^3, 6*A01234^3, 2*A01234^3, 2*A01234^3, 6*A01234^3, + 2*A01234^3, 6*A01234^3, 6*A01234^3, 2*A01234^3, 6*A01234^3, + 6*A01234^3, 6*A01234^3, -20*A01234^3], 3: [0]} + + TESTS:: + + sage: U46 = matroids.Uniform(4,6) + sage: C = U46.chow_ring(QQ, False) + sage: w = C.lefschetz_element(); w + -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A05 - 2*A12 - 2*A13 - 2*A14 - 2*A15 - 2*A23 - 2*A24 - 2*A25 - 2*A34 - 2*A35 - 2*A45 - 6*A012 - 6*A013 - 6*A014 - 6*A015 - 6*A023 - 6*A024 - 6*A025 - 6*A034 - 6*A035 - 6*A045 - 6*A123 - 6*A124 - 6*A125 - 6*A134 - 6*A135 - 6*A145 - 6*A234 - 6*A235 - 6*A245 - 6*A345 - 30*A012345 + sage: basis_deg = {} + sage: for b in C.basis(): + ....: deg = b.homogeneous_degree() + ....: if deg not in basis_deg: + ....: basis_deg[deg] = [] + ....: basis_deg[deg].append(b) + sage: m = max(basis_deg); m + 3 + sage: len(basis_deg[1]) == len(basis_deg[2]) + True + sage: matrix([(w*b).to_vector() for b in basis_deg[1]]).rank() + 36 + sage: len(basis_deg[2]) + 36 + """ + w = sum(len(F) * (len(self.matroid().groundset()) - len(F)) * gen for F, gen in self.flats_generator().items()) + return w + class Element(QuotientRing_generic.Element): def to_vector(self, order=None): r""" From 38ebe742175828b55a975d98f25ab20437d85d23 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 12:59:00 +0530 Subject: [PATCH 050/175] Formatted kahler_algebras.py --- src/sage/categories/kahler_algebras.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 0ec85c4fbdb..543a1a9c1b2 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -30,7 +30,7 @@ class KahlerAlgebras(Category_over_base_ring): sage: TestSuite(C).run() """ def super_categories(self): - return [GradedAlgebrasWithBasis(self.base_ring())] + return [GradedAlgebrasWithBasis(self.base_ring())] class ParentMethods: def poincare_pairing(self, el1, el2, r): @@ -69,10 +69,10 @@ def hodge_riemann_relations(self, k, r): Kähler algebra. EXAMPLES:: - + sage: ch = matroids.Uniform(4,6).chow_ring(QQ, False) sage: ch.hodge_riemann_relations(1, ch.matroid().rank() - 1) - Quadratic form in 36 variables over Rational Field with coefficients: + Quadratic form in 36 variables over Rational Field with coefficients: [ 3 -1 -1 3 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 3 ] [ * 3 -1 3 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 3 ] [ * * 3 3 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 3 ] @@ -123,7 +123,7 @@ def hodge_riemann_relations(self, k, r): coeff = [] for i,el in enumerate(basis_k): for j in range(i, len(basis_k)): - coeff.append((el*(lefschetz_el**(r-(2*k))*basis_k[j])).degree()) + coeff.append((el * (lefschetz_el ** (r-(2*k)) * basis_k[j])).degree()) return QuadraticForm(self.base_ring(), len(basis_k), coeff) else: raise ValueError("k must be less than r < 2") \ No newline at end of file From d36957b7d7a9aac82cf7b5ad8d57f6148ff53576 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 13:16:42 +0530 Subject: [PATCH 051/175] Formatted kahler_algebras.py --- src/sage/categories/kahler_algebras.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 543a1a9c1b2..2bbbc0919f4 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -11,6 +11,7 @@ from sage.misc.abstract_method import abstract_method from sage.quadratic_forms.quadratic_form import QuadraticForm + class KahlerAlgebras(Category_over_base_ring): r""" The category of graded algebras satisfying the Kähler package. From ce47f30050bccd79bf7848bc6f76d5ac8c44bccb Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 15:22:44 +0530 Subject: [PATCH 052/175] Modified index.rst for categories and corrected doctest --- src/doc/en/reference/categories/index.rst | 1 + src/sage/categories/kahler_algebras.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/en/reference/categories/index.rst b/src/doc/en/reference/categories/index.rst index a40cca76e0f..2f6c4ec65d9 100644 --- a/src/doc/en/reference/categories/index.rst +++ b/src/doc/en/reference/categories/index.rst @@ -137,6 +137,7 @@ Individual Categories sage/categories/integral_domains sage/categories/j_trivial_semigroups sage/categories/kac_moody_algebras + sage/categories/kahler_algebras sage/categories/lambda_bracket_algebras sage/categories/lambda_bracket_algebras_with_basis sage/categories/lattice_posets diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 2bbbc0919f4..b0927de41c3 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -111,7 +111,7 @@ def hodge_riemann_relations(self, k, r): [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 ] [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 ] sage: ch.hodge_riemann_relations(3, ch.matroid().rank() - 1) - Traceback (most recent call last): + Traceback (most recent call last): ... ValueError: k must be less than r < 2 """ From b75cffede026463e78831632fbaa5de8294dd649 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 16:33:44 +0530 Subject: [PATCH 053/175] Edited title --- src/sage/categories/kahler_algebras.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index b0927de41c3..385a6a747b2 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -1,5 +1,5 @@ r""" -Category of Kähler Algebras. +Kähler Algebras. AUTHORS: From 15c532379b5f44444a1297595e505ea441c80fd6 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 16:38:23 +0530 Subject: [PATCH 054/175] Formatted title --- src/sage/categories/kahler_algebras.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 385a6a747b2..39cf7264088 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -1,5 +1,5 @@ r""" -Kähler Algebras. +Kähler Algebras AUTHORS: From 7a1a449444001e8b331b1bf01b60188e1d2f456e Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 18:57:15 +0530 Subject: [PATCH 055/175] Added GPL license --- src/sage/categories/kahler_algebras.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 39cf7264088..d1f125b44d7 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -11,7 +11,15 @@ from sage.misc.abstract_method import abstract_method from sage.quadratic_forms.quadratic_form import QuadraticForm - +# **************************************************************************** +# Copyright (C) 2024 Shriya M <25shriya at gmail.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** class KahlerAlgebras(Category_over_base_ring): r""" The category of graded algebras satisfying the Kähler package. From 27c70edbfe648761f9415baa1c9782894061f9d6 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 19:08:03 +0530 Subject: [PATCH 056/175] Implemented poincare_pairing() in Chow rings and made it abstact in the category --- src/sage/categories/kahler_algebras.py | 28 +-- src/sage/matroids/chow_ring.py | 258 ++++++++++++++----------- 2 files changed, 145 insertions(+), 141 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index d1f125b44d7..546725ffcba 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -42,31 +42,9 @@ def super_categories(self): return [GradedAlgebrasWithBasis(self.base_ring())] class ParentMethods: - def poincare_pairing(self, el1, el2, r): - r""" - Return the Poincaré pairing of any two elements of the - Kähler algebra. - - EXAMPLES:: - - sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') - sage: A0, A1, A2, A3, A4, A5, A013, A025, A04, A124, A15, A23, A345, A012345 = ch.gens() - sage: u = ch(-1/6*A2*A012345 + 41/48*A012345^2); u - -1/6*A2*A012345 + 41/48*A012345^2 - sage: v = ch(-A345^2 - 1/4*A345); v - -A345^2 - 1/4*A345 - sage: ch.poincare_pairing(v, u, ch.matroid().rank()) - 3 - """ - hom_components1 = el1.lift().homogeneous_components() - hom_components2 = el2.lift().homogeneous_components() - new_el = self.base_ring().zero() - for i in hom_components1: - for j in hom_components2: - if i == r - j: - new_el += hom_components1[i] * hom_components2[j] - # the 'else' case is new_el += self.base_ring().zero() - return new_el.degree() + @abstract_method + def poincare_pairing(): + pass @abstract_method def lefschetz_element(): diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 45d91a6a4f2..cf1a3c26840 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -199,29 +199,29 @@ def basis(self): def flats_generator(self): r""" - Return the corresponding generators of flats of the Chow ring. + Return the corresponding generators of flats of the Chow ring. - EXAMPLES:: + EXAMPLES:: - sage: ch = matroids.catalog.NonFano().chow_ring(ZZ, True, 'atom-free') - sage: ch.flats_generator() - {frozenset({'a'}): Aa, - frozenset({'b'}): Ab, - frozenset({'c'}): Ac, - frozenset({'d'}): Ad, - frozenset({'e'}): Ae, - frozenset({'f'}): Af, - frozenset({'g'}): Ag, - frozenset({'a', 'b', 'f'}): Aabf, - frozenset({'a', 'c', 'e'}): Aace, - frozenset({'a', 'd', 'g'}): Aadg, - frozenset({'b', 'c', 'd'}): Abcd, - frozenset({'b', 'e', 'g'}): Abeg, - frozenset({'c', 'f', 'g'}): Acfg, - frozenset({'d', 'e'}): Ade, - frozenset({'d', 'f'}): Adf, - frozenset({'e', 'f'}): Aef, - frozenset({'a', 'b', 'c', 'd', 'e', 'f', 'g'}): Aabcdefg} + sage: ch = matroids.catalog.NonFano().chow_ring(ZZ, True, 'atom-free') + sage: ch.flats_generator() + {frozenset({'a'}): Aa, + frozenset({'b'}): Ab, + frozenset({'c'}): Ac, + frozenset({'d'}): Ad, + frozenset({'e'}): Ae, + frozenset({'f'}): Af, + frozenset({'g'}): Ag, + frozenset({'a', 'b', 'f'}): Aabf, + frozenset({'a', 'c', 'e'}): Aace, + frozenset({'a', 'd', 'g'}): Aadg, + frozenset({'b', 'c', 'd'}): Abcd, + frozenset({'b', 'e', 'g'}): Abeg, + frozenset({'c', 'f', 'g'}): Acfg, + frozenset({'d', 'e'}): Ade, + frozenset({'d', 'f'}): Adf, + frozenset({'e', 'f'}): Aef, + frozenset({'a', 'b', 'c', 'd', 'e', 'f', 'g'}): Aabcdefg} """ flats = [X for i in range(1, self._matroid.rank() + 1) for X in self._matroid.flats(i)] @@ -237,109 +237,135 @@ def flats_generator(self): def lefschetz_element(self): r""" - Return one Lefschetz element of the given Chow ring. + Return one Lefschetz element of the given Chow ring. - EXAMPLES:: + EXAMPLES:: - sage: ch = matroids.catalog.P8pp().chow_ring(QQ, False) - sage: ch.lefschetz_element() - -2*Aab - 2*Aac - 2*Aad - 2*Aae - 2*Aaf - 2*Aag - 2*Aah - 2*Abc - - 2*Abd - 2*Abe - 2*Abf - 2*Abg - 2*Abh - 2*Acd - 2*Ace - 2*Acf - - 2*Acg - 2*Ach - 2*Ade - 2*Adf - 2*Adg - 2*Adh - 2*Aef - 2*Aeg - - 2*Aeh - 2*Afg - 2*Afh - 2*Agh - 6*Aabc - 6*Aabd - 6*Aabe - - 12*Aabfh - 6*Aabg - 6*Aacd - 12*Aacef - 12*Aacgh - 12*Aadeg - - 6*Aadf - 6*Aadh - 6*Aaeh - 6*Aafg - 6*Abcd - 12*Abceg - - 6*Abcf - 6*Abch - 12*Abdeh - 12*Abdfg - 6*Abef - 6*Abgh - - 6*Acde - 12*Acdfh - 6*Acdg - 6*Aceh - 6*Acfg - 6*Adef - - 6*Adgh - 6*Aefg - 6*Aefh - 6*Aegh - 6*Afgh - 56*Aabcdefgh - - The following example finds the Lefschetz element of the Chow ring - of the uniform matroid of rank 4 on 5 elements (non-augmented). - It is then multiplied with the elements of FY-monomial bases of - different degrees:: - - sage: ch = matroids.Uniform(4,5).chow_ring(QQ, False) - sage: basis_deg = {} - sage: for b in ch.basis(): - ....: deg = b.homogeneous_degree() - ....: if deg not in basis_deg: - ....: basis_deg[deg] = [] - ....: basis_deg[deg].append(b) - ....: - sage: basis_deg - {0: [1], 1: [A02, A12, A01, A012, A03, A13, A013, A23, A023, - A123, A04, A14, A014, A24, A024, A124, A34, A034, A134, A234, - A01234], 2: [A02*A01234, A12*A01234, A01*A01234, A012^2, - A03*A01234, A13*A01234, A013^2, A23*A01234, A023^2, A123^2, - A04*A01234, A14*A01234, A014^2, A24*A01234, A024^2, A124^2, - A34*A01234, A034^2, A134^2, A234^2, A01234^2], 3: [A01234^3]} - sage: g_eq_maps = {} - sage: lefschetz_el = ch.lefschetz_element(); lefschetz_el - -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A12 - 2*A13 - 2*A14 - 2*A23 - - 2*A24 - 2*A34 - 6*A012 - 6*A013 - 6*A014 - 6*A023 - 6*A024 - - 6*A034 - 6*A123 - 6*A124 - 6*A134 - 6*A234 - 20*A01234 - sage: for deg in basis_deg: - ....: if deg not in g_eq_maps: - ....: g_eq_maps[deg] = [] - ....: g_eq_maps[deg].extend([i*lefschetz_el for i in basis_deg[deg]]) - ....: - sage: g_eq_maps - {0: [-2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A12 - 2*A13 - 2*A14 - - 2*A23 - 2*A24 - 2*A34 - 6*A012 - 6*A013 - 6*A014 - 6*A023 - - 6*A024 - 6*A034 - 6*A123 - 6*A124 - 6*A134 - 6*A234 - - 20*A01234], 1: [2*A012^2 + 2*A023^2 + 2*A024^2 - - 10*A02*A01234 + 2*A01234^2, 2*A012^2 + 2*A123^2 + 2*A124^2 - - 10*A12*A01234 + 2*A01234^2, 2*A012^2 + 2*A013^2 + 2*A014^2 - - 10*A01*A01234 + 2*A01234^2, -6*A012^2 + 2*A01*A01234 - + 2*A02*A01234 + 2*A12*A01234, 2*A013^2 + 2*A023^2 + 2*A034^2 - - 10*A03*A01234 + 2*A01234^2, 2*A013^2 + 2*A123^2 + 2*A134^2 - - 10*A13*A01234 + 2*A01234^2, -6*A013^2 + 2*A01*A01234 - + 2*A03*A01234 + 2*A13*A01234, 2*A023^2 + 2*A123^2 + 2*A234^2 - - 10*A23*A01234 + 2*A01234^2, -6*A023^2 + 2*A02*A01234 - + 2*A03*A01234 + 2*A23*A01234, -6*A123^2 + 2*A12*A01234 - + 2*A13*A01234 + 2*A23*A01234, 2*A014^2 + 2*A024^2 + 2*A034^2 - - 10*A04*A01234 + 2*A01234^2, 2*A014^2 + 2*A124^2 + 2*A134^2 - - 10*A14*A01234 + 2*A01234^2, -6*A014^2 + 2*A01*A01234 - + 2*A04*A01234 + 2*A14*A01234, 2*A024^2 + 2*A124^2 + 2*A234^2 - - 10*A24*A01234 + 2*A01234^2, -6*A024^2 + 2*A02*A01234 - + 2*A04*A01234 + 2*A24*A01234, -6*A124^2 + 2*A12*A01234 - + 2*A14*A01234 + 2*A24*A01234, 2*A034^2 + 2*A134^2 + 2*A234^2 - - 10*A34*A01234 + 2*A01234^2, -6*A034^2 + 2*A03*A01234 - + 2*A04*A01234 + 2*A34*A01234, -6*A134^2 + 2*A13*A01234 - + 2*A14*A01234 + 2*A34*A01234, -6*A234^2 + 2*A23*A01234 - + 2*A24*A01234 + 2*A34*A01234, -2*A01*A01234 - 2*A02*A01234 - - 2*A03*A01234 - 2*A04*A01234 - 2*A12*A01234 - 2*A13*A01234 - - 2*A14*A01234 - 2*A23*A01234 - 2*A24*A01234 - 2*A34*A01234 - - 20*A01234^2], 2: [2*A01234^3, 2*A01234^3, 2*A01234^3, - 6*A01234^3, 2*A01234^3, 2*A01234^3, 6*A01234^3, 2*A01234^3, - 6*A01234^3, 6*A01234^3, 2*A01234^3, 2*A01234^3, 6*A01234^3, - 2*A01234^3, 6*A01234^3, 6*A01234^3, 2*A01234^3, 6*A01234^3, - 6*A01234^3, 6*A01234^3, -20*A01234^3], 3: [0]} + sage: ch = matroids.catalog.P8pp().chow_ring(QQ, False) + sage: ch.lefschetz_element() + -2*Aab - 2*Aac - 2*Aad - 2*Aae - 2*Aaf - 2*Aag - 2*Aah - 2*Abc + - 2*Abd - 2*Abe - 2*Abf - 2*Abg - 2*Abh - 2*Acd - 2*Ace - 2*Acf + - 2*Acg - 2*Ach - 2*Ade - 2*Adf - 2*Adg - 2*Adh - 2*Aef - 2*Aeg + - 2*Aeh - 2*Afg - 2*Afh - 2*Agh - 6*Aabc - 6*Aabd - 6*Aabe + - 12*Aabfh - 6*Aabg - 6*Aacd - 12*Aacef - 12*Aacgh - 12*Aadeg + - 6*Aadf - 6*Aadh - 6*Aaeh - 6*Aafg - 6*Abcd - 12*Abceg + - 6*Abcf - 6*Abch - 12*Abdeh - 12*Abdfg - 6*Abef - 6*Abgh + - 6*Acde - 12*Acdfh - 6*Acdg - 6*Aceh - 6*Acfg - 6*Adef + - 6*Adgh - 6*Aefg - 6*Aefh - 6*Aegh - 6*Afgh - 56*Aabcdefgh + + The following example finds the Lefschetz element of the Chow ring + of the uniform matroid of rank 4 on 5 elements (non-augmented). + It is then multiplied with the elements of FY-monomial bases of + different degrees:: + + sage: ch = matroids.Uniform(4,5).chow_ring(QQ, False) + sage: basis_deg = {} + sage: for b in ch.basis(): + ....: deg = b.homogeneous_degree() + ....: if deg not in basis_deg: + ....: basis_deg[deg] = [] + ....: basis_deg[deg].append(b) + ....: + sage: basis_deg + {0: [1], 1: [A02, A12, A01, A012, A03, A13, A013, A23, A023, + A123, A04, A14, A014, A24, A024, A124, A34, A034, A134, A234, + A01234], 2: [A02*A01234, A12*A01234, A01*A01234, A012^2, + A03*A01234, A13*A01234, A013^2, A23*A01234, A023^2, A123^2, + A04*A01234, A14*A01234, A014^2, A24*A01234, A024^2, A124^2, + A34*A01234, A034^2, A134^2, A234^2, A01234^2], 3: [A01234^3]} + sage: g_eq_maps = {} + sage: lefschetz_el = ch.lefschetz_element(); lefschetz_el + -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A12 - 2*A13 - 2*A14 - 2*A23 + - 2*A24 - 2*A34 - 6*A012 - 6*A013 - 6*A014 - 6*A023 - 6*A024 + - 6*A034 - 6*A123 - 6*A124 - 6*A134 - 6*A234 - 20*A01234 + sage: for deg in basis_deg: + ....: if deg not in g_eq_maps: + ....: g_eq_maps[deg] = [] + ....: g_eq_maps[deg].extend([i*lefschetz_el for i in basis_deg[deg]]) + ....: + sage: g_eq_maps + {0: [-2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A12 - 2*A13 - 2*A14 + - 2*A23 - 2*A24 - 2*A34 - 6*A012 - 6*A013 - 6*A014 - 6*A023 + - 6*A024 - 6*A034 - 6*A123 - 6*A124 - 6*A134 - 6*A234 + - 20*A01234], 1: [2*A012^2 + 2*A023^2 + 2*A024^2 + - 10*A02*A01234 + 2*A01234^2, 2*A012^2 + 2*A123^2 + 2*A124^2 + - 10*A12*A01234 + 2*A01234^2, 2*A012^2 + 2*A013^2 + 2*A014^2 + - 10*A01*A01234 + 2*A01234^2, -6*A012^2 + 2*A01*A01234 + + 2*A02*A01234 + 2*A12*A01234, 2*A013^2 + 2*A023^2 + 2*A034^2 + - 10*A03*A01234 + 2*A01234^2, 2*A013^2 + 2*A123^2 + 2*A134^2 + - 10*A13*A01234 + 2*A01234^2, -6*A013^2 + 2*A01*A01234 + + 2*A03*A01234 + 2*A13*A01234, 2*A023^2 + 2*A123^2 + 2*A234^2 + - 10*A23*A01234 + 2*A01234^2, -6*A023^2 + 2*A02*A01234 + + 2*A03*A01234 + 2*A23*A01234, -6*A123^2 + 2*A12*A01234 + + 2*A13*A01234 + 2*A23*A01234, 2*A014^2 + 2*A024^2 + 2*A034^2 + - 10*A04*A01234 + 2*A01234^2, 2*A014^2 + 2*A124^2 + 2*A134^2 + - 10*A14*A01234 + 2*A01234^2, -6*A014^2 + 2*A01*A01234 + + 2*A04*A01234 + 2*A14*A01234, 2*A024^2 + 2*A124^2 + 2*A234^2 + - 10*A24*A01234 + 2*A01234^2, -6*A024^2 + 2*A02*A01234 + + 2*A04*A01234 + 2*A24*A01234, -6*A124^2 + 2*A12*A01234 + + 2*A14*A01234 + 2*A24*A01234, 2*A034^2 + 2*A134^2 + 2*A234^2 + - 10*A34*A01234 + 2*A01234^2, -6*A034^2 + 2*A03*A01234 + + 2*A04*A01234 + 2*A34*A01234, -6*A134^2 + 2*A13*A01234 + + 2*A14*A01234 + 2*A34*A01234, -6*A234^2 + 2*A23*A01234 + + 2*A24*A01234 + 2*A34*A01234, -2*A01*A01234 - 2*A02*A01234 + - 2*A03*A01234 - 2*A04*A01234 - 2*A12*A01234 - 2*A13*A01234 + - 2*A14*A01234 - 2*A23*A01234 - 2*A24*A01234 - 2*A34*A01234 + - 20*A01234^2], 2: [2*A01234^3, 2*A01234^3, 2*A01234^3, + 6*A01234^3, 2*A01234^3, 2*A01234^3, 6*A01234^3, 2*A01234^3, + 6*A01234^3, 6*A01234^3, 2*A01234^3, 2*A01234^3, 6*A01234^3, + 2*A01234^3, 6*A01234^3, 6*A01234^3, 2*A01234^3, 6*A01234^3, + 6*A01234^3, 6*A01234^3, -20*A01234^3], 3: [0]} - TESTS:: + TESTS:: - sage: U46 = matroids.Uniform(4,6) - sage: C = U46.chow_ring(QQ, False) - sage: w = C.lefschetz_element(); w - -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A05 - 2*A12 - 2*A13 - 2*A14 - 2*A15 - 2*A23 - 2*A24 - 2*A25 - 2*A34 - 2*A35 - 2*A45 - 6*A012 - 6*A013 - 6*A014 - 6*A015 - 6*A023 - 6*A024 - 6*A025 - 6*A034 - 6*A035 - 6*A045 - 6*A123 - 6*A124 - 6*A125 - 6*A134 - 6*A135 - 6*A145 - 6*A234 - 6*A235 - 6*A245 - 6*A345 - 30*A012345 - sage: basis_deg = {} - sage: for b in C.basis(): - ....: deg = b.homogeneous_degree() - ....: if deg not in basis_deg: - ....: basis_deg[deg] = [] - ....: basis_deg[deg].append(b) - sage: m = max(basis_deg); m - 3 - sage: len(basis_deg[1]) == len(basis_deg[2]) - True - sage: matrix([(w*b).to_vector() for b in basis_deg[1]]).rank() - 36 - sage: len(basis_deg[2]) - 36 + sage: U46 = matroids.Uniform(4,6) + sage: C = U46.chow_ring(QQ, False) + sage: w = C.lefschetz_element(); w + -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A05 - 2*A12 - 2*A13 - 2*A14 - 2*A15 - 2*A23 - 2*A24 - 2*A25 - 2*A34 - 2*A35 - 2*A45 - 6*A012 - 6*A013 - 6*A014 - 6*A015 - 6*A023 - 6*A024 - 6*A025 - 6*A034 - 6*A035 - 6*A045 - 6*A123 - 6*A124 - 6*A125 - 6*A134 - 6*A135 - 6*A145 - 6*A234 - 6*A235 - 6*A245 - 6*A345 - 30*A012345 + sage: basis_deg = {} + sage: for b in C.basis(): + ....: deg = b.homogeneous_degree() + ....: if deg not in basis_deg: + ....: basis_deg[deg] = [] + ....: basis_deg[deg].append(b) + sage: m = max(basis_deg); m + 3 + sage: len(basis_deg[1]) == len(basis_deg[2]) + True + sage: matrix([(w*b).to_vector() for b in basis_deg[1]]).rank() + 36 + sage: len(basis_deg[2]) + 36 """ w = sum(len(F) * (len(self.matroid().groundset()) - len(F)) * gen for F, gen in self.flats_generator().items()) return w + def poincare_pairing(self, el1, el2, r): + r""" + Return the Poincaré pairing of any two elements of the + Kähler algebra. + + EXAMPLES:: + + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') + sage: A0, A1, A2, A3, A4, A5, A013, A025, A04, A124, A15, A23, A345, A012345 = ch.gens() + sage: u = ch(-1/6*A2*A012345 + 41/48*A012345^2); u + -1/6*A2*A012345 + 41/48*A012345^2 + sage: v = ch(-A345^2 - 1/4*A345); v + -A345^2 - 1/4*A345 + sage: ch.poincare_pairing(v, u, ch.matroid().rank()) + 3 + """ + hom_components1 = el1.lift().homogeneous_components() + hom_components2 = el2.lift().homogeneous_components() + new_el = self.base_ring().zero() + for i in hom_components1: + for j in hom_components2: + if i == r - j: + new_el += hom_components1[i] * hom_components2[j] + # the 'else' case is new_el += self.base_ring().zero() + return new_el.degree() + class Element(QuotientRing_generic.Element): def to_vector(self, order=None): r""" From c2720cb643261ea528e20968a84053c1acd2aaa8 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 19:12:25 +0530 Subject: [PATCH 057/175] Modified poincare_pairing() method --- src/sage/matroids/chow_ring.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index cf1a3c26840..57e701252b5 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -343,7 +343,7 @@ def lefschetz_element(self): def poincare_pairing(self, el1, el2, r): r""" Return the Poincaré pairing of any two elements of the - Kähler algebra. + Chow ring. EXAMPLES:: @@ -361,9 +361,9 @@ def poincare_pairing(self, el1, el2, r): new_el = self.base_ring().zero() for i in hom_components1: for j in hom_components2: - if i == r - j: - new_el += hom_components1[i] * hom_components2[j] - # the 'else' case is new_el += self.base_ring().zero() + if r - i not in hom_components2: + continue + new_el += hom_components1[i] * hom_components2[j] return new_el.degree() class Element(QuotientRing_generic.Element): From 9423bd82ff7553a17838d98cc01566544d413028 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 19:21:08 +0530 Subject: [PATCH 058/175] Modified flats_generator for ChowRing --- src/sage/matroids/chow_ring.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 57e701252b5..2042e53dbba 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -226,14 +226,13 @@ def flats_generator(self): flats = [X for i in range(1, self._matroid.rank() + 1) for X in self._matroid.flats(i)] gens = self.gens() - if self._augmented & (self._presentation == 'fy'): - flats_gen = {} - E = list(self.matroid().groundset()) - for i,F in enumerate(flats): - flats_gen[F] = gens[len(E) + i] - return flats_gen - else: + if not (self._augmented and self._presentation == 'fy'): return dict(zip(flats, gens)) + flats_gen = {} + E = list(self.matroid().groundset()) + for i,F in enumerate(flats): + flats_gen[F] = gens[len(E) + i] + return flats_gen def lefschetz_element(self): r""" From 85bc761fb9943569a5414acc5b5e90b9f7dc7e9d Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 19:22:48 +0530 Subject: [PATCH 059/175] Modified hodge_riemann_relations() --- src/sage/categories/kahler_algebras.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 546725ffcba..293775841d5 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -101,16 +101,15 @@ def hodge_riemann_relations(self, k, r): ... ValueError: k must be less than r < 2 """ - if k < (r/2): - basis_k = [] - lefschetz_el = self.lefschetz_element() - for b in self.basis(): - if b.homogeneous_degree() == k: - basis_k.append(b) - coeff = [] - for i,el in enumerate(basis_k): - for j in range(i, len(basis_k)): - coeff.append((el * (lefschetz_el ** (r-(2*k)) * basis_k[j])).degree()) - return QuadraticForm(self.base_ring(), len(basis_k), coeff) - else: - raise ValueError("k must be less than r < 2") \ No newline at end of file + if k >= (r/2): + raise ValueError("k must be less than r < 2") + basis_k = [] + lefschetz_el = self.lefschetz_element() + for b in self.basis(): + if b.homogeneous_degree() == k: + basis_k.append(b) + coeff = [] + for i,el in enumerate(basis_k): + for j in range(i, len(basis_k)): + coeff.append((el * (lefschetz_el ** (r-(2*k)) * basis_k[j])).degree()) + return QuadraticForm(self.base_ring(), len(basis_k), coeff) \ No newline at end of file From e772478cdd6fd6b0392ffa87908323c4890c5f98 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 19 Dec 2024 19:42:05 +0530 Subject: [PATCH 060/175] Fixed linting errors --- src/sage/categories/kahler_algebras.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 293775841d5..19d0a798ab2 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -11,6 +11,7 @@ from sage.misc.abstract_method import abstract_method from sage.quadratic_forms.quadratic_form import QuadraticForm + # **************************************************************************** # Copyright (C) 2024 Shriya M <25shriya at gmail.com> # @@ -112,4 +113,4 @@ def hodge_riemann_relations(self, k, r): for i,el in enumerate(basis_k): for j in range(i, len(basis_k)): coeff.append((el * (lefschetz_el ** (r-(2*k)) * basis_k[j])).degree()) - return QuadraticForm(self.base_ring(), len(basis_k), coeff) \ No newline at end of file + return QuadraticForm(self.base_ring(), len(basis_k), coeff) \ No newline at end of file From fc1d59fa62fdbed7d3460aed4e250d446d3bfbac Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 21 Dec 2024 13:33:11 +0100 Subject: [PATCH 061/175] replace _restricted with _constrained to avoid misconceptions --- src/sage/combinat/partition.py | 70 +++++++++++++++++----------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 2fd1c799e20..0bd6fad7b9f 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6177,14 +6177,14 @@ def __classcall_private__(cls, n=None, **kwargs): max_part = min(kwargs['max_part'], n) if max_part < 1: return Partitions_n(-1) - return Partitions_length_and_parts_restricted(n, 1, n, 1, max_part) + return Partitions_length_and_parts_constrained(n, 1, n, 1, max_part) if 'min_part' in kwargs: if not n: return Partitions_n(0) min_part = max(kwargs['min_part'], 1) if min_part > n: return Partitions_n(-1) - return Partitions_length_and_parts_restricted(n, 1, n, min_part, n) + return Partitions_length_and_parts_constrained(n, 1, n, min_part, n) if 'length' in kwargs: return Partitions_nk(n, kwargs['length']) if 'parts_in' in kwargs: @@ -6237,7 +6237,7 @@ def __classcall_private__(cls, n=None, **kwargs): if min_part > max_part: return Partitions_n(-1) - return Partitions_length_and_parts_restricted(n, min_length, max_length, min_part, max_part) + return Partitions_length_and_parts_constrained(n, min_length, max_length, min_part, max_part) # FIXME: should inherit from IntegerListLex, and implement repr, or _name as a lazy attribute kwargs['name'] = "Partitions of the integer {} satisfying constraints {}".format(n, ", ".join(["{}={}".format(key, kwargs[key]) for key in sorted(kwargs)])) @@ -6288,7 +6288,7 @@ def __classcall_private__(cls, n=None, **kwargs): elif 'max_part' in kwargs and 'max_length' in kwargs: return PartitionsInBox(kwargs['max_length'], kwargs['max_part']) - return Partitions_all_restricted(**kwargs) + return Partitions_all_constrained(**kwargs) raise ValueError("n must be an integer or be equal to one of " "None, NN, NonNegativeIntegers()") @@ -6806,14 +6806,14 @@ def from_core_and_quotient(self, core, quotient): return self.element_class(self, [new_w[i]+i for i in range(len(new_w))]) -class Partitions_all_restricted(Partitions): +class Partitions_all_constrained(Partitions): def __init__(self, **kwargs): """ TESTS:: - sage: TestSuite(sage.combinat.partition.Partitions_all_restricted(max_length=3)).run() # long time + sage: TestSuite(sage.combinat.partition.Partitions_all_constrained(max_length=3)).run() # long time """ - self._restrictions = kwargs + self._constraints = kwargs Partitions.__init__(self, is_infinite=True) def __contains__(self, x): @@ -6837,7 +6837,7 @@ def __contains__(self, x): True """ try: - return mu in Partitions(sum(mu), **self._restrictions) + return mu in Partitions(sum(mu), **self._constraints) except Exception: return False @@ -6849,11 +6849,11 @@ def _repr_(self): Partitions satisfying constraints max_length=4, max_part=3, min_length=2 """ return "Partitions satisfying constraints " + ", ".join(["{}={}".format(key, value) - for key, value in sorted(self._restrictions.items())]) + for key, value in sorted(self._constraints.items())]) def __iter__(self): """ - An iterator for partitions with various restrictions. + An iterator for partitions with various constraints. EXAMPLES:: @@ -6864,7 +6864,7 @@ def __iter__(self): """ n = 0 while True: - for p in Partitions(n, **self._restrictions): + for p in Partitions(n, **self._constraints): yield self.element_class(self, p) n += 1 @@ -8929,11 +8929,11 @@ def cardinality(self): return ZZ(ans) -########################################## -# Partitions_length_and_parts_restricted # -########################################## +########################################### +# Partitions_length_and_parts_constrained # +########################################### -class Partitions_length_and_parts_restricted(Partitions): +class Partitions_length_and_parts_constrained(Partitions): r""" The class of all integer partitions having parts and length in a given range. @@ -8941,7 +8941,7 @@ class Partitions_length_and_parts_restricted(Partitions): This class is strictly more general than :class:`PartitionsGreatestLE`, except that we insist that the size of the partition is positive and that neither the - restrictions on the parts nor on the length are contradictory. + constraints on the parts nor on the length are contradictory. INPUT: @@ -8953,15 +8953,15 @@ class Partitions_length_and_parts_restricted(Partitions): EXAMPLES:: - sage: from sage.combinat.partition import Partitions_length_and_parts_restricted - sage: Partitions_length_and_parts_restricted(10, 1, 10, 2, 5) + sage: from sage.combinat.partition import Partitions_length_and_parts_constrained + sage: Partitions_length_and_parts_constrained(10, 1, 10, 2, 5) Partitions of 10 whose parts are between 2 and 5 - sage: list(Partitions_length_and_parts_restricted(9, 3, 4, 2, 4)) + sage: list(Partitions_length_and_parts_constrained(9, 3, 4, 2, 4)) [[4, 3, 2], [3, 3, 3], [3, 2, 2, 2]] - sage: [4,3,2,1] in Partitions_length_and_parts_restricted(10, 1, 10, 2, 10) + sage: [4,3,2,1] in Partitions_length_and_parts_constrained(10, 1, 10, 2, 10) False - sage: [2,2,2,2,2] in Partitions_length_and_parts_restricted(10, 1, 10, 2, 10) + sage: [2,2,2,2,2] in Partitions_length_and_parts_constrained(10, 1, 10, 2, 10) True .. WARNING:: @@ -8973,9 +8973,9 @@ class Partitions_length_and_parts_restricted(Partitions): :: - sage: Partitions_length_and_parts_restricted(9, 1, 9, 1, 9) + sage: Partitions_length_and_parts_constrained(9, 1, 9, 1, 9) Partitions of 9 - sage: Partitions_length_and_parts_restricted(9, 1, 9, 1, 9) == Partitions(9) + sage: Partitions_length_and_parts_constrained(9, 1, 9, 1, 9) == Partitions(9) False """ def __init__(self, n, min_length, max_length, min_part, max_part): @@ -8984,8 +8984,8 @@ def __init__(self, n, min_length, max_length, min_part, max_part): TESTS:: - sage: from sage.combinat.partition import Partitions_length_and_parts_restricted - sage: p = Partitions_length_and_parts_restricted(10, 2, 5, 3, 4) + sage: from sage.combinat.partition import Partitions_length_and_parts_constrained + sage: p = Partitions_length_and_parts_constrained(10, 2, 5, 3, 4) sage: TestSuite(p).run() """ if not (1 <= min_part <= max_part <= n): @@ -9005,18 +9005,18 @@ def _repr_(self): TESTS:: - sage: from sage.combinat.partition import Partitions_length_and_parts_restricted - sage: Partitions_length_and_parts_restricted(9, 1, 9, 1, 9) + sage: from sage.combinat.partition import Partitions_length_and_parts_constrained + sage: Partitions_length_and_parts_constrained(9, 1, 9, 1, 9) Partitions of 9 - sage: Partitions_length_and_parts_restricted(9, 1, 3, 1, 9) + sage: Partitions_length_and_parts_constrained(9, 1, 3, 1, 9) Partitions of 9 having length at most 3 - sage: Partitions_length_and_parts_restricted(9, 3, 9, 1, 9) + sage: Partitions_length_and_parts_constrained(9, 3, 9, 1, 9) Partitions of 9 having length at least 3 - sage: Partitions_length_and_parts_restricted(9, 1, 9, 2, 9) + sage: Partitions_length_and_parts_constrained(9, 1, 9, 2, 9) Partitions of 9 whose parts are at least 2 - sage: Partitions_length_and_parts_restricted(9, 1, 9, 1, 3) + sage: Partitions_length_and_parts_constrained(9, 1, 9, 1, 3) Partitions of 9 whose parts are at most 3 - sage: Partitions_length_and_parts_restricted(9, 3, 5, 2, 9) + sage: Partitions_length_and_parts_constrained(9, 3, 5, 2, 9) Partitions of 9 having length between 3 and 5 and whose parts are at least 2 """ if self._min_length == 1 and self._max_length == self._n: @@ -9096,10 +9096,10 @@ def cardinality(self): EXAMPLES:: - sage: from sage.combinat.partition import Partitions_length_and_parts_restricted - sage: list(Partitions_length_and_parts_restricted(9, 1, 2, 3, 9)) + sage: from sage.combinat.partition import Partitions_length_and_parts_constrained + sage: list(Partitions_length_and_parts_constrained(9, 1, 2, 3, 9)) [[9], [6, 3], [5, 4]] - sage: Partitions_length_and_parts_restricted(9, 1, 2, 3, 9).cardinality() + sage: Partitions_length_and_parts_constrained(9, 1, 2, 3, 9).cardinality() 3 TESTS:: From 87c44c8a420da308b6aeba904f0c992b30a4ba1a Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 21 Dec 2024 16:39:56 +0100 Subject: [PATCH 062/175] add doctests for containment with trailing zero --- src/sage/combinat/partition.py | 58 ++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 0bd6fad7b9f..f607cea6957 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6820,7 +6820,8 @@ def __contains__(self, x): """ TESTS:: - sage: P = Partitions(max_part=3, max_length=2) + sage: from sage.combinat.partition import Partitions_all_constrained + sage: P = Partitions_all_constrained(max_part=3, max_length=2) sage: Partition([2,1]) in P True sage: [2,1] in P @@ -6835,6 +6836,8 @@ def __contains__(self, x): True sage: [] in P True + sage: [3,1,0] in P + True """ try: return mu in Partitions(sum(mu), **self._constraints) @@ -7373,6 +7376,8 @@ def __contains__(self, x): False sage: [5] in p False + sage: [4,1,0] in p + True """ return x in _Partitions and sum(x) == self.n and len(x) == self.k @@ -7590,11 +7595,14 @@ def __contains__(self, x): """ TESTS:: - sage: p = Partitions(5, parts_in=[1,2]) + sage: from sage.combinat.partition import Partitions_parts_in + sage: p = Partitions_parts_in(5, [1,2]) sage: [2,1,1,1] in p True sage: [4,1] in p False + sage: [2,1,1,1,0] in p + True """ return (x in _Partitions and sum(x) == self.n and all(p in self.parts for p in x)) @@ -7945,6 +7953,12 @@ def __contains__(self, x): True sage: [3] in p False + + TESTS:: + + sage: from sage.combinat.partition import Partitions_starting + sage: [2,1,0] in Partitions_starting(3, [2, 1]) + True """ return x in Partitions_n(self.n) and x <= self._starting @@ -8057,6 +8071,12 @@ def __contains__(self, x): False sage: [2,1] in p False + + TESTS:: + + sage: from sage.combinat.partition import Partitions_ending + sage: [4,0] in Partitions_ending(3, [2, 2]) + True """ return x in Partitions_n(self.n) and x >= self._ending @@ -8158,6 +8178,8 @@ def __contains__(self, x): False sage: [3,1] in PartitionsInBox(2, 3) True + sage: [3,1,0] in PartitionsInBox(2, 3) + True """ return x in _Partitions and len(x) <= self.h \ and (len(x) == 0 or x[0] <= self.w) @@ -8333,7 +8355,8 @@ def __contains__(self, x): """ TESTS:: - sage: P = Partitions(regular=3) + sage: from sage.combinat.partition import RegularPartitions + sage: P = RegularPartitions(3) sage: [5] in P True sage: [] in P @@ -8495,13 +8518,16 @@ def __contains__(self, x): """ TESTS:: - sage: P = Partitions(regular=4, max_length=3) + sage: from sage.combinat.partition import RegularPartitions_truncated + sage: P = RegularPartitions_truncated(4, 3) sage: [3, 3, 3] in P True sage: [] in P True sage: [4, 2, 1, 1] in P False + sage: [0,0,0,0] in P + True """ return len(x) <= self._max_len and RegularPartitions.__contains__(self, x) @@ -8612,13 +8638,16 @@ def __contains__(self, x): """ TESTS:: - sage: P = Partitions(regular=4, max_part=3) + sage: from sage.combinat.partition import RegularPartitions_bounded + sage: P = RegularPartitions_bounded(4, 3) sage: [3, 3, 3] in P True sage: [] in P True sage: [4, 2, 1] in P False + sage: [0,0,0,0,0] in P + True """ return len(x) == 0 or (x[0] <= self.k and RegularPartitions.__contains__(self, x)) @@ -8699,11 +8728,14 @@ def __contains__(self, x): """ TESTS:: - sage: P = Partitions(5, regular=3) + sage: from sage.combinat.partition import RegularPartitions_n + sage: P = RegularPartitions_n(5, 3) sage: [3, 1, 1] in P True sage: [3, 2, 1] in P False + sage: [5, 0, 0, 0, 0] in P + True """ return RegularPartitions.__contains__(self, x) and sum(x) == self.n @@ -9055,7 +9087,8 @@ def __contains__(self, x): TESTS:: - sage: P = Partitions(10, min_part=2, max_part=5, min_length=2, max_length=4) + sage: from sage.combinat.partition import Partitions_length_and_parts_constrained + sage: P = Partitions_length_and_parts_constrained(10, 2, 5, 2, 4) sage: Partition([]) in P False @@ -9064,6 +9097,9 @@ def __contains__(self, x): sage: Partition([5, 3, 2]) in P True + + sage: Partition([5, 3, 2, 0, 0]) in P + True """ if x not in _Partitions: return False @@ -9351,7 +9387,8 @@ def __contains__(self, x): """ TESTS:: - sage: P = Partitions(restricted=3) + sage: from sage.combinat.partition import RestrictedPartitions_generic + sage: P = RestrictedPartitions_generic(3) sage: [5] in P False sage: [2] in P @@ -9514,11 +9551,14 @@ def __contains__(self, x): """ TESTS:: - sage: P = Partitions(5, regular=3) + sage: from sage.combinat.partition import RestrictedPartitions_n + sage: P = RestrictedPartitions_n(5, 3) sage: [3, 1, 1] in P True sage: [3, 2, 1] in P False + sage: [5, 0, 0, 0, 0] in P + True """ return RestrictedPartitions_generic.__contains__(self, x) and sum(x) == self.n From 48c32d8164f9cd1d724f64c419e81bf4b4ad4801 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 21 Dec 2024 16:52:20 +0100 Subject: [PATCH 063/175] fix typo --- src/sage/combinat/partition.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index f607cea6957..6e3bd44e14b 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6840,8 +6840,8 @@ def __contains__(self, x): True """ try: - return mu in Partitions(sum(mu), **self._constraints) - except Exception: + return x in Partitions(sum(x), **self._constraints) + except TypeError: return False def _repr_(self): From d3f86e7aed211e03a8abe6067ec68e502ca7aac0 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 21 Dec 2024 17:00:11 +0100 Subject: [PATCH 064/175] fix another typo --- src/sage/combinat/partition.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 6e3bd44e14b..0d6df40cfc8 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -9088,7 +9088,7 @@ def __contains__(self, x): TESTS:: sage: from sage.combinat.partition import Partitions_length_and_parts_constrained - sage: P = Partitions_length_and_parts_constrained(10, 2, 5, 2, 4) + sage: P = Partitions_length_and_parts_constrained(10, 2, 4, 2, 5) sage: Partition([]) in P False From c06eba42f3e61e946826dc0e8747953b25a3a630 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 21 Dec 2024 17:04:36 +0100 Subject: [PATCH 065/175] yet another thinko --- src/sage/combinat/partition.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 0d6df40cfc8..ff8710d52b5 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -8526,7 +8526,7 @@ def __contains__(self, x): True sage: [4, 2, 1, 1] in P False - sage: [0,0,0,0] in P + sage: [0, 0, 0, 0] in P True """ return len(x) <= self._max_len and RegularPartitions.__contains__(self, x) @@ -8646,7 +8646,7 @@ def __contains__(self, x): True sage: [4, 2, 1] in P False - sage: [0,0,0,0,0] in P + sage: [0, 0, 0, 0, 0] in P True """ return len(x) == 0 or (x[0] <= self.k and RegularPartitions.__contains__(self, x)) @@ -9098,7 +9098,7 @@ def __contains__(self, x): sage: Partition([5, 3, 2]) in P True - sage: Partition([5, 3, 2, 0, 0]) in P + sage: [5, 3, 2, 0, 0] in P True """ if x not in _Partitions: From 2dcc3371b7561dce68f4737b47c1372928182e28 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sat, 21 Dec 2024 22:16:14 +0100 Subject: [PATCH 066/175] Define __iter__ method in SetSystemIterator This is required for iterator types and seems to be enforced in Python 3.13 https://docs.python.org/3/library/stdtypes.html#iterator-types --- src/sage/matroids/set_system.pyx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/matroids/set_system.pyx b/src/sage/matroids/set_system.pyx index d9a2f631fbf..0bf9cb2b7fa 100644 --- a/src/sage/matroids/set_system.pyx +++ b/src/sage/matroids/set_system.pyx @@ -772,6 +772,9 @@ cdef class SetSystemIterator: self._pointer = -1 self._len = len(H) + def __iter__(self): + return self + def __next__(self): """ Return the next subset of a SetSystem. From e1e594882c7018fe66909651724df5ef9c415fd3 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 22 Dec 2024 00:43:47 +0100 Subject: [PATCH 067/175] fix and test __contains__ --- src/sage/combinat/partition.py | 131 ++++++++++++++++++++++----------- 1 file changed, 89 insertions(+), 42 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index ff8710d52b5..e2cab4d68b6 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6461,7 +6461,7 @@ def _element_constructor_(self, lst): try: lst = list(map(ZZ, lst)) except TypeError: - raise ValueError('all parts of %s should be nonnegative integers' % repr(lst)) + raise ValueError(f'all parts of {lst} should be nonnegative integers') if lst in self: # trailing zeros are removed in Partition.__init__ @@ -6822,6 +6822,8 @@ def __contains__(self, x): sage: from sage.combinat.partition import Partitions_all_constrained sage: P = Partitions_all_constrained(max_part=3, max_length=2) + sage: 1 in P + False sage: Partition([2,1]) in P True sage: [2,1] in P @@ -6873,11 +6875,14 @@ def __iter__(self): class Partitions_all_bounded(Partitions): + """ + Partitions whose parts do not exceed a given bound. + """ def __init__(self, k): """ TESTS:: - sage: TestSuite( sage.combinat.partition.Partitions_all_bounded(3) ).run() # long time + sage: TestSuite(sage.combinat.partition.Partitions_all_bounded(3)).run() # long time """ self.k = k Partitions.__init__(self, is_infinite=True) @@ -6887,6 +6892,10 @@ def __contains__(self, x): TESTS:: sage: P = Partitions(max_part=3) + sage: 1 in P + False + sage: 0 in P + False sage: Partition([2,1]) in P True sage: [2,1] in P @@ -6902,7 +6911,7 @@ def __contains__(self, x): sage: [] in P True """ - return not x or (x[0] <= self.k and x in _Partitions) + return x in _Partitions and (not x or x[0] <= self.k) def _repr_(self): """ @@ -6959,14 +6968,16 @@ def __contains__(self, x): TESTS:: - sage: p = Partitions(5) - sage: [2,1] in p + sage: P = Partitions(5) + sage: 5 in P + False + sage: [2,1] in P False - sage: [2,2,1] in p + sage: [2,2,1] in P True - sage: [3,2] in p + sage: [3,2] in P True - sage: [2,3] in p + sage: [2,3] in P False """ return x in _Partitions and sum(x) == self.n @@ -7361,25 +7372,35 @@ def __contains__(self, x): TESTS:: - sage: p = Partitions(5, length=2) - sage: [2,1] in p + sage: P = Partitions(5, length=2) + sage: [2,1] in P False - sage: [2,2,1] in p + sage: [2,2,1] in P False - sage: [3,2] in p + sage: [3,2] in P True - sage: [2,3] in p + sage: [2,3] in P False - sage: [4,1] in p + sage: [4,1] in P True - sage: [1,1,1,1,1] in p + sage: [1,1,1,1,1] in P False - sage: [5] in p + sage: [5] in P False - sage: [4,1,0] in p + sage: [4,1,0] in P + True + sage: [] in Partitions(0, length=0) True + sage: [0] in Partitions(0, length=0) + True + sage: [] in Partitions(0, length=1) + False """ - return x in _Partitions and sum(x) == self.n and len(x) == self.k + if x not in _Partitions or sum(x) != self.n: + return False + if not x or not x[0]: + return not self.k + return len(x) == next(i for i, e in enumerate(reversed(x), self.k) if e) def _repr_(self): """ @@ -7596,16 +7617,21 @@ def __contains__(self, x): TESTS:: sage: from sage.combinat.partition import Partitions_parts_in - sage: p = Partitions_parts_in(5, [1,2]) - sage: [2,1,1,1] in p + sage: P = Partitions_parts_in(5, [1,2]) + sage: 5 in P + False + sage: [2,1,1,1] in P True - sage: [4,1] in p + sage: [4,1] in P False - sage: [2,1,1,1,0] in p + sage: [2,1,1,1,0] in P True """ - return (x in _Partitions and sum(x) == self.n and - all(p in self.parts for p in x)) + try: + mu = Partition(x) + except (ValueError, TypeError): + return False + return sum(mu) == self.n and all(p in self.parts for p in mu) def _repr_(self): """ @@ -7960,7 +7986,11 @@ def __contains__(self, x): sage: [2,1,0] in Partitions_starting(3, [2, 1]) True """ - return x in Partitions_n(self.n) and x <= self._starting + try: + mu = Partition(x) + except (ValueError, TypeError): + return False + return sum(mu) == self.n and mu <= self._starting def first(self): """ @@ -8075,10 +8105,14 @@ def __contains__(self, x): TESTS:: sage: from sage.combinat.partition import Partitions_ending - sage: [4,0] in Partitions_ending(3, [2, 2]) + sage: [4,0] in Partitions_ending(4, [2, 2]) True """ - return x in Partitions_n(self.n) and x >= self._ending + try: + mu = Partition(x) + except (ValueError, TypeError): + return False + return sum(mu) == self.n and mu >= self._ending def first(self): """ @@ -8178,11 +8212,15 @@ def __contains__(self, x): False sage: [3,1] in PartitionsInBox(2, 3) True + sage: [0] in PartitionsInBox(2,2) + True sage: [3,1,0] in PartitionsInBox(2, 3) True """ - return x in _Partitions and len(x) <= self.h \ - and (len(x) == 0 or x[0] <= self.w) + return (x in _Partitions + and (not x or not x[0] + or (x[0] <= self.w + and len(x) <= next(i for i, e in enumerate(reversed(x), self.h) if e)))) def list(self): """ @@ -8520,6 +8558,8 @@ def __contains__(self, x): sage: from sage.combinat.partition import RegularPartitions_truncated sage: P = RegularPartitions_truncated(4, 3) + sage: 3 in P + False sage: [3, 3, 3] in P True sage: [] in P @@ -8529,7 +8569,9 @@ def __contains__(self, x): sage: [0, 0, 0, 0] in P True """ - return len(x) <= self._max_len and RegularPartitions.__contains__(self, x) + return (RegularPartitions.__contains__(self, x) + and (not x or not x[0] or + len(x) <= next(i for i, e in enumerate(reversed(x), self._max_len) if e))) def _repr_(self): """ @@ -8640,6 +8682,8 @@ def __contains__(self, x): sage: from sage.combinat.partition import RegularPartitions_bounded sage: P = RegularPartitions_bounded(4, 3) + sage: 0 in P + False sage: [3, 3, 3] in P True sage: [] in P @@ -8649,7 +8693,8 @@ def __contains__(self, x): sage: [0, 0, 0, 0, 0] in P True """ - return len(x) == 0 or (x[0] <= self.k and RegularPartitions.__contains__(self, x)) + return (RegularPartitions.__contains__(self, x) + and (not x or x[0] <= self.k)) def _repr_(self): """ @@ -9089,26 +9134,26 @@ def __contains__(self, x): sage: from sage.combinat.partition import Partitions_length_and_parts_constrained sage: P = Partitions_length_and_parts_constrained(10, 2, 4, 2, 5) + sage: 1 in P + False sage: Partition([]) in P False - sage: Partition([3]) in P False - sage: Partition([5, 3, 2]) in P True - sage: [5, 3, 2, 0, 0] in P True """ - if x not in _Partitions: + try: + mu = Partition(x) + except (ValueError, TypeError): return False - if not self._n: - return not x - return (sum(x) == self._n - and x[-1] >= self._min_part - and x[0] <= self._max_part - and self._min_length <= len(x) <= self._max_length) + return (sum(mu) == self._n + and (not mu + or (mu[-1] >= self._min_part + and mu[0] <= self._max_part + and self._min_length <= len(mu) <= self._max_length))) def __iter__(self): """ @@ -9557,8 +9602,10 @@ def __contains__(self, x): True sage: [3, 2, 1] in P False - sage: [5, 0, 0, 0, 0] in P + sage: [3, 2, 0, 0, 0] in P True + sage: [5] in P + False """ return RestrictedPartitions_generic.__contains__(self, x) and sum(x) == self.n From 40fcd027bd2620e162e58c5b74a9e8a2a7265d08 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 22 Dec 2024 09:57:13 +0100 Subject: [PATCH 068/175] revert to previous behaviour --- src/sage/combinat/partition.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index e2cab4d68b6..2c4d432917b 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6461,7 +6461,7 @@ def _element_constructor_(self, lst): try: lst = list(map(ZZ, lst)) except TypeError: - raise ValueError(f'all parts of {lst} should be nonnegative integers') + raise ValueError(f'all parts of {repr(lst)} should be nonnegative integers') if lst in self: # trailing zeros are removed in Partition.__init__ From 4c833319c9f3ed17e0dabe6a38f3718955ddf538 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 22 Dec 2024 16:23:14 +0700 Subject: [PATCH 069/175] Refactor produce_latex_macro --- src/sage/misc/latex_macros.py | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/sage/misc/latex_macros.py b/src/sage/misc/latex_macros.py index fc389b32a72..1cce2fa6f14 100644 --- a/src/sage/misc/latex_macros.py +++ b/src/sage/misc/latex_macros.py @@ -43,6 +43,8 @@ contain '\newcommand' lines for each of the entries in ``macros``. """ +import importlib + def produce_latex_macro(name, *sample_args): r""" @@ -69,7 +71,7 @@ def produce_latex_macro(name, *sample_args): sage: produce_latex_macro('GF', 37) '\\newcommand{\\GF}[1]{\\Bold{F}_{#1}}' - If the Sage object is not in the global name space, describe it + If the Sage object is not in the global namespace, describe it like so:: sage: produce_latex_macro('sage.rings.finite_rings.finite_field_constructor.FiniteField', 3) @@ -84,22 +86,16 @@ def produce_latex_macro(name, *sample_args): else: module, real_name = names_split newcommand = '\\newcommand{\\' + real_name + '}' - count = 0 - args = "(" - for x in sample_args: - count += 1 - args += str(x) + ',' - args += ')' - exec('from ' + module + ' import ' + real_name) - if count: - defn = '[' + str(count) + ']{' - defn += eval('str(LatexCall()(' + real_name + args + '))') + '}' + sage_object = getattr(importlib.import_module(module), real_name) + if sample_args: + defn = '[' + str(len(sample_args)) + ']{' + defn += str(LatexCall()(sage_object(*sample_args))) + '}' else: - defn = '{' + eval('str(LatexCall()(' + real_name + '))') + '}' - count = 0 - for x in sample_args: - count += 1 - defn = defn.replace(str(x), "#" + str(count)) + defn = '{' + str(LatexCall()(sage_object)) + '}' + for i, x in enumerate(sample_args): + s = str(x) + assert s in defn + defn = defn.replace(s, "#" + str(i+1)) return newcommand + defn From 9ec9a9a7695b783de05b12966f0121ddcffe4dbe Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 22 Dec 2024 10:54:23 +0100 Subject: [PATCH 070/175] Define __iter__ in LinearSubclassesIter too --- src/sage/matroids/extension.pyx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/matroids/extension.pyx b/src/sage/matroids/extension.pyx index 778e6d6ef70..83b792e8d2b 100644 --- a/src/sage/matroids/extension.pyx +++ b/src/sage/matroids/extension.pyx @@ -211,6 +211,9 @@ cdef class LinearSubclassesIter: self._nodes = [first_cut] + def __iter__(self): + return self + def __next__(self): """ Return the next linear subclass. From dfd1644c450ba8dd5d451bd678a761de81397d1c Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 22 Dec 2024 12:24:07 +0100 Subject: [PATCH 071/175] make __contains__ self-contained --- src/sage/combinat/partition.py | 55 +++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 2c4d432917b..927f1da8ec5 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -6459,7 +6459,7 @@ def _element_constructor_(self, lst): if lst.parent() is self: return lst try: - lst = list(map(ZZ, lst)) + lst = [ZZ(e) for e in lst] except TypeError: raise ValueError(f'all parts of {repr(lst)} should be nonnegative integers') @@ -7627,11 +7627,13 @@ def __contains__(self, x): sage: [2,1,1,1,0] in P True """ - try: - mu = Partition(x) - except (ValueError, TypeError): + if x not in _Partitions or sum(x) != self.n: return False - return sum(mu) == self.n and all(p in self.parts for p in mu) + if x and not x[-1]: + x = x[:-1] + while x and not x[-1]: + x.pop() + return all(p in self.parts for p in x) def _repr_(self): """ @@ -7986,11 +7988,13 @@ def __contains__(self, x): sage: [2,1,0] in Partitions_starting(3, [2, 1]) True """ - try: - mu = Partition(x) - except (ValueError, TypeError): + if x not in _Partitions or sum(x) != self.n: return False - return sum(mu) == self.n and mu <= self._starting + if x and not x[-1]: + x = x[:-1] + while x and not x[-1]: + x.pop() + return x <= self._starting def first(self): """ @@ -8108,11 +8112,13 @@ def __contains__(self, x): sage: [4,0] in Partitions_ending(4, [2, 2]) True """ - try: - mu = Partition(x) - except (ValueError, TypeError): + if x not in _Partitions or sum(x) != self.n: return False - return sum(mu) == self.n and mu >= self._ending + if x and not x[-1]: + x = x[:-1] + while x and not x[-1]: + x.pop() + return x >= self._ending def first(self): """ @@ -8412,7 +8418,7 @@ def __contains__(self, x): sage: Partition([10,1]) in P True """ - if not Partitions.__contains__(self, x): + if x not in _Partitions: return False if isinstance(x, Partition): return max(x.to_exp() + [0]) < self._ell @@ -9145,15 +9151,16 @@ def __contains__(self, x): sage: [5, 3, 2, 0, 0] in P True """ - try: - mu = Partition(x) - except (ValueError, TypeError): + if x not in _Partitions or sum(x) != self._n: return False - return (sum(mu) == self._n - and (not mu - or (mu[-1] >= self._min_part - and mu[0] <= self._max_part - and self._min_length <= len(mu) <= self._max_length))) + if x and not x[-1]: + x = x[:-1] + while x and not x[-1]: + x.pop() + return (not x + or (x[-1] >= self._min_part + and x[0] <= self._max_part + and self._min_length <= len(x) <= self._max_length)) def __iter__(self): """ @@ -9463,9 +9470,9 @@ def __contains__(self, x): sage: Partition([3,3] + [1]*10) in P True """ - if not Partitions.__contains__(self, x): + if x not in _Partitions: return False - if x == []: + if not x: return True return (all(x[i] - x[i+1] < self._ell for i in range(len(x)-1)) and x[-1] < self._ell) From 481db2a120b35d0b42806467d7e5ce5c7bc3b20e Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 22 Dec 2024 11:17:38 +0100 Subject: [PATCH 072/175] Fix find_replacements with Python 3.13 After PEP 667 implementation [1] locals() changes within an exec call are not propagated outside the call [1] https://github.com/python/cpython/commit/b034f14a4b6e9197d3926046721b8b4b4b4f5b3d --- src/sage/misc/replace_dot_all.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/replace_dot_all.py b/src/sage/misc/replace_dot_all.py index ea51a9b3159..fea2faaa716 100644 --- a/src/sage/misc/replace_dot_all.py +++ b/src/sage/misc/replace_dot_all.py @@ -63,6 +63,7 @@ from sage.misc.dev_tools import import_statements import os import re +import sys import argparse # We import this using __import__ so that "tox -e relint" does not complain about this source file. @@ -194,14 +195,21 @@ def find_replacements(location, package_regex=None, verbose=False): to_exec = to_exec.replace("'", '').replace('"', '') if (to_exec[-1] == ','): to_exec = to_exec[:-1] - exec(to_exec) + if sys.version_info.minor < 13: + exec(to_exec) + else: + loc = locals() + exec(to_exec, locals=loc) except ModuleNotFoundError as err: print(f'ModuleNotFoundError: {err} found when trying to execute {to_exec}') except ImportError as err: print(f'ImportError: {err} found when trying to execute {to_exec}') try: # try to evaluate the list of module names to get a list of the modules themselves which we can call import_statements on - modules = eval(to_eval) + if sys.version_info.minor < 13: + modules = eval(to_eval) + else: + modules = eval(to_eval, locals=loc) except NameError as err: print(f'NameError: {err} found when trying to evaluate {to_eval} at {location}:{row_index + 1}') except SyntaxError as err: From b8cd5a6f69eefe5915f9acfe0fc8e7826806d427 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 22 Dec 2024 11:46:47 +0100 Subject: [PATCH 073/175] Simplify --- src/sage/misc/replace_dot_all.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/sage/misc/replace_dot_all.py b/src/sage/misc/replace_dot_all.py index fea2faaa716..a196810bd44 100644 --- a/src/sage/misc/replace_dot_all.py +++ b/src/sage/misc/replace_dot_all.py @@ -63,7 +63,6 @@ from sage.misc.dev_tools import import_statements import os import re -import sys import argparse # We import this using __import__ so that "tox -e relint" does not complain about this source file. @@ -195,21 +194,15 @@ def find_replacements(location, package_regex=None, verbose=False): to_exec = to_exec.replace("'", '').replace('"', '') if (to_exec[-1] == ','): to_exec = to_exec[:-1] - if sys.version_info.minor < 13: - exec(to_exec) - else: - loc = locals() - exec(to_exec, locals=loc) + glob = globals() + exec(to_exec, glob) except ModuleNotFoundError as err: print(f'ModuleNotFoundError: {err} found when trying to execute {to_exec}') except ImportError as err: print(f'ImportError: {err} found when trying to execute {to_exec}') try: # try to evaluate the list of module names to get a list of the modules themselves which we can call import_statements on - if sys.version_info.minor < 13: - modules = eval(to_eval) - else: - modules = eval(to_eval, locals=loc) + modules = eval(to_eval, glob) except NameError as err: print(f'NameError: {err} found when trying to evaluate {to_eval} at {location}:{row_index + 1}') except SyntaxError as err: From cee808aa724e9b1e57436afb31739ea7c8369e15 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 22 Dec 2024 20:09:06 +0100 Subject: [PATCH 074/175] Use temporary dict as globals --- src/sage/misc/replace_dot_all.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/replace_dot_all.py b/src/sage/misc/replace_dot_all.py index a196810bd44..a43d6c0a929 100644 --- a/src/sage/misc/replace_dot_all.py +++ b/src/sage/misc/replace_dot_all.py @@ -194,7 +194,7 @@ def find_replacements(location, package_regex=None, verbose=False): to_exec = to_exec.replace("'", '').replace('"', '') if (to_exec[-1] == ','): to_exec = to_exec[:-1] - glob = globals() + glob = dict() exec(to_exec, glob) except ModuleNotFoundError as err: print(f'ModuleNotFoundError: {err} found when trying to execute {to_exec}') From 2234210e3497a7a0631ba60267bb42f3f86fc748 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Mon, 16 Dec 2024 22:00:46 +0100 Subject: [PATCH 075/175] Fix doctesting with Python 3.13 Adapt to upstream changes in doctest [1]: - _name2ft was renamed to _stats - it now records the number of skipped tests [1] https://github.com/python/cpython/commit/4f9b706c6f5d4422a398146bfd011daedaef1851 --- src/sage/doctest/forker.py | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index bf6d49906de..697bd09c615 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -553,6 +553,8 @@ def __init__(self, *args, **kwds): self.total_walltime_skips = 0 self.total_performed_tests = 0 self.total_walltime = 0 + if not hasattr(self, "_stats"): + self._stats = self._name2ft def _run(self, test, compileflags, out): """ @@ -830,7 +832,10 @@ def compiler(example): self.optionflags = original_optionflags # Record and return the number of failures and tries. - self._DocTestRunner__record_outcome(test, failures, tries) + try: + self._DocTestRunner__record_outcome(test, failures, tries, walltime_skips) + except TypeError: + self._DocTestRunner__record_outcome(test, failures, tries) self.total_walltime_skips += walltime_skips self.total_performed_tests += tries return TestResults(failures, tries) @@ -931,7 +936,7 @@ def summarize(self, verbose=None): sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: import doctest, sys, os sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) - sage: DTR._name2ft['sage.doctest.forker'] = (1,120) + sage: DTR._stats['sage.doctest.forker'] = (1,120) sage: results = DTR.summarize() ********************************************************************** 1 item had failures: @@ -946,15 +951,15 @@ def summarize(self, verbose=None): passed = [] failed = [] totalt = totalf = 0 - for x in self._name2ft.items(): - name, (f, t) = x - assert f <= t - totalt += t - totalf += f - if not t: + for x in self._stats.items(): + name, f = x + assert f[0] <= f[1] + totalt += f[1] + totalf += f[0] + if not f[1]: notests.append(name) - elif not f: - passed.append((name, t)) + elif not f[0]: + passed.append((name, f[1])) else: failed.append(x) if verbose: @@ -972,10 +977,10 @@ def summarize(self, verbose=None): print(self.DIVIDER, file=m) print(count_noun(len(failed), "item"), "had failures:", file=m) failed.sort() - for thing, (f, t) in failed: - print(" %3d of %3d in %s" % (f, t, thing), file=m) + for thing, f in failed: + print(" %3d of %3d in %s" % (f[0], f[1], thing), file=m) if verbose: - print(count_noun(totalt, "test") + " in " + count_noun(len(self._name2ft), "item") + ".", file=m) + print(count_noun(totalt, "test") + " in " + count_noun(len(self._stats), "item") + ".", file=m) print("%s passed and %s failed." % (totalt - totalf, totalf), file=m) if totalf: print("***Test Failed***", file=m) From acfe0c2de6e0a9bd12843f36ebb63b15366cf230 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Fri, 20 Dec 2024 22:11:20 +0100 Subject: [PATCH 076/175] Use sys.version_info --- src/sage/doctest/forker.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index 697bd09c615..a52485d3d91 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -553,7 +553,7 @@ def __init__(self, *args, **kwds): self.total_walltime_skips = 0 self.total_performed_tests = 0 self.total_walltime = 0 - if not hasattr(self, "_stats"): + if sys.version_info.minor < 13: self._stats = self._name2ft def _run(self, test, compileflags, out): @@ -832,10 +832,10 @@ def compiler(example): self.optionflags = original_optionflags # Record and return the number of failures and tries. - try: - self._DocTestRunner__record_outcome(test, failures, tries, walltime_skips) - except TypeError: + if sys.version_info.minor < 13: self._DocTestRunner__record_outcome(test, failures, tries) + else: + self._DocTestRunner__record_outcome(test, failures, tries, walltime_skips) self.total_walltime_skips += walltime_skips self.total_performed_tests += tries return TestResults(failures, tries) @@ -952,14 +952,14 @@ def summarize(self, verbose=None): failed = [] totalt = totalf = 0 for x in self._stats.items(): - name, f = x - assert f[0] <= f[1] - totalt += f[1] - totalf += f[0] - if not f[1]: + name, (f, t, *_) = x + assert f <= t + totalt += t + totalf += f + if not t: notests.append(name) - elif not f[0]: - passed.append((name, f[1])) + elif not f: + passed.append((name, t)) else: failed.append(x) if verbose: @@ -977,8 +977,8 @@ def summarize(self, verbose=None): print(self.DIVIDER, file=m) print(count_noun(len(failed), "item"), "had failures:", file=m) failed.sort() - for thing, f in failed: - print(" %3d of %3d in %s" % (f[0], f[1], thing), file=m) + for thing, (f, t, *_) in failed: + print(" %3d of %3d in %s" % (f, t, thing), file=m) if verbose: print(count_noun(totalt, "test") + " in " + count_noun(len(self._stats), "item") + ".", file=m) print("%s passed and %s failed." % (totalt - totalf, totalf), file=m) From 15b14ca8eb51acb4bdbd7c6faeb8abab89e88bc7 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 22 Dec 2024 20:12:49 +0100 Subject: [PATCH 077/175] Use full version_info instead of just version_info_minor --- src/sage/doctest/forker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index a52485d3d91..6c36ab47baf 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -553,7 +553,7 @@ def __init__(self, *args, **kwds): self.total_walltime_skips = 0 self.total_performed_tests = 0 self.total_walltime = 0 - if sys.version_info.minor < 13: + if sys.version_info < (3,13): self._stats = self._name2ft def _run(self, test, compileflags, out): @@ -832,7 +832,7 @@ def compiler(example): self.optionflags = original_optionflags # Record and return the number of failures and tries. - if sys.version_info.minor < 13: + if sys.version_info < (3,13): self._DocTestRunner__record_outcome(test, failures, tries) else: self._DocTestRunner__record_outcome(test, failures, tries, walltime_skips) From 3bb1db4411b188490998722ac8e90cbb20f87c10 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 22 Dec 2024 12:33:20 +0100 Subject: [PATCH 078/175] Declare Python 3.13 as supported in sagelib --- src/setup.cfg.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/setup.cfg.m4 b/src/setup.cfg.m4 index 969793209c8..3a4ec930b8f 100644 --- a/src/setup.cfg.m4 +++ b/src/setup.cfg.m4 @@ -9,7 +9,7 @@ license_files = LICENSE.txt include(`setup_cfg_metadata.m4')dnl' [options] -python_requires = >=3.9, <3.13 +python_requires = >=3.9, <3.14 install_requires = SPKG_INSTALL_REQUIRES_six dnl From build/pkgs/sagelib/dependencies From 335b6dd392bde1ef87034cd7c08466859efb144a Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Mon, 23 Dec 2024 09:10:30 +0100 Subject: [PATCH 079/175] Declare 3.13 as supported in pyproject.toml --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index da06db03649..ca2d483197a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,11 +74,12 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Scientific/Engineering :: Mathematics", ] urls = {Homepage = "https://www.sagemath.org"} -requires-python = ">=3.9, <3.13" +requires-python = ">=3.9, <3.14" [project.optional-dependencies] R = [ From 662e795c5b9fa3036f5a8d5fd034de4406318202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Tue, 24 Dec 2024 18:27:38 -0300 Subject: [PATCH 080/175] Fix `spyx_tmp()` cleanup. For some reason, a new behaviour of python 3.13 [0] causes the `TemporaryDirectory()` in `sage.misc.temporary_file.spyx_tmp()` to be deleted on child exit, which causes trouble with parallel doctesting [1]. We rewrite `spyx_tmp()` using `tmp_dir()`, which doesn't have this problem, see [2]. [0] https://github.com/python/cpython/pull/114279 [1] https://github.com/sagemath/sage/pull/39188#issuecomment-2559925083 [2] https://github.com/sagemath/sage/pull/39188#issuecomment-2561459269 --- src/sage/misc/temporary_file.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/misc/temporary_file.py b/src/sage/misc/temporary_file.py index 998260be8eb..de872802805 100644 --- a/src/sage/misc/temporary_file.py +++ b/src/sage/misc/temporary_file.py @@ -533,14 +533,15 @@ def spyx_tmp() -> str: We cache the result of this function "by hand" so that the same temporary directory will always be returned. A function is used to delay creating a directory until (if) it is needed. The temporary - directory is removed when sage terminates by way of an atexit - hook. + directory is automatically removed when sage terminates. """ global _spyx_tmp if _spyx_tmp: return _spyx_tmp - d = tempfile.TemporaryDirectory() - _spyx_tmp = os.path.join(d.name, 'spyx') - atexit.register(lambda: d.cleanup()) + # We don't use `tempfile.TemporaryDirectory()` here because it + # will be cleaned up on child exit (e.g. for parallel testing) + # For some reason this doesn't affect the `TemporaryDirectory` + # stored in the global `TMP_DIR_FILENAME_BASE`. + _spyx_tmp = tmp_dir(name='spyx_') return _spyx_tmp From 9669a8666126cbcaad56ddc5196092ce7a9d54d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Tue, 24 Dec 2024 18:35:12 -0300 Subject: [PATCH 081/175] Use `sage_` prefix for the main temporary directory. --- src/sage/misc/temporary_file.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/misc/temporary_file.py b/src/sage/misc/temporary_file.py index de872802805..820d5cf2e95 100644 --- a/src/sage/misc/temporary_file.py +++ b/src/sage/misc/temporary_file.py @@ -32,7 +32,9 @@ # as the parent for all temporary files & directories created by them. # This lets us clean up after those two functions when sage exits normally # using an atexit hook -TMP_DIR_FILENAME_BASE = tempfile.TemporaryDirectory() +# Note that `TemporaryDirectory()` will cleanup on program exit; +# we keep the atexit hook to be redundant, in case that fails. +TMP_DIR_FILENAME_BASE = tempfile.TemporaryDirectory(prefix='sage_') atexit.register(lambda: TMP_DIR_FILENAME_BASE.cleanup()) From 2e6c9680e00b3cdbe62ebee84513cbc9f850803c Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 29 Dec 2024 09:00:58 +0530 Subject: [PATCH 082/175] Added _top_degree() method --- src/sage/categories/kahler_algebras.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 19d0a798ab2..4a71f943f42 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -10,6 +10,7 @@ from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.misc.abstract_method import abstract_method from sage.quadratic_forms.quadratic_form import QuadraticForm +from sage.misc.cachefunc import cached_method # **************************************************************************** @@ -47,6 +48,26 @@ class ParentMethods: def poincare_pairing(): pass + @cached_method + def _top_degree(self): + r""" + Return the top degree of the Kähler algebra. + + EXAMPLES:: + + sage: ch = matroids.Uniform(4,6).chow_ring(QQ, False) + sage: ch._top_degree() + 3 + sage: ch = matroids.Wheel(3).chow_ring(QQ, 'atom-free') + sage: ch._top_degree() + 2 + """ + return max([b.degree() for b in self.basis()]) + + # check all methods with matroids with loops/parallel elements + # add properties and Kahler algebra def. Be as detailed as possible + # issue with category + @abstract_method def lefschetz_element(): pass @@ -102,7 +123,7 @@ def hodge_riemann_relations(self, k, r): ... ValueError: k must be less than r < 2 """ - if k >= (r/2): + if k > (r/2): raise ValueError("k must be less than r < 2") basis_k = [] lefschetz_el = self.lefschetz_element() From c24db6bb15cd620dd1ff004a98bf903307d372ce Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 29 Dec 2024 09:03:04 +0530 Subject: [PATCH 083/175] Added _top_degree() method in other methods --- src/sage/categories/kahler_algebras.py | 3 ++- src/sage/matroids/chow_ring.py | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 4a71f943f42..83bd3b3e7b3 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -72,7 +72,7 @@ def _top_degree(self): def lefschetz_element(): pass - def hodge_riemann_relations(self, k, r): + def hodge_riemann_relations(self, k): r""" Return the quadratic form for the corresponding k (< r/2) for the Kähler algebra. @@ -123,6 +123,7 @@ def hodge_riemann_relations(self, k, r): ... ValueError: k must be less than r < 2 """ + r = self._top_degree() if k > (r/2): raise ValueError("k must be less than r < 2") basis_k = [] diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 2042e53dbba..2b49e7b5e9f 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -320,7 +320,11 @@ def lefschetz_element(self): sage: U46 = matroids.Uniform(4,6) sage: C = U46.chow_ring(QQ, False) sage: w = C.lefschetz_element(); w - -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A05 - 2*A12 - 2*A13 - 2*A14 - 2*A15 - 2*A23 - 2*A24 - 2*A25 - 2*A34 - 2*A35 - 2*A45 - 6*A012 - 6*A013 - 6*A014 - 6*A015 - 6*A023 - 6*A024 - 6*A025 - 6*A034 - 6*A035 - 6*A045 - 6*A123 - 6*A124 - 6*A125 - 6*A134 - 6*A135 - 6*A145 - 6*A234 - 6*A235 - 6*A245 - 6*A345 - 30*A012345 + -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A05 - 2*A12 - 2*A13 - 2*A14 + - 2*A15 - 2*A23 - 2*A24 - 2*A25 - 2*A34 - 2*A35 - 2*A45 - 6*A012 + - 6*A013 - 6*A014 - 6*A015 - 6*A023 - 6*A024 - 6*A025 - 6*A034 + - 6*A035 - 6*A045 - 6*A123 - 6*A124 - 6*A125 - 6*A134 - 6*A135 + - 6*A145 - 6*A234 - 6*A235 - 6*A245 - 6*A345 - 30*A012345 sage: basis_deg = {} sage: for b in C.basis(): ....: deg = b.homogeneous_degree() @@ -339,7 +343,7 @@ def lefschetz_element(self): w = sum(len(F) * (len(self.matroid().groundset()) - len(F)) * gen for F, gen in self.flats_generator().items()) return w - def poincare_pairing(self, el1, el2, r): + def poincare_pairing(self, el1, el2): r""" Return the Poincaré pairing of any two elements of the Chow ring. @@ -355,6 +359,7 @@ def poincare_pairing(self, el1, el2, r): sage: ch.poincare_pairing(v, u, ch.matroid().rank()) 3 """ + r = self._top_degree() hom_components1 = el1.lift().homogeneous_components() hom_components2 = el2.lift().homogeneous_components() new_el = self.base_ring().zero() From dd5ec3be9d7d413893ebbb9be252a76f2f0a2555 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 29 Dec 2024 15:09:04 +0100 Subject: [PATCH 084/175] some care in src/sage/graphs/comparability.pyx --- src/sage/graphs/comparability.pyx | 304 ++++++++++++++++-------------- 1 file changed, 166 insertions(+), 138 deletions(-) diff --git a/src/sage/graphs/comparability.pyx b/src/sage/graphs/comparability.pyx index 05d5d3b5185..08714ade199 100644 --- a/src/sage/graphs/comparability.pyx +++ b/src/sage/graphs/comparability.pyx @@ -15,12 +15,12 @@ The following methods are implemented in this module :widths: 30, 70 :delim: | - :meth:`~is_comparability_MILP` | Test whether the graph is a comparability graph (MILP) - :meth:`~greedy_is_comparability` | Test whether the graph is a comparability graph (greedy algorithm) - :meth:`~greedy_is_comparability_with_certificate` | Test whether the graph is a comparability graph and returns certificates (greedy algorithm) - :meth:`~is_comparability` | Test whether the graph is a comparability graph - :meth:`~is_permutation` | Test whether the graph is a permutation graph. - :meth:`~is_transitive` | Test whether the digraph is transitive. + :meth:`~is_comparability_MILP` | Check whether the graph is a comparability graph (MILP) + :meth:`~greedy_is_comparability` | Check whether the graph is a comparability graph (greedy algorithm) + :meth:`~greedy_is_comparability_with_certificate` | Check whether the graph is a comparability graph and returns certificates (greedy algorithm) + :meth:`~is_comparability` | Check whether the graph is a comparability graph + :meth:`~is_permutation` | Check whether the graph is a permutation graph. + :meth:`~is_transitive` | Check whether the digraph is transitive. Author: @@ -210,7 +210,7 @@ from copy import copy def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): r""" - Test whether the graph is a comparability graph (greedy algorithm). + Check whether the graph is a comparability graph (greedy algorithm). This method only returns no-certificates. @@ -219,6 +219,8 @@ def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): INPUT: + - ``g`` -- a graph + - ``no_certificate`` -- whether to return a *no*-certificate when the graph is not a comparability graph. This certificate is an odd cycle of edges, each of which implies the next. It is set to ``False`` by default. @@ -239,23 +241,33 @@ def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): The Petersen Graph is not transitively orientable:: - sage: from sage.graphs.comparability import greedy_is_comparability as is_comparability - sage: g = graphs.PetersenGraph() - sage: is_comparability(g) - False - sage: is_comparability(g, no_certificate=True) - (False, [2, 1, 0, 4, 3, 2]) + sage: from sage.graphs.comparability import greedy_is_comparability as is_comparability + sage: g = graphs.PetersenGraph() + sage: is_comparability(g) + False + sage: is_comparability(g, no_certificate=True) + (False, [2, 1, 0, 4, 3, 2]) But the Bull graph is:: - sage: g = graphs.BullGraph() - sage: is_comparability(g) - True + sage: g = graphs.BullGraph() + sage: is_comparability(g) + True + + TESTS: + + Check that the method is working even when vertices are of incomparable + types:: + + sage: from sage.graphs.comparability import greedy_is_comparability + sage: G = Graph([('a', 1), (1, 2), (2, 3)]) + sage: greedy_is_comparability(G, equivalence_class=True) + (True, [(2, 3), (2, 1), ('a', 1)]) """ cdef int i, j # Each vertex can partition its neighbors into equivalence classes - equivalence_classes = {} + cdef dict equivalence_classes = {} for v in g: equivalence_classes[v] = g.subgraph(vertices=g.neighbors(v)).complement().connected_components(sort=False) @@ -288,7 +300,7 @@ def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): if equivalence_class: # Returning the largest equivalence class - cc = sorted(h.connected_components(sort=False), key=len)[-1] + cc = max(h.connected_components(sort=False), key=len) edges = [] for v, sid in cc: @@ -296,29 +308,27 @@ def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): # For each edge we pick the good orientations if certif[v, sid] == 1: - for vv in s: - edges.append((v, vv)) + edges.extend((v, vv) for vv in s) else: - for vv in s: - edges.append((vv, v)) + edges.extend((vv, v) for vv in s) # We return the value but take care of removing edges that were # added twice. - return True, sorted(set(edges)) + return True, list(set(edges)) return True if no_certificate: - certif.append(certif[0]) cycle = [v for v, _ in certif] + cycle.append(cycle[0]) return False, cycle return False def greedy_is_comparability_with_certificate(g, certificate=False): r""" - Test whether the graph is a comparability graph and returns - certificates(greedy algorithm). + Check whether the graph is a comparability graph and returns + certificates (greedy algorithm). This method can return certificates of both *yes* and *no* answers. @@ -327,6 +337,8 @@ def greedy_is_comparability_with_certificate(g, certificate=False): INPUT: + - ``g`` -- a graph + - ``certificate`` -- boolean; whether to return a certificate. *Yes*-answers the certificate is a transitive orientation of `G`, and a *no* certificates is an odd cycle of sequentially forcing @@ -336,24 +348,34 @@ def greedy_is_comparability_with_certificate(g, certificate=False): The 5-cycle or the Petersen Graph are not transitively orientable:: - sage: from sage.graphs.comparability import greedy_is_comparability_with_certificate as is_comparability - sage: is_comparability(graphs.CycleGraph(5), certificate=True) - (False, [2, 1, 0, 4, 3, 2]) - sage: g = graphs.PetersenGraph() - sage: is_comparability(g) - False - sage: is_comparability(g, certificate=True) - (False, [2, 1, 0, 4, 3, 2]) + sage: from sage.graphs.comparability import greedy_is_comparability_with_certificate as is_comparability + sage: is_comparability(graphs.CycleGraph(5), certificate=True) + (False, [2, 1, 0, 4, 3, 2]) + sage: g = graphs.PetersenGraph() + sage: is_comparability(g) + False + sage: is_comparability(g, certificate=True) + (False, [2, 1, 0, 4, 3, 2]) But the Bull graph is:: - sage: g = graphs.BullGraph() - sage: is_comparability(g) - True - sage: is_comparability(g, certificate = True) - (True, Digraph on 5 vertices) - sage: is_comparability(g, certificate = True)[1].is_transitive() - True + sage: g = graphs.BullGraph() + sage: is_comparability(g) + True + sage: is_comparability(g, certificate = True) + (True, Digraph on 5 vertices) + sage: is_comparability(g, certificate = True)[1].is_transitive() + True + + TESTS: + + Check that the method is working even when vertices are of incomparable + types:: + + sage: from sage.graphs.comparability import greedy_is_comparability_with_certificate + sage: G = Graph([('a', 1), (1, 2), (2, 3)]) + sage: greedy_is_comparability_with_certificate(G, certificate=True) + (True, Digraph on 4 vertices) """ isit, certif = greedy_is_comparability(g, no_certificate=True, equivalence_class=True) if not isit: @@ -393,73 +415,70 @@ def greedy_is_comparability_with_certificate(g, certificate=False): def is_comparability_MILP(g, certificate=False, solver=None, verbose=0): r""" - Test whether the graph is a comparability graph (MILP). + Check whether the graph is a comparability graph (MILP). INPUT: - - ``certificate`` -- boolean; whether to return a certificate for - yes instances. This method cannot return negative certificates. + - ``g`` -- a graph - - ``solver`` -- (default: ``None``) specify a Linear Program (LP) solver to - be used. If set to ``None``, the default one is used. For more information - on LP solvers and which default solver is used, see the method - :meth:`~sage.numerical.mip.MixedIntegerLinearProgram.solve` of the class - :class:`~sage.numerical.mip.MixedIntegerLinearProgram`. + - ``certificate`` -- boolean (default: ``False``); whether to return a + certificate for yes instances. This method cannot return negative + certificates. + + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear + Programming (MILP) solver to be used. If set to ``None``, the default one + is used. For more information on MILP solvers and which default solver is + used, see the method :meth:`solve + ` of the class + :class:`MixedIntegerLinearProgram + `. - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. - EXAMPLES: + EXAMPLES: The 5-cycle or the Petersen Graph are not transitively orientable:: - sage: from sage.graphs.comparability import is_comparability_MILP as is_comparability - sage: is_comparability(graphs.CycleGraph(5), certificate=True) # needs sage.numerical.mip - (False, None) - sage: g = graphs.PetersenGraph() - sage: is_comparability(g, certificate=True) # needs sage.numerical.mip - (False, None) + sage: from sage.graphs.comparability import is_comparability_MILP as is_comparability + sage: is_comparability(graphs.CycleGraph(5), certificate=True) # needs sage.numerical.mip + (False, None) + sage: g = graphs.PetersenGraph() + sage: is_comparability(g, certificate=True) # needs sage.numerical.mip + (False, None) But the Bull graph is:: - sage: g = graphs.BullGraph() - sage: is_comparability(g) # needs sage.numerical.mip - True - sage: is_comparability(g, certificate=True) # needs sage.numerical.mip - (True, Digraph on 5 vertices) - sage: is_comparability(g, certificate=True)[1].is_transitive() # needs sage.numerical.mip - True + sage: g = graphs.BullGraph() + sage: is_comparability(g) # needs sage.numerical.mip + True + sage: is_comparability(g, certificate=True) # needs sage.numerical.mip + (True, Digraph on 5 vertices) + sage: is_comparability(g, certificate=True)[1].is_transitive() # needs sage.numerical.mip + True """ from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException - cdef int i - p = MixedIntegerLinearProgram(solver=solver) o = p.new_variable(binary=True) for u, v in g.edge_iterator(labels=False): p.add_constraint(o[u, v] + o[v, u] == 1) + from itertools import combinations for u in g: - neighbors = g.neighbors(u) - - for i in range(len(neighbors)): - v = neighbors[i] - for j in range(i + 1, len(neighbors)): - vv = neighbors[j] - - # If there is an edge between v and vv, we must be - # sure it is in the good direction when v-u-vv is a - # directed path - if g.has_edge(v, vv): - p.add_constraint(o[u, v] + o[vv, u] - o[vv, v] <= 1) - p.add_constraint(o[u, vv] + o[v, u] - o[v, vv] <= 1) - - # If there is no edge, there are only two - # orientations possible (see the module's documentation - # about edges which imply each other) - else: - p.add_constraint(o[u, v] + o[vv, u] <= 1) - p.add_constraint(o[u, vv] + o[v, u] <= 1) + for v, vv in combinations(g.neighbors(u), 2): + + # If there is an edge between v and vv, we must be sure it is in the + # good direction when v-u-vv is a directed path + if g.has_edge(v, vv): + p.add_constraint(o[u, v] + o[vv, u] - o[vv, v] <= 1) + p.add_constraint(o[u, vv] + o[v, u] - o[v, vv] <= 1) + + # If there is no edge, there are only two orientations possible (see + # the module's documentation about edges which imply each other) + else: + p.add_constraint(o[u, v] + o[vv, u] <= 1) + p.add_constraint(o[u, vv] + o[v, u] <= 1) try: p.solve(log=verbose) @@ -494,11 +513,14 @@ def is_comparability_MILP(g, certificate=False, solver=None, verbose=0): def is_comparability(g, algorithm='greedy', certificate=False, check=True, solver=None, verbose=0): r""" - Test whether the graph is a comparability graph. + Check whether the graph is a comparability graph. INPUT: - - ``algorithm`` -- choose the implementation used to do the test + - ``g`` -- a graph + + - ``algorithm`` -- string (default: ``'greedy'``); choose the implementation + used to do the test - ``'greedy'`` -- a greedy algorithm (see the documentation of the :mod:`comparability module `) @@ -508,20 +530,22 @@ def is_comparability(g, algorithm='greedy', certificate=False, check=True, certificates ! When ``certificate = True``, negative certificates are always equal to ``None``. ``True`` certificates are valid, though. - - ``certificate`` -- boolean; whether to return a + - ``certificate`` -- boolean (default: ``False``); whether to return a certificate. *Yes*-answers the certificate is a transitive orientation of `G`, and a *no* certificates is an odd cycle of sequentially forcing edges. - - ``check`` -- boolean; whether to check that the + - ``check`` -- boolean (default: ``True``); whether to check that the yes-certificates are indeed transitive. As it is very quick compared to the rest of the operation, it is enabled by default. - - ``solver`` -- (default: ``None``) specify a Linear Program (LP) solver to - be used. If set to ``None``, the default one is used. For more information - on LP solvers and which default solver is used, see the method - :meth:`~sage.numerical.mip.MixedIntegerLinearProgram.solve` of the class - :class:`~sage.numerical.mip.MixedIntegerLinearProgram`. + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear + Programming (MILP) solver to be used. If set to ``None``, the default one + is used. For more information on MILP solvers and which default solver is + used, see the method :meth:`solve + ` of the class + :class:`MixedIntegerLinearProgram + `. - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. @@ -537,15 +561,14 @@ def is_comparability(g, algorithm='greedy', certificate=False, check=True, TESTS: - Let us ensure that no exception is raised when we go over all - small graphs:: + Let us ensure that no exception is raised when we go over all small graphs:: sage: from sage.graphs.comparability import is_comparability sage: [len([g for g in graphs(i) if is_comparability(g, certificate=True)[0]]) for i in range(7)] [1, 1, 2, 4, 11, 33, 144] """ g._scream_if_not_simple() - if g.size() == 0: + if not g.size(): if certificate: from sage.graphs.digraph import DiGraph return True, DiGraph(g) @@ -568,8 +591,8 @@ def is_comparability(g, algorithm='greedy', certificate=False, check=True, if check and isit and (not certif.is_transitive()): raise ValueError("Looks like there is a bug somewhere. The " "algorithm thinks that the orientation is " - "transitive, but we just checked and it is not." - "Please report the bug on sage-devel, and give" + "transitive, but we just checked and it is not. " + "Please report the bug on sage-devel, and give " "us the graph that made this method fail !") return isit, certif @@ -578,15 +601,17 @@ def is_comparability(g, algorithm='greedy', certificate=False, check=True, def is_permutation(g, algorithm='greedy', certificate=False, check=True, solver=None, verbose=0): r""" - Test whether the graph is a permutation graph. + Check whether the graph is a permutation graph. For more information on permutation graphs, refer to the documentation of the :mod:`comparability module `. INPUT: - - ``algorithm`` -- choose the implementation used for the subcalls to - :meth:`is_comparability` + - ``g`` -- a graph + + - ``algorithm`` -- string (default: ``'greedy'``); choose the implementation + used for the subcalls to :meth:`is_comparability` - ``'greedy'`` -- a greedy algorithm (see the documentation of the :mod:`comparability module `) @@ -596,20 +621,23 @@ def is_permutation(g, algorithm='greedy', certificate=False, check=True, certificates ! When ``certificate = True``, negative certificates are always equal to ``None``. ``True`` certificates are valid, though. - - ``certificate`` -- boolean; whether to return a certificate for the - answer given. For ``True`` answers the certificate is a permutation, for - ``False`` answers it is a no-certificate for the test of comparability or - co-comparability. + - ``certificate`` -- boolean (default: ``False``); whether to return a + certificate for the answer given. For ``True`` answers the certificate is + a permutation, for ``False`` answers it is a no-certificate for the test + of comparability or co-comparability. - - ``check`` -- boolean; whether to check that the permutations returned - indeed create the expected Permutation graph. Pretty cheap compared to the - rest, hence a good investment. It is enabled by default. + - ``check`` -- boolean (default: ``True``); whether to check that the + permutations returned indeed create the expected Permutation graph. Pretty + cheap compared to the rest, hence a good investment. It is enabled by + default. - - ``solver`` -- (default: ``None``) specify a Linear Program (LP) solver to - be used. If set to ``None``, the default one is used. For more information - on LP solvers and which default solver is used, see the method - :meth:`~sage.numerical.mip.MixedIntegerLinearProgram.solve` of the class - :class:`~sage.numerical.mip.MixedIntegerLinearProgram`. + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear + Programming (MILP) solver to be used. If set to ``None``, the default one + is used. For more information on MILP solvers and which default solver is + used, see the method :meth:`solve + ` of the class + :class:`MixedIntegerLinearProgram + `. - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 by default, which means quiet. @@ -644,33 +672,33 @@ def is_permutation(g, algorithm='greedy', certificate=False, check=True, Trying random permutations, first with the greedy algorithm:: - sage: from sage.graphs.comparability import is_permutation - sage: for i in range(20): - ....: p = Permutations(10).random_element() - ....: g1 = graphs.PermutationGraph(p) - ....: isit, certif = is_permutation(g1, certificate=True) - ....: if not isit: - ....: print("Something is wrong here !!") - ....: break - ....: g2 = graphs.PermutationGraph(*certif) - ....: if not g1.is_isomorphic(g2): - ....: print("Something is wrong here !!") - ....: break + sage: from sage.graphs.comparability import is_permutation + sage: for i in range(20): + ....: p = Permutations(10).random_element() + ....: g1 = graphs.PermutationGraph(p) + ....: isit, certif = is_permutation(g1, certificate=True) + ....: if not isit: + ....: print("Something is wrong here !!") + ....: break + ....: g2 = graphs.PermutationGraph(*certif) + ....: if not g1.is_isomorphic(g2): + ....: print("Something is wrong here !!") + ....: break Then with MILP:: - sage: from sage.graphs.comparability import is_permutation - sage: for i in range(20): # needs sage.numerical.mip - ....: p = Permutations(10).random_element() - ....: g1 = graphs.PermutationGraph(p) - ....: isit, certif = is_permutation(g1, algorithm='MILP', certificate=True) - ....: if not isit: - ....: print("Something is wrong here !!") - ....: break - ....: g2 = graphs.PermutationGraph(*certif) - ....: if not g1.is_isomorphic(g2): - ....: print("Something is wrong here !!") - ....: break + sage: from sage.graphs.comparability import is_permutation + sage: for i in range(20): # needs sage.numerical.mip + ....: p = Permutations(10).random_element() + ....: g1 = graphs.PermutationGraph(p) + ....: isit, certif = is_permutation(g1, algorithm='MILP', certificate=True) + ....: if not isit: + ....: print("Something is wrong here !!") + ....: break + ....: g2 = graphs.PermutationGraph(*certif) + ....: if not g1.is_isomorphic(g2): + ....: print("Something is wrong here !!") + ....: break """ if not certificate: # No certificate... A piece of cake From 349ed3cbf54b40f685aa0e35b3f2179aa4b039d5 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 29 Dec 2024 16:05:00 +0100 Subject: [PATCH 085/175] fix ordering issue with vertices of different types --- src/sage/graphs/comparability.pyx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/comparability.pyx b/src/sage/graphs/comparability.pyx index 08714ade199..88a3314b3cc 100644 --- a/src/sage/graphs/comparability.pyx +++ b/src/sage/graphs/comparability.pyx @@ -262,7 +262,7 @@ def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): sage: from sage.graphs.comparability import greedy_is_comparability sage: G = Graph([('a', 1), (1, 2), (2, 3)]) sage: greedy_is_comparability(G, equivalence_class=True) - (True, [(2, 3), (2, 1), ('a', 1)]) + (True, [('a', 1), (2, 1), (2, 3)]) """ cdef int i, j @@ -298,6 +298,10 @@ def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): if isit: if equivalence_class: + # We use a mapping between vertices and integers to deal with + # vertices of different types + int_to_vertex = list(g) + vertex_to_int = {u: i for i, u in enumerate(int_to_vertex)} # Returning the largest equivalence class cc = max(h.connected_components(sort=False), key=len) @@ -307,14 +311,16 @@ def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): s = equivalence_classes[v][sid] # For each edge we pick the good orientations + vi = vertex_to_int[v] if certif[v, sid] == 1: - edges.extend((v, vv) for vv in s) + edges.extend((vi, vertex_to_int[vv]) for vv in s) else: - edges.extend((vv, v) for vv in s) + edges.extend((vertex_to_int[vv], vi) for vv in s) # We return the value but take care of removing edges that were # added twice. - return True, list(set(edges)) + edges = [(int_to_vertex[u], int_to_vertex[v]) for u, v in sorted(set(edges))] + return True, edges return True From fe94c3f639ec2c57f82b78db806ea142bd4ef6ce Mon Sep 17 00:00:00 2001 From: dcoudert Date: Mon, 30 Dec 2024 17:42:57 +0100 Subject: [PATCH 086/175] bidirectional dijkstra using pairing heap --- src/sage/data_structures/pairing_heap.pxd | 1 + src/sage/graphs/base/c_graph.pyx | 224 +++++++++++++++++++++- src/sage/graphs/generic_graph.py | 2 +- 3 files changed, 216 insertions(+), 11 deletions(-) diff --git a/src/sage/data_structures/pairing_heap.pxd b/src/sage/data_structures/pairing_heap.pxd index d749cc7ec31..875e654c457 100644 --- a/src/sage/data_structures/pairing_heap.pxd +++ b/src/sage/data_structures/pairing_heap.pxd @@ -30,6 +30,7 @@ cdef extern from "./pairing_heap.h" namespace "pairing_heap": void decrease(TypeOfItem, TypeOfValue) except + bint contains(TypeOfItem) TypeOfValue value(TypeOfItem) except + + size_t size() cdef cppclass PairingHeapNodePy: PyObject * value # value associated with the item diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 00a535c3335..f3db3dce905 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -52,6 +52,7 @@ from libcpp.pair cimport pair from sage.rings.integer_ring import ZZ from cysignals.memory cimport check_allocarray, sig_free from sage.data_structures.bitset cimport FrozenBitset +from sage.data_structures.pairing_heap cimport PairingHeap cdef extern from "Python.h": @@ -3868,7 +3869,7 @@ cdef class CGraphBackend(GenericGraphBackend): return shortest_path - def bidirectional_dijkstra(self, x, y, weight_function=None, + def bidirectional_dijkstra_old(self, x, y, weight_function=None, distance_flag=False): r""" Return the shortest path or distance from ``x`` to ``y`` using a @@ -3899,15 +3900,15 @@ cdef class CGraphBackend(GenericGraphBackend): sage: G = Graph(graphs.PetersenGraph()) sage: for (u, v) in G.edges(sort=True, labels=None): - ....: G.set_edge_label(u, v, 1) - sage: G.shortest_path(0, 1, by_weight=True) + ....: G.set_edge_label(u, v, 1) + sage: G._backend.bidirectional_dijkstra_old(0, 1) [0, 1] - sage: G.shortest_path_length(0, 1, by_weight=True) + sage: G._backend.bidirectional_dijkstra_old(0, 1, distance_flag=True) 1 sage: G = DiGraph([(1, 2, {'weight':1}), (1, 3, {'weight':5}), (2, 3, {'weight':1})]) - sage: G.shortest_path(1, 3, weight_function=lambda e:e[2]['weight']) + sage: G._backend.bidirectional_dijkstra_old(1, 3, weight_function=lambda e:e[2]['weight']) [1, 2, 3] - sage: G.shortest_path_length(1, 3, weight_function=lambda e:e[2]['weight']) + sage: G._backend.bidirectional_dijkstra_old(1, 3, weight_function=lambda e:e[2]['weight'], distance_flag=True) 2 TESTS: @@ -3915,21 +3916,21 @@ cdef class CGraphBackend(GenericGraphBackend): Bugfix from :issue:`7673` :: sage: G = Graph([(0, 1, 9), (0, 2, 8), (1, 2, 7)]) - sage: G.shortest_path_length(0, 1, by_weight=True) + sage: G._backend.bidirectional_dijkstra_old(0, 1, distance_flag=True) 9 Bugfix from :issue:`28221` :: sage: G = Graph([(0, 1, 9.2), (0, 2, 4.5), (1, 2, 4.6)]) - sage: G.shortest_path_length(0, 1, by_weight=True) + sage: G._backend.bidirectional_dijkstra_old(0, 1, distance_flag=True) 9.1 Bugfix from :issue:`27464` :: sage: G = DiGraph({0: [1, 2], 1: [4], 2: [3, 4], 4: [5], 5: [6]}, multiedges=True) sage: for u, v in list(G.edges(labels=None, sort=False)): - ....: G.set_edge_label(u, v, 1) - sage: G.distance(0, 5, by_weight=true) + ....: G.set_edge_label(u, v, 1) + sage: G._backend.bidirectional_dijkstra_old(0, 5, distance_flag=true) 3 """ if x == y: @@ -4067,6 +4068,209 @@ cdef class CGraphBackend(GenericGraphBackend): return shortest_path + def bidirectional_dijkstra(self, x, y, weight_function=None, + distance_flag=False): + r""" + Return the shortest path or distance from ``x`` to ``y`` using a + bidirectional version of Dijkstra's algorithm. + + INPUT: + + - ``x`` -- the starting vertex in the shortest path from ``x`` to ``y`` + + - ``y`` -- the end vertex in the shortest path from ``x`` to ``y`` + + - ``weight_function`` -- function (default: ``None``); a function that + inputs an edge ``(u, v, l)`` and outputs its weight. If ``None``, we + use the edge label ``l`` as a weight, if ``l`` is not ``None``, else + ``1`` as a weight. + + - ``distance_flag`` -- boolean (default: ``False``); when set to + ``True``, the shortest path distance from ``x`` to ``y`` is returned + instead of the path. + + OUTPUT: + + - A list of vertices in the shortest path from ``x`` to ``y`` or + distance from ``x`` to ``y`` is returned depending upon the value of + parameter ``distance_flag`` + + EXAMPLES:: + + sage: G = Graph(graphs.PetersenGraph()) + sage: for (u, v) in G.edges(sort=True, labels=None): + ....: G.set_edge_label(u, v, 1) + sage: G.shortest_path(0, 1, by_weight=True) + [0, 1] + sage: G.shortest_path_length(0, 1, by_weight=True) + 1 + sage: G = DiGraph([(1, 2, {'weight':1}), (1, 3, {'weight':5}), (2, 3, {'weight':1})]) + sage: G.shortest_path(1, 3, weight_function=lambda e:e[2]['weight']) + [1, 2, 3] + sage: G.shortest_path_length(1, 3, weight_function=lambda e:e[2]['weight']) + 2 + + TESTS: + + Bugfix from :issue:`7673` :: + + sage: G = Graph([(0, 1, 9), (0, 2, 8), (1, 2, 7)]) + sage: G.shortest_path_length(0, 1, by_weight=True) + 9 + + Bugfix from :issue:`28221` :: + + sage: G = Graph([(0, 1, 9.2), (0, 2, 4.5), (1, 2, 4.6)]) + sage: G.shortest_path_length(0, 1, by_weight=True) + 9.1 + + Bugfix from :issue:`27464` :: + + sage: G = DiGraph({0: [1, 2], 1: [4], 2: [3, 4], 4: [5], 5: [6]}, multiedges=True) + sage: for u, v in list(G.edges(labels=None, sort=False)): + ....: G.set_edge_label(u, v, 1) + sage: G.distance(0, 5, by_weight=true) + 3 + """ + if x == y: + if distance_flag: + return 0 + else: + return [x] + + # As for shortest_path, the roles of x and y are symmetric, hence we + # define dictionaries like pred_current and pred_other, which + # represent alternatively pred_x or pred_y according to the side + # studied. + cdef int x_int = self.get_vertex(x) + cdef int y_int = self.get_vertex(y) + cdef int v = 0 + cdef int w = 0 + cdef int pred + cdef int side + cdef double distance + + # Each vertex knows its predecessors in the search, for each side + cdef dict pred_x = {} + cdef dict pred_y = {} + cdef dict pred_current + + # Stores the distances from x and y + cdef dict dist_x = {} + cdef dict dist_y = {} + cdef dict dist_current + cdef dict dist_other + + # We use 2 min-heap data structures (pairing heaps), one for the + # exploration from x and the other for the reverse exploration to y. + # Each heap associates to a vertex a pair (distance, pred). + cdef PairingHeap[int, pair[double, int]] px = PairingHeap[int, pair[double, int]]() + cdef PairingHeap[int, pair[double, int]] py = PairingHeap[int, pair[double, int]]() + cdef PairingHeap[int, pair[double, int]] * ptmp + px.push(x_int, (0, x_int)) + py.push(y_int, (0, y_int)) + + cdef list neighbors + + # Meeting_vertex is a vertex discovered through x and through y + # which defines the shortest path found + # (of length shortest_path_length). + cdef int meeting_vertex = -1 + cdef double shortest_path_length + cdef double f_tmp + + if weight_function is None: + def weight_function(e): + return 1 if e[2] is None else e[2] + + # As long as the current side (x or y) is not totally explored ... + while not (px.empty() and py.empty()): + if (px.empty() or + (not py.empty() and px.top_value().first > py.top_value().first)): + side = -1 + ptmp = &py + else: # px is not empty + side = 1 + ptmp = &px + v, (distance, pred) = ptmp.top() + if meeting_vertex != -1 and distance > shortest_path_length: + break + ptmp.pop() + + if side == 1: + dist_current, dist_other = dist_x, dist_y + pred_current = pred_x + neighbors = self.cg().out_neighbors(v) + else: + dist_current, dist_other = dist_y, dist_x + pred_current = pred_y + neighbors = self.cg().in_neighbors(v) + + dist_current[v] = distance + if not distance_flag: + pred_current[v] = pred + + if v in dist_other: + f_tmp = distance + dist_other[v] + if meeting_vertex == -1 or f_tmp < shortest_path_length: + meeting_vertex = v + shortest_path_length = f_tmp + + for w in neighbors: + # If w has not yet been extracted from the heap, we check if we + # can improve its path + if w not in dist_current: + v_obj = self.vertex_label(v) + w_obj = self.vertex_label(w) + if side == -1: + v_obj, w_obj = w_obj, v_obj + if self._multiple_edges: + edge_label = min(weight_function((v_obj, w_obj, l)) for l in self.get_edge_label(v_obj, w_obj)) + else: + edge_label = weight_function((v_obj, w_obj, self.get_edge_label(v_obj, w_obj))) + if edge_label < 0: + raise ValueError("the graph contains an edge with negative weight") + f_tmp = distance + edge_label + if ptmp.contains(w): + if ptmp.value(w).first > f_tmp: + ptmp.decrease(w, (f_tmp, v)) + else: + ptmp.push(w, (f_tmp, v)) + + # No meeting point has been found + if meeting_vertex == -1: + if distance_flag: + from sage.rings.infinity import Infinity + return Infinity + return [] + + if distance_flag: + if shortest_path_length in ZZ: + return int(shortest_path_length) + return shortest_path_length + + # build the shortest path and returns it. + cdef list shortest_path = [] + w = meeting_vertex + while w != x_int: + shortest_path.append(self.vertex_label(w)) + w = pred_x[w] + + shortest_path.append(x) + shortest_path.reverse() + + if meeting_vertex == y_int: + return shortest_path + + w = pred_y[meeting_vertex] + while w != y_int: + shortest_path.append(self.vertex_label(w)) + w = pred_y[w] + + shortest_path.append(y) + + return shortest_path + def shortest_path_all_vertices(self, v, cutoff=None, distance_flag=False): r""" diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 101952109c3..38b6b816134 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -17338,7 +17338,7 @@ def shortest_path(self, u, v, by_weight=False, algorithm=None, sage: D.shortest_path(4, 8, algorithm='Dijkstra_Bid_NetworkX') # needs networkx [4, 3, 2, 1, 8] sage: D.shortest_path(4, 9, algorithm='Dijkstra_Bid') - [4, 3, 19, 0, 10, 9] + [4, 3, 2, 1, 8, 9] sage: D.shortest_path(5, 5) [5] sage: D.delete_edges(D.edges_incident(13)) From 3ba67e296cc1746eec4cd26376beb8558e7df5a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 31 Dec 2024 15:24:19 +0100 Subject: [PATCH 087/175] add some typing annotations to gens methods (-> tuple) --- .../rings/algebraic_closure_finite_field.py | 2 +- src/sage/rings/asymptotic/growth_group.py | 14 ++++++------- .../asymptotic/growth_group_cartesian.py | 2 +- src/sage/rings/derivation.py | 2 +- src/sage/rings/function_field/ideal.py | 2 +- .../rings/function_field/ideal_polymod.py | 19 +++++++++--------- .../rings/function_field/ideal_rational.py | 8 ++++---- src/sage/rings/ideal.py | 4 ++-- src/sage/rings/lazy_series_ring.py | 4 ++-- src/sage/rings/localization.py | 2 +- src/sage/rings/number_field/class_group.py | 2 +- .../rings/number_field/number_field_ideal.py | 6 +++--- .../rings/number_field/number_field_rel.py | 2 +- src/sage/rings/number_field/order_ideal.py | 6 +++--- src/sage/rings/padics/padic_generic.py | 20 ++++++------------- .../polynomial/infinite_polynomial_ring.py | 2 +- .../polynomial/laurent_polynomial_ideal.py | 2 +- .../polynomial/multi_polynomial_ideal.py | 11 +++++----- src/sage/rings/polynomial/polynomial_ring.py | 2 +- src/sage/rings/qqbar.py | 4 ++-- src/sage/rings/rational_field.py | 2 +- .../rings/semirings/tropical_mpolynomial.py | 2 +- .../rings/semirings/tropical_polynomial.py | 4 ++-- src/sage/rings/tate_algebra.py | 8 ++++---- src/sage/rings/valuation/value_group.py | 2 +- 25 files changed, 63 insertions(+), 71 deletions(-) diff --git a/src/sage/rings/algebraic_closure_finite_field.py b/src/sage/rings/algebraic_closure_finite_field.py index b5e76c676d3..61a430262ca 100644 --- a/src/sage/rings/algebraic_closure_finite_field.py +++ b/src/sage/rings/algebraic_closure_finite_field.py @@ -833,7 +833,7 @@ def gen(self, n): F = self._subfield(n) return self(F.gen()) - def gens(self): + def gens(self): # -> Family """ Return a family of generators of ``self``. diff --git a/src/sage/rings/asymptotic/growth_group.py b/src/sage/rings/asymptotic/growth_group.py index a82188ed355..3f711f269aa 100644 --- a/src/sage/rings/asymptotic/growth_group.py +++ b/src/sage/rings/asymptotic/growth_group.py @@ -2370,7 +2370,7 @@ def _pushout_(self, other): from sage.categories.cartesian_product import cartesian_product return cartesian_product([self, other]) - def gens_monomial(self): + def gens_monomial(self) -> tuple: r""" Return a tuple containing monomial generators of this growth group. @@ -2399,9 +2399,9 @@ def gens_monomial(self): sage: GrowthGroup('QQ^x').gens_monomial() () """ - return tuple() + return () - def gens(self): + def gens(self) -> tuple: r""" Return a tuple of all generators of this growth group. @@ -3519,7 +3519,7 @@ def _split_raw_element_(raw_element): from sage.functions.other import real, imag return real(raw_element), imag(raw_element) - def gens_monomial(self): + def gens_monomial(self) -> tuple: r""" Return a tuple containing monomial generators of this growth group. @@ -3546,7 +3546,7 @@ def gens_monomial(self): return tuple() return (self(raw_element=self.base().one()),) - def gens_logarithmic(self): + def gens_logarithmic(self) -> tuple: r""" Return a tuple containing logarithmic generators of this growth group. @@ -4529,7 +4529,7 @@ def some_elements(self): return iter(self.element_class(self, e) for e in self.base().some_elements() if e > 0) - def gens(self): + def gens(self) -> tuple: r""" Return a tuple of all generators of this exponential growth group. @@ -4543,7 +4543,7 @@ def gens(self): sage: E.gens() () """ - return tuple() + return () def construction(self): r""" diff --git a/src/sage/rings/asymptotic/growth_group_cartesian.py b/src/sage/rings/asymptotic/growth_group_cartesian.py index 19bb7d975a6..1b15ac8f252 100644 --- a/src/sage/rings/asymptotic/growth_group_cartesian.py +++ b/src/sage/rings/asymptotic/growth_group_cartesian.py @@ -836,7 +836,7 @@ def next_custom(self): from sage.categories.cartesian_product import cartesian_product return pushout(cartesian_product(newS), cartesian_product(newO)) - def gens_monomial(self): + def gens_monomial(self) -> tuple: r""" Return a tuple containing monomial generators of this growth group. diff --git a/src/sage/rings/derivation.py b/src/sage/rings/derivation.py index 4375ddfe656..24c9ac92dd7 100644 --- a/src/sage/rings/derivation.py +++ b/src/sage/rings/derivation.py @@ -649,7 +649,7 @@ def ngens(self): raise NotImplementedError("generators are not implemented for this derivation module") return len(self._gens) - def gens(self): + def gens(self) -> tuple: r""" Return the generators of this module of derivations. diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index 2ef9d20d132..640e2f53ae3 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -723,7 +723,7 @@ def module(self): """ return self._module - def gens(self): + def gens(self) -> tuple: """ Return a set of generators of this ideal. diff --git a/src/sage/rings/function_field/ideal_polymod.py b/src/sage/rings/function_field/ideal_polymod.py index 829598231cb..cedc8d3b273 100644 --- a/src/sage/rings/function_field/ideal_polymod.py +++ b/src/sage/rings/function_field/ideal_polymod.py @@ -579,7 +579,7 @@ def module(self): return V.span([to(g) for g in self.gens_over_base()], base_ring=O) @cached_method - def gens_over_base(self): + def gens_over_base(self) -> tuple: """ Return the generators of this ideal as a module over the maximal order of the base rational function field. @@ -624,7 +624,7 @@ def _gens_over_base(self): for row in self._hnf] return gens, self._denominator - def gens(self): + def gens(self) -> tuple: """ Return a set of generators of this ideal. @@ -1108,7 +1108,7 @@ def __pow__(self, mod): return generic_power(self, mod) - def gens(self): + def gens(self) -> tuple: """ Return a set of generators of this ideal. @@ -1134,10 +1134,9 @@ def gens(self): """ if self._gens_two.is_in_cache(): return self._gens_two.cache - else: - return self.gens_over_base() + return self.gens_over_base() - def gens_two(self): + def gens_two(self) -> tuple: r""" Return two generators of this fractional ideal. @@ -1173,7 +1172,7 @@ def gens_two(self): return tuple(e / d for e in self._gens_two()) @cached_method - def _gens_two(self): + def _gens_two(self) -> tuple: r""" Return a set of two generators of the integral ideal, that is the denominator times this fractional ideal. @@ -1556,7 +1555,7 @@ def _relative_degree(self): return self._ideal._relative_degree - def gens(self): + def gens(self) -> tuple: """ Return a set of generators of this ideal. @@ -1582,7 +1581,7 @@ def gens(self): iF, from_iF, to_iF = F._inversion_isomorphism() return tuple(from_iF(b) for b in self._ideal.gens()) - def gens_two(self): + def gens_two(self) -> tuple: """ Return a set of at most two generators of this ideal. @@ -1608,7 +1607,7 @@ def gens_two(self): iF, from_iF, to_iF = F._inversion_isomorphism() return tuple(from_iF(b) for b in self._ideal.gens_two()) - def gens_over_base(self): + def gens_over_base(self) -> tuple: """ Return a set of generators of this ideal. diff --git a/src/sage/rings/function_field/ideal_rational.py b/src/sage/rings/function_field/ideal_rational.py index 59c63cc9782..6cb21710e0d 100644 --- a/src/sage/rings/function_field/ideal_rational.py +++ b/src/sage/rings/function_field/ideal_rational.py @@ -252,7 +252,7 @@ def gen(self): """ return self._gen - def gens(self): + def gens(self) -> tuple: """ Return the tuple of the unique generator of this ideal. @@ -267,7 +267,7 @@ def gens(self): """ return (self._gen,) - def gens_over_base(self): + def gens_over_base(self) -> tuple: """ Return the generator of this ideal as a rank one module over the maximal order. @@ -548,7 +548,7 @@ def gen(self): """ return self._gen - def gens(self): + def gens(self) -> tuple: """ Return the generator of this principal ideal. @@ -563,7 +563,7 @@ def gens(self): """ return (self._gen,) - def gens_over_base(self): + def gens_over_base(self) -> tuple: """ Return the generator of this ideal as a rank one module over the infinite maximal order. diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index dc785891828..96520442c49 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -280,7 +280,7 @@ def __init__(self, ring, gens, coerce=True, **kwds): gens = [ring(x) for x in gens] gens = tuple(gens) - if len(gens) == 0: + if not gens: gens = (ring.zero(),) self.__gens = gens MonoidElement.__init__(self, ring.ideal_monoid()) @@ -622,7 +622,7 @@ def reduce(self, f): """ return f # default - def gens(self): + def gens(self): # -> tuple | PolynomialSequence """ Return a set of generators / a basis of ``self``. diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index a5900982a3a..51359391111 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -1604,7 +1604,7 @@ def ngens(self): return 1 @cached_method - def gens(self): + def gens(self) -> tuple: """ Return the generators of ``self``. @@ -2168,7 +2168,7 @@ def ngens(self): return len(self.variable_names()) @cached_method - def gens(self): + def gens(self) -> tuple: """ Return the generators of ``self``. diff --git a/src/sage/rings/localization.py b/src/sage/rings/localization.py index e5015e95a7a..8ac31a6ff67 100644 --- a/src/sage/rings/localization.py +++ b/src/sage/rings/localization.py @@ -838,7 +838,7 @@ def gen(self, i): """ return self(self.base_ring().gen(i)) - def gens(self): + def gens(self) -> tuple: """ Return a tuple whose entries are the generators for this object, in order. diff --git a/src/sage/rings/number_field/class_group.py b/src/sage/rings/number_field/class_group.py index 34a48931f8e..e1185a499bb 100644 --- a/src/sage/rings/number_field/class_group.py +++ b/src/sage/rings/number_field/class_group.py @@ -303,7 +303,7 @@ def representative_prime(self, norm_bound=1000): return P raise RuntimeError("No prime of norm less than %s found in class %s" % (norm_bound, c)) - def gens(self): + def gens(self) -> tuple: r""" Return generators for a representative ideal in this (`S`-)ideal class. diff --git a/src/sage/rings/number_field/number_field_ideal.py b/src/sage/rings/number_field/number_field_ideal.py index 171fba9af6e..28fbe508a47 100644 --- a/src/sage/rings/number_field/number_field_ideal.py +++ b/src/sage/rings/number_field/number_field_ideal.py @@ -815,7 +815,7 @@ def gens_reduced(self, proof=None): self._cache_bnfisprincipal(proof=proof, gens=True) return self._reduced_generators - def gens_two(self): + def gens_two(self) -> tuple: r""" Express this ideal using exactly two generators, the first of which is a generator for the intersection of the ideal with `\QQ`. @@ -861,8 +861,8 @@ def gens_two(self): HNF = self.pari_hnf() # Check whether the ideal is generated by an integer, i.e. # whether HNF is a multiple of the identity matrix - if HNF.gequal(HNF[0,0]): - a = HNF[0,0] + if HNF.gequal(HNF[0, 0]): + a = HNF[0, 0] alpha = 0 else: a, alpha = K.pari_nf().idealtwoelt(HNF) diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index 7ea070b113e..2216ee9c679 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -493,7 +493,7 @@ def is_absolute(self): """ return False - def gens(self): + def gens(self) -> tuple: """ Return the generators of this relative number field. diff --git a/src/sage/rings/number_field/order_ideal.py b/src/sage/rings/number_field/order_ideal.py index 772c4ad3a9a..3e0ecce3653 100644 --- a/src/sage/rings/number_field/order_ideal.py +++ b/src/sage/rings/number_field/order_ideal.py @@ -399,7 +399,7 @@ def conjugate(self): conj_gens = [g.conjugate() for g in self.gens()] return NumberFieldOrderIdeal(self.ring(), conj_gens) - def gens_two(self): + def gens_two(self) -> tuple: r""" Express this ideal using exactly two generators, the first of which is a generator for the intersection of the ideal with `\ZZ`. @@ -506,7 +506,7 @@ def is_principal(self): sol = f.solve_integer(-1) return sol is not None - def gens_reduced(self): + def gens_reduced(self) -> tuple: r""" Express this ideal in terms of at most two generators, and one if possible (i.e., if the ideal is principal). @@ -550,7 +550,7 @@ def gens_reduced(self): sol = f.solve_integer(-1) if sol is None: return self.gens_two() - gen = sum(c*g for c,g in zip(sol, bas)) + gen = sum(c * g for c, g in zip(sol, bas)) assert NumberFieldOrderIdeal(self.ring(), gen) == self return (gen,) diff --git a/src/sage/rings/padics/padic_generic.py b/src/sage/rings/padics/padic_generic.py index 39d1fb43006..be3f3de2e7d 100644 --- a/src/sage/rings/padics/padic_generic.py +++ b/src/sage/rings/padics/padic_generic.py @@ -145,20 +145,20 @@ def ngens(self): """ return 1 - def gens(self): + def gens(self) -> tuple: r""" - Return a list of generators. + Return a tuple of generators. EXAMPLES:: sage: R = Zp(5); R.gens() - [5 + O(5^21)] + (5 + O(5^21),) sage: Zq(25,names='a').gens() # needs sage.libs.ntl - [a + O(5^20)] + (a + O(5^20),) sage: S. = ZZ[]; f = x^5 + 25*x -5; W. = R.ext(f); W.gens() # needs sage.libs.ntl - [w + O(w^101)] + (w + O(w^101),) """ - return [self.gen()] + return (self.gen(),) def __richcmp__(self, other, op): r""" @@ -195,14 +195,6 @@ def __richcmp__(self, other, op): return self._printer.richcmp_modes(other._printer, op) - # def ngens(self): - # return 1 - - # def gen(self, n=0): - # if n != 0: - # raise IndexError, "only one generator" - # return self(self.prime()) - def print_mode(self): r""" Return the current print mode as a string. diff --git a/src/sage/rings/polynomial/infinite_polynomial_ring.py b/src/sage/rings/polynomial/infinite_polynomial_ring.py index 05735a21cd2..278e7b6e676 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_ring.py +++ b/src/sage/rings/polynomial/infinite_polynomial_ring.py @@ -1265,7 +1265,7 @@ def _first_ngens(self, n): return self.gens()[-n:] @cached_method - def gens_dict(self): + def gens_dict(self) -> GenDictWithBasering: """ Return a dictionary-like object containing the infinitely many ``{var_name:variable}`` pairs. diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 0403526ae15..096e6bff57d 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -211,7 +211,7 @@ def __contains__(self, f): g = f.__reduce__()[1][0] return (g in self.polynomial_ideal()) - def gens_reduced(self): + def gens_reduced(self) -> tuple: """ Return a reduced system of generators. diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index adf1dc5db01..ee556b4730c 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -448,8 +448,7 @@ def _groebner_basis_magma(self, deg_bound=None, prot=False, magma=magma_default) from sage.rings.polynomial.multi_polynomial_sequence import \ PolynomialSequence - B = PolynomialSequence([R(e) for e in mgb], R, immutable=True) - return B + return PolynomialSequence([R(e) for e in mgb], R, immutable=True) class MPolynomialIdeal_singular_base_repr: @@ -3919,10 +3918,12 @@ def __hash__(self): return 0 @cached_method - def gens(self): + def gens(self): # -> PolynomialSequence """ - Return a set of generators / a basis of this ideal. This is usually the - set of generators provided during object creation. + Return a set of generators / a basis of this ideal. + + This is usually the set of generators provided during object + creation. EXAMPLES:: diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 6be288de70f..ddb7537526a 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -1263,7 +1263,7 @@ def gen(self, n=0): raise IndexError("generator n not defined") return self.element_class(self, [0,1], is_gen=True) - def gens_dict(self): + def gens_dict(self) -> dict: """ Return a dictionary whose entries are ``{name:variable,...}``, where ``name`` stands for the variable names of this diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 3806663eaf0..bf0b0c4366e 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -1313,7 +1313,7 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=False): except TypeError: return False - def gens(self): + def gens(self) -> tuple: r""" Return a set of generators for this field. @@ -1811,7 +1811,7 @@ def construction(self): from sage.rings.rational_field import QQ return (AlgebraicClosureFunctor(), QQ) - def gens(self): + def gens(self) -> tuple: r""" Return a set of generators for this field. diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index f1b414089e2..6bd7e4a9362 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -918,7 +918,7 @@ def phi(x): assert phi(a) == v, "oops" return a - def gens(self): + def gens(self) -> tuple: r""" Return a tuple of generators of `\QQ`, which is only ``(1,)``. diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index d8011d2b033..33558a5fe38 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -915,7 +915,7 @@ def gen(self, n=0): return self.gens()[n] @cached_method - def gens(self): + def gens(self) -> tuple: r""" Return the generators of ``self``. diff --git a/src/sage/rings/semirings/tropical_polynomial.py b/src/sage/rings/semirings/tropical_polynomial.py index 42caa0601f9..965ee31ad8a 100644 --- a/src/sage/rings/semirings/tropical_polynomial.py +++ b/src/sage/rings/semirings/tropical_polynomial.py @@ -769,9 +769,9 @@ def gen(self, n=0): return self.gens()[n] @cached_method - def gens(self): + def gens(self) -> tuple: """ - Return a tuple whose entries are the generators for ``self``. + Return the generators for ``self``. EXAMPLES:: diff --git a/src/sage/rings/tate_algebra.py b/src/sage/rings/tate_algebra.py index d80060696be..43223432650 100644 --- a/src/sage/rings/tate_algebra.py +++ b/src/sage/rings/tate_algebra.py @@ -613,9 +613,9 @@ def ngens(self): """ return self._ngens - def gens(self): + def gens(self) -> tuple: r""" - Return the list of generators of this monoid of terms. + Return the generators of this monoid of terms. EXAMPLES:: @@ -934,9 +934,9 @@ def gen(self, n=0): except IndexError: raise ValueError("generator not defined") - def gens(self): + def gens(self) -> tuple: r""" - Return the list of generators of this Tate algebra. + Return the generators of this Tate algebra. EXAMPLES:: diff --git a/src/sage/rings/valuation/value_group.py b/src/sage/rings/valuation/value_group.py index 0ec0a087bac..77b1178922e 100644 --- a/src/sage/rings/valuation/value_group.py +++ b/src/sage/rings/valuation/value_group.py @@ -624,7 +624,7 @@ def _mul_(self, other, switch_sides=False): other = QQ.coerce(other) return DiscreteValueSemigroup([g*other for g in self._generators]) - def gens(self): + def gens(self) -> tuple: r""" Return the generators of this semigroup. From f819115f2145f72b689c99a12db11d75fc9cb85b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 31 Dec 2024 17:23:44 +0100 Subject: [PATCH 088/175] suggestion --- src/sage/rings/algebraic_closure_finite_field.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/algebraic_closure_finite_field.py b/src/sage/rings/algebraic_closure_finite_field.py index 61a430262ca..da9737adf38 100644 --- a/src/sage/rings/algebraic_closure_finite_field.py +++ b/src/sage/rings/algebraic_closure_finite_field.py @@ -53,12 +53,11 @@ - Vincent Delecroix (November 2013): additional methods """ - from sage.misc.abstract_method import abstract_method from sage.misc.fast_methods import WithEqualityById - from sage.rings.finite_rings.finite_field_base import FiniteField from sage.rings.ring import Field +from sage.sets.family import AbstractFamily from sage.structure.element import Element, FieldElement from sage.structure.richcmp import richcmp @@ -833,7 +832,7 @@ def gen(self, n): F = self._subfield(n) return self(F.gen()) - def gens(self): # -> Family + def gens(self) -> AbstractFamily: """ Return a family of generators of ``self``. From 11a3f7d35930de143f0b3039751f78e9ff2f5c9c Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Wed, 1 Jan 2025 12:04:03 -0700 Subject: [PATCH 089/175] Remove unnecessary for loop --- src/sage/graphs/graph_plot.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index f927df5a10d..6b968128849 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -753,13 +753,9 @@ def set_edges(self, **edge_options): style_key_edges = None thickness_key_edges = None if isinstance(self._options['edge_styles'], dict): - for k in self._options['edge_styles']: - style_key_edges = k in self._graph.edges() - break + style_key_edges = list(self._options['edge_styles'])[0] in self._graph.edges() if isinstance(self._options['edge_thicknesses'], dict): - for k in self._options['edge_thicknesses']: - thickness_key_edges = k in self._graph.edges() - break + thickness_key_edges = list(self._options['edge_thicknesses'])[0] in self._graph.edges() eoptions = {} if 'arrowsize' in self._options: From 1e2a17da52082b610967f9a4737a7e19de130df5 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 2 Jan 2025 15:51:47 +0530 Subject: [PATCH 090/175] Added definitions of properties of Kahler Algebras --- src/sage/categories/kahler_algebras.py | 38 +++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 83bd3b3e7b3..091661b82a3 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -25,6 +25,40 @@ class KahlerAlgebras(Category_over_base_ring): r""" The category of graded algebras satisfying the Kähler package. + A finite-dimensional graded algebra `\bigoplus_{k=1}^{r}A^k` satisfies + the *Kähler package* if the following properties hold: + + - Poincaré duality: There exists a perfect `\mathbb{Z}`-bilinear pairing + given by + + .. MATH:: + + A^k \times A^{r-k} \longrightarrow \mathbb{Z} \\ + (a,b) \mapsto \text{deg}(a \cdot b) + + - Hard-Lefschetz Theorem: The graded algebra contains *Lefschetz elements* + `\omega \in A^{1}_{\mathbb{R}}` such that multiplication by `\omega` is + an injection from `A^k_{\mathbb{R}} \longrightarrow A^{k+1}_{\mathbb{R}}` + for all `k < \frac{r}{2}`. + + - Hodge-Riemann-Minikowski Relations: Every Lefchetz element `\omega`, + define quadratic forms on `A^{k}_{\mathbb{R}}` given by + + .. MATH:: + + a \mapsto (-1)^k \text{deg}(a \cdot \omega^{r-2k} \cdot a) + + This quadratic form becomes positive definite upon restriction to the + kernel of the following map + + .. MATH:: + + A^k_\mathbb{R} \longrightarrow A^{r-k+1}_\mathbb{R} \\ + a \mapsto a \cdot \omega^{r-2k+1} + + REFERENCES: + + - [ANR2023]_ EXAMPLES:: @@ -64,10 +98,6 @@ def _top_degree(self): """ return max([b.degree() for b in self.basis()]) - # check all methods with matroids with loops/parallel elements - # add properties and Kahler algebra def. Be as detailed as possible - # issue with category - @abstract_method def lefschetz_element(): pass From ac745917933529b36a7b75241d3ee4867ab206e6 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 2 Jan 2025 15:55:41 +0530 Subject: [PATCH 091/175] Fixed typo --- src/sage/categories/kahler_algebras.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 091661b82a3..0c61a48cf21 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -92,7 +92,7 @@ def _top_degree(self): sage: ch = matroids.Uniform(4,6).chow_ring(QQ, False) sage: ch._top_degree() 3 - sage: ch = matroids.Wheel(3).chow_ring(QQ, 'atom-free') + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: ch._top_degree() 2 """ From e336e04976248b9f281d04dc72384794a2855b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 2 Jan 2025 20:49:06 +0100 Subject: [PATCH 092/175] true annotation, not commented --- src/sage/rings/polynomial/multi_polynomial_ideal.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index ee556b4730c..24239660dec 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -251,7 +251,7 @@ from sage.structure.element import parent from sage.structure.richcmp import (op_EQ, op_GE, op_GT, op_LE, op_LT, op_NE, rich_to_bool, richcmp_method) -from sage.structure.sequence import Sequence +from sage.structure.sequence import Sequence, Sequence_generic try: from sage.interfaces.expect import StdOutContext @@ -1160,7 +1160,7 @@ def triangular_decomposition(self, algorithm=None, singular=None): else: raise TypeError("algorithm '%s' unknown" % algorithm) - T = Sequence([ MPolynomialIdeal(Q,t) for t in Tbar]) + T = Sequence([MPolynomialIdeal(Q, t) for t in Tbar]) return sorted(T, key=lambda x: x.gens()) @require_field @@ -3918,7 +3918,7 @@ def __hash__(self): return 0 @cached_method - def gens(self): # -> PolynomialSequence + def gens(self) -> Sequence_generic: """ Return a set of generators / a basis of this ideal. From 65ac6cac70078287cbb2e13bffed26c157fb61cb Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Fri, 3 Jan 2025 11:04:01 +0530 Subject: [PATCH 093/175] Corrected super_categories(), documentation and doctests --- src/sage/categories/kahler_algebras.py | 6 +++--- src/sage/matroids/chow_ring.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 0c61a48cf21..bc43d42961a 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -34,7 +34,7 @@ class KahlerAlgebras(Category_over_base_ring): .. MATH:: A^k \times A^{r-k} \longrightarrow \mathbb{Z} \\ - (a,b) \mapsto \text{deg}(a \cdot b) + (a,b) \mapsto \text{deg}(a \cdot b). - Hard-Lefschetz Theorem: The graded algebra contains *Lefschetz elements* `\omega \in A^{1}_{\mathbb{R}}` such that multiplication by `\omega` is @@ -54,7 +54,7 @@ class KahlerAlgebras(Category_over_base_ring): .. MATH:: A^k_\mathbb{R} \longrightarrow A^{r-k+1}_\mathbb{R} \\ - a \mapsto a \cdot \omega^{r-2k+1} + a \mapsto a \cdot \omega^{r-2k+1}. REFERENCES: @@ -75,7 +75,7 @@ class KahlerAlgebras(Category_over_base_ring): sage: TestSuite(C).run() """ def super_categories(self): - return [GradedAlgebrasWithBasis(self.base_ring())] + return [GradedAlgebrasWithBasis(self.base_ring()).FiniteDimensional()] class ParentMethods: @abstract_method diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 2b49e7b5e9f..6153a1691d3 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -356,7 +356,7 @@ def poincare_pairing(self, el1, el2): -1/6*A2*A012345 + 41/48*A012345^2 sage: v = ch(-A345^2 - 1/4*A345); v -A345^2 - 1/4*A345 - sage: ch.poincare_pairing(v, u, ch.matroid().rank()) + sage: ch.poincare_pairing(v, u) 3 """ r = self._top_degree() From 3b8c699651e38c5ad55195270452fa6ba3e0abf9 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Fri, 3 Jan 2025 12:35:00 +0530 Subject: [PATCH 094/175] Corrected TestSuite() doctest --- src/sage/categories/category_types.py | 5 +++-- src/sage/categories/graded_algebras_with_basis.py | 4 ++++ src/sage/categories/kahler_algebras.py | 11 +++++++---- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/sage/categories/category_types.py b/src/sage/categories/category_types.py index 01455011c40..567e2b7d195 100644 --- a/src/sage/categories/category_types.py +++ b/src/sage/categories/category_types.py @@ -202,12 +202,13 @@ def _test_category_over_bases(self, **options): """ tester = self._tester(**options) from sage.categories.category_singleton import Category_singleton - + from sage.categories.category_with_axiom import CategoryWithAxiom_over_base_ring from .bimodules import Bimodules from .schemes import Schemes for cat in self.super_categories(): tester.assertTrue(isinstance(cat, (Category_singleton, Category_over_base, - Bimodules, Schemes)), + CategoryWithAxiom_over_base_ring, + Bimodules, Schemes)), "The super categories of a category over base should" " be a category over base (or the related Bimodules)" " or a singleton category") diff --git a/src/sage/categories/graded_algebras_with_basis.py b/src/sage/categories/graded_algebras_with_basis.py index 793e19c848b..c87a90af893 100644 --- a/src/sage/categories/graded_algebras_with_basis.py +++ b/src/sage/categories/graded_algebras_with_basis.py @@ -13,6 +13,7 @@ from sage.categories.graded_modules import GradedModulesCategory from sage.categories.signed_tensor import SignedTensorProductsCategory, tensor_signed from sage.misc.cachefunc import cached_method +from sage.categories.category_with_axiom import CategoryWithAxiom_over_base_ring class GradedAlgebrasWithBasis(GradedModulesCategory): @@ -154,6 +155,9 @@ def formal_series_ring(self): class ElementMethods: pass + class FiniteDimensional(CategoryWithAxiom_over_base_ring): + pass + class SignedTensorProducts(SignedTensorProductsCategory): """ The category of algebras with basis constructed by signed tensor diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index bc43d42961a..d176abb72fc 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -8,6 +8,8 @@ from sage.categories.category_types import Category_over_base_ring from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis +from sage.categories.finite_dimensional_algebras_with_basis import FiniteDimensionalAlgebrasWithBasis +from sage.categories.filtered_modules_with_basis import FilteredModulesWithBasis from sage.misc.abstract_method import abstract_method from sage.quadratic_forms.quadratic_form import QuadraticForm from sage.misc.cachefunc import cached_method @@ -67,7 +69,8 @@ class KahlerAlgebras(Category_over_base_ring): sage: C = KahlerAlgebras(QQ); C Category of kahler algebras over Rational Field sage: sorted(C.super_categories(), key=str) - [Category of graded algebras with basis over Rational Field] + [Category of finite dimensional algebras with basis over Rational + Field, Category of graded algebras with basis over Rational Field] TESTS:: @@ -94,7 +97,7 @@ def _top_degree(self): 3 sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: ch._top_degree() - 2 + 3 """ return max([b.degree() for b in self.basis()]) @@ -110,7 +113,7 @@ def hodge_riemann_relations(self, k): EXAMPLES:: sage: ch = matroids.Uniform(4,6).chow_ring(QQ, False) - sage: ch.hodge_riemann_relations(1, ch.matroid().rank() - 1) + sage: ch.hodge_riemann_relations(1) Quadratic form in 36 variables over Rational Field with coefficients: [ 3 -1 -1 3 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 3 ] [ * 3 -1 3 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 3 ] @@ -148,7 +151,7 @@ def hodge_riemann_relations(self, k): [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 -1 ] [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 -1 ] [ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 3 ] - sage: ch.hodge_riemann_relations(3, ch.matroid().rank() - 1) + sage: ch.hodge_riemann_relations(3) Traceback (most recent call last): ... ValueError: k must be less than r < 2 From 8f2e1a56e5ca432516800276324fcc905bc1e961 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Fri, 3 Jan 2025 12:38:04 +0530 Subject: [PATCH 095/175] Changed top_degree() location --- .../categories/graded_algebras_with_basis.py | 16 +++++++++++++++- src/sage/categories/kahler_algebras.py | 16 ---------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/sage/categories/graded_algebras_with_basis.py b/src/sage/categories/graded_algebras_with_basis.py index c87a90af893..61ba58021c7 100644 --- a/src/sage/categories/graded_algebras_with_basis.py +++ b/src/sage/categories/graded_algebras_with_basis.py @@ -156,7 +156,21 @@ class ElementMethods: pass class FiniteDimensional(CategoryWithAxiom_over_base_ring): - pass + @cached_method + def top_degree(self): + r""" + Return the top degree of the finite dimensional graded algebra. + + EXAMPLES:: + + sage: ch = matroids.Uniform(4,6).chow_ring(QQ, False) + sage: ch.top_degree() + 3 + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') + sage: ch.top_degree() + 3 + """ + return max([b.degree() for b in self.basis()]) class SignedTensorProducts(SignedTensorProductsCategory): """ diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index d176abb72fc..c699c080653 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -85,22 +85,6 @@ class ParentMethods: def poincare_pairing(): pass - @cached_method - def _top_degree(self): - r""" - Return the top degree of the Kähler algebra. - - EXAMPLES:: - - sage: ch = matroids.Uniform(4,6).chow_ring(QQ, False) - sage: ch._top_degree() - 3 - sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') - sage: ch._top_degree() - 3 - """ - return max([b.degree() for b in self.basis()]) - @abstract_method def lefschetz_element(): pass From d25630cab52e9612442d186b476392c933358b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 3 Jan 2025 17:46:18 +0100 Subject: [PATCH 096/175] minor details in posets to please mypy --- src/sage/combinat/posets/hasse_diagram.py | 12 +++---- .../combinat/posets/incidence_algebras.py | 10 +++--- src/sage/combinat/posets/linear_extensions.py | 8 ++--- src/sage/combinat/posets/posets.py | 33 +++++++++---------- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 56b51e96371..8a872fa39ac 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -2101,14 +2101,14 @@ def orthocomplementations_iterator(self): for e in orbit: orbit_number[e] = ind - comps = [None] * n mt = self.meet_matrix() jn = self.join_matrix() - for e in range(n): - # Fix following after issue #20727 - comps[e] = [x for x in range(n) if - mt[e, x] == 0 and jn[e, x] == n - 1 and - x in orbits[orbit_number[dual_isomorphism[e]]]] + + # Fix following after issue #20727 + comps = [[x for x in range(n) + if mt[e, x] == 0 and jn[e, x] == n - 1 and + x in orbits[orbit_number[dual_e]]] + for e, dual_e in dual_isomorphism.items()] # Fitting is done by this recursive function: def recursive_fit(orthocomplements, unbinded): diff --git a/src/sage/combinat/posets/incidence_algebras.py b/src/sage/combinat/posets/incidence_algebras.py index 3fc3f2a0b76..720d49cf8f7 100644 --- a/src/sage/combinat/posets/incidence_algebras.py +++ b/src/sage/combinat/posets/incidence_algebras.py @@ -11,6 +11,8 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from copy import copy +from typing import Any from sage.misc.cachefunc import cached_method from sage.misc.lazy_attribute import lazy_attribute @@ -19,8 +21,6 @@ from sage.combinat.free_module import CombinatorialFreeModule from sage.matrix.matrix_space import MatrixSpace -from copy import copy - class IncidenceAlgebra(CombinatorialFreeModule): r""" @@ -449,7 +449,7 @@ def __init__(self, I, prefix='R') -> None: sage: TestSuite(R).run() # long time """ self._ambient = I - EC = {} + EC: dict[Any, list] = {} P = self._ambient._poset if not P.is_finite(): raise NotImplementedError("only implemented for finite posets") @@ -463,8 +463,8 @@ def __init__(self, I, prefix='R') -> None: break if not added: EC[S] = [i] - self._equiv_classes = map(sorted, EC.values()) - self._equiv_classes = {cls[0]: cls for cls in self._equiv_classes} + equiv_classes = map(sorted, EC.values()) + self._equiv_classes = {cls[0]: cls for cls in equiv_classes} cat = Algebras(I.base_ring()).FiniteDimensional().WithBasis() CombinatorialFreeModule.__init__(self, I.base_ring(), sorted(self._equiv_classes.keys()), diff --git a/src/sage/combinat/posets/linear_extensions.py b/src/sage/combinat/posets/linear_extensions.py index cf62e234321..f8c93185940 100644 --- a/src/sage/combinat/posets/linear_extensions.py +++ b/src/sage/combinat/posets/linear_extensions.py @@ -627,12 +627,12 @@ def cardinality(self): for x in range(n): # Use the existing Jup table to compute all covering # relations in J(P) for things that are above loc(x). - K = [[loc[x]]] + K0 = [[loc[x]]] j = 0 - while K[j]: - K.append([b for a in K[j] for b in Jup[a]]) + while K0[j]: + K0.append([b for a in K0[j] for b in Jup[a]]) j += 1 - K = sorted({item for sublist in K for item in sublist}) + K = sorted({item for sublist in K0 for item in sublist}) for j in range(len(K)): i = m + j + 1 Jup[i] = [m + K.index(a) + 1 for a in Jup[K[j]]] diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 2a4b2d24f48..366f505c3a4 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -699,15 +699,12 @@ def Poset(data=None, element_labels=None, cover_relations=False, linear_extensio if element_labels is not None: P = P.relabel(element_labels) return P - else: - if element_labels is None: - return FinitePoset(data, elements=data._elements, category=category, facade=facade) - else: - return FinitePoset(data, elements=element_labels, category=category, facade=facade) + if element_labels is None: + return FinitePoset(data, elements=data._elements, category=category, facade=facade) + return FinitePoset(data, elements=element_labels, category=category, facade=facade) # Convert data to a DiGraph elements = None - D = {} if data is None: # type 0 D = DiGraph() elif isinstance(data, DiGraph): # type 4 @@ -1529,10 +1526,11 @@ def sorted(self, l, allow_incomparable=True, remove_duplicates=False): sage: P.sorted([], allow_incomparable=False, remove_duplicates=False) [] """ - v = [self._element_to_vertex(x) for x in l] + v = (self._element_to_vertex(x) for x in l) if remove_duplicates: - v = set(v) - o = sorted(v) + o = sorted(set(v)) + else: + o = sorted(v) if not allow_incomparable: H = self._hasse_diagram @@ -2716,10 +2714,9 @@ def linear_intervals_count(self) -> list[int]: for y in H.neighbor_out_iterator(xmax): if exposant == 1: next_stock.append((xmin, y, y)) - else: - if (cov_xmin, y) in short_stock: - if H.is_linear_interval(xmin, y): - next_stock.append((xmin, cov_xmin, y)) + elif (cov_xmin, y) in short_stock: + if H.is_linear_interval(xmin, y): + next_stock.append((xmin, cov_xmin, y)) if next_stock: poly.append(len(next_stock)) stock = next_stock @@ -2856,12 +2853,12 @@ def is_incomparable_chain_free(self, m, n=None) -> bool: closure = self._hasse_diagram.transitive_closure() for m, n in chain_pairs: try: - m, n = Integer(m), Integer(n) + ZZm, ZZn = Integer(m), Integer(n) except TypeError: raise TypeError(f"{m} and {n} must be integers") if m < 1 or n < 1: raise ValueError(f"{m} and {n} must be positive integers") - twochains = digraphs.TransitiveTournament(m) + digraphs.TransitiveTournament(n) + twochains = digraphs.TransitiveTournament(ZZm) + digraphs.TransitiveTournament(ZZn) if closure.subgraph_search(twochains, induced=True) is not None: return False return True @@ -5324,9 +5321,9 @@ def edge_color(va, vb): neigh1 = [z for z in prod_dg.neighbor_iterator(x) if edge_color(x, z) == i1] for x0, x1 in product(neigh0, neigh1): - x2 = list(x0) - x2[i1] = x1[i1] - x2 = tuple(x2) + _x2 = list(x0) + _x2[i1] = x1[i1] + x2 = tuple(_x2) A0 = prod_dg.has_edge(x, x0) B0 = prod_dg.has_edge(x1, x2) if A0 != B0: From aa817c24e988df871dfaeedbc2faef67827ead34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 3 Jan 2025 19:04:33 +0100 Subject: [PATCH 097/175] some type annotations in modular folder --- src/sage/modular/cusps.py | 12 ++++-------- src/sage/modular/cusps_nf.py | 4 ++-- src/sage/modular/dims.py | 2 +- src/sage/modular/dirichlet.py | 4 +--- src/sage/modular/etaproducts.py | 13 +++++++------ src/sage/modular/hypergeometric_motive.py | 12 ++++++------ src/sage/modular/multiple_zeta.py | 20 ++++++++++++-------- 7 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/sage/modular/cusps.py b/src/sage/modular/cusps.py index 7a4a2628096..1dc3a2aaa22 100644 --- a/src/sage/modular/cusps.py +++ b/src/sage/modular/cusps.py @@ -27,6 +27,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +from sage.misc.cachefunc import cached_method from sage.misc.fast_methods import Singleton from sage.modular.modsym.p1list import lift_to_sl2z_llong from sage.rings.infinity import Infinity, InfinityRing @@ -195,7 +196,7 @@ def __init__(self, a, b=None, parent=None, check=True): self.__a = r.numer() self.__b = r.denom() except (ValueError, TypeError): - raise TypeError("unable to convert %r to a cusp" % a) + raise TypeError(f"unable to convert {a} to a cusp") else: try: r = QQ(a) @@ -364,6 +365,7 @@ def denominator(self): """ return self.__b + @cached_method def _rational_(self): """ Coerce to a rational number. @@ -379,15 +381,9 @@ def _rational_(self): sage: Cusp(11,2)._rational_() 11/2 """ - try: - return self.__rational - except AttributeError: - pass - if not self.__b: raise TypeError("cusp %s is not a rational number" % self) - self.__rational = self.__a / self.__b - return self.__rational + return self.__a / self.__b def _integer_(self, ZZ=None): """ diff --git a/src/sage/modular/cusps_nf.py b/src/sage/modular/cusps_nf.py index 4d120c075da..2fdfc7cdc02 100644 --- a/src/sage/modular/cusps_nf.py +++ b/src/sage/modular/cusps_nf.py @@ -488,8 +488,8 @@ def __init__(self, number_field, a, b=None, parent=None, lreps=None): self.__b = R(r.denominator()) self.__a = R(r * self.__b) except (ValueError, TypeError): - raise TypeError("unable to convert %r to a cusp " - "of the number field" % a) + raise TypeError(f"unable to convert {a} to a cusp " + "of the number field") else: try: r = number_field(a) diff --git a/src/sage/modular/dims.py b/src/sage/modular/dims.py index 7eef7392e76..423ed5a0c96 100644 --- a/src/sage/modular/dims.py +++ b/src/sage/modular/dims.py @@ -54,7 +54,7 @@ from sage.rings.integer import Integer from sage.rings.rational_field import frac -from . import dirichlet +from sage.modular import dirichlet ########################################################################## # Helper functions for calculating dimensions of spaces of modular forms diff --git a/src/sage/modular/dirichlet.py b/src/sage/modular/dirichlet.py index c261a84e8de..ddeb5b37fec 100644 --- a/src/sage/modular/dirichlet.py +++ b/src/sage/modular/dirichlet.py @@ -999,10 +999,8 @@ def fixed_field_polynomial(self, algorithm='pari'): v += s m.append(v) - m = matrix(m) - xx = S.gen() - return m.charpoly(xx) + return matrix(m).charpoly(xx) elif algorithm == "pari": # Use pari diff --git a/src/sage/modular/etaproducts.py b/src/sage/modular/etaproducts.py index 4b2d1e6ea2d..eedb7da940e 100644 --- a/src/sage/modular/etaproducts.py +++ b/src/sage/modular/etaproducts.py @@ -31,6 +31,7 @@ # https://www.gnu.org/licenses/ # *************************************************************************** from __future__ import annotations +from typing import Any from sage.arith.misc import divisors, prime_divisors, euler_phi, is_square, gcd from sage.categories.groups import Groups @@ -52,7 +53,7 @@ import weakref -_cache = {} +_cache: dict[int, Any] = {} def EtaGroup(level): @@ -107,10 +108,10 @@ def __init__(self, parent, rdict): if rdict == 1: rdict = {} + # Check Ligozat criteria sumR = sumDR = sumNoverDr = 0 prod = 1 - for d in list(rdict): if N % d: raise ValueError("%s does not divide %s" % (d, N)) @@ -120,7 +121,7 @@ def __init__(self, parent, rdict): continue sumR += rdict[d] sumDR += rdict[d] * d - sumNoverDr += rdict[d] * N / d + sumNoverDr += rdict[d] * (N // d) prod *= (N // d)**rdict[d] if sumR != 0: @@ -202,7 +203,7 @@ def is_one(self) -> bool: """ return not self._rdict - def _richcmp_(self, other, op): + def _richcmp_(self, other, op) -> bool: r""" Compare ``self`` to ``other``. @@ -556,7 +557,7 @@ def basis(self, reduce=True) -> list: good_vects.append((vect * 24 / gcd(nf, 24)).list()) for v in good_vects: v.append(-sum(list(v))) - dicts = [] + dicts: list[dict] = [] for v in good_vects: dicts.append({}) for i in range(s): @@ -1036,7 +1037,7 @@ def _eta_relations_helper(eta1, eta2, degree, qexp_terms, labels, verbose): if verbose: print("Trying all coefficients from q^%s to q^%s inclusive" % (-pole_at_infinity, -pole_at_infinity + qexp_terms - 1)) - rows = [[] for _ in range(qexp_terms)] + rows: list[list] = [[] for _ in range(qexp_terms)] for i in indices: func = (eta1**i[0] * eta2**i[1]).qexp(qexp_terms) for j in range(qexp_terms): diff --git a/src/sage/modular/hypergeometric_motive.py b/src/sage/modular/hypergeometric_motive.py index 393312443bd..4bf214d7e23 100644 --- a/src/sage/modular/hypergeometric_motive.py +++ b/src/sage/modular/hypergeometric_motive.py @@ -355,16 +355,16 @@ def cyclotomic_to_gamma(cyclo_up, cyclo_down) -> dict: sage: cyclotomic_to_gamma([6], [1]) {2: -1, 3: -1, 6: 1} """ - dico = defaultdict(int) + dico: dict[int, int] = defaultdict(int) for d in cyclo_up: dico[d] += 1 for d in cyclo_down: dico[d] -= 1 - resu = defaultdict(int) + resu: dict[int, int] = defaultdict(int) for n in dico: for d in divisors(n): - resu[d] += moebius(n / d) * dico[n] + resu[d] += moebius(n // d) * dico[n] return {d: resu[d] for d in resu if resu[d]} @@ -399,7 +399,7 @@ def gamma_list_to_cyclotomic(galist): sage: gamma_list_to_cyclotomic([8, 2, 2, 2, -6, -4, -3, -1]) ([2, 2, 8], [3, 3, 6]) """ - resu = defaultdict(int) + resu: dict[int, int] = defaultdict(int) for n in galist: eps = sgn(n) for d in divisors(abs(n)): @@ -824,7 +824,7 @@ def hodge_numbers(self) -> list: alpha = [(x, 'a') for x in self._alpha] beta = [(x, 'b') for x in self._beta] height = 0 - hodge = defaultdict(int) + hodge: dict[int, int] = defaultdict(int) for x, letter in sorted(alpha + beta): if letter == 'a': hodge[height] += 1 @@ -1423,7 +1423,7 @@ def padic_H_value(self, p, f, t, prec=None, cache_p=False): if q > 2 ** 31: raise ValueError("p^f cannot exceed 2^31") - m = defaultdict(int) + m: dict[int, int] = defaultdict(int) for b in beta: u = b * (q - 1) if u.is_integer(): diff --git a/src/sage/modular/multiple_zeta.py b/src/sage/modular/multiple_zeta.py index 8bcbb1101de..239bc0b1ead 100644 --- a/src/sage/modular/multiple_zeta.py +++ b/src/sage/modular/multiple_zeta.py @@ -202,13 +202,17 @@ # using the following convention # (3, 5) <---> (sign) * [1,0,0,1,0,0,0,0] # taken from the Maple implementation by F. Brown -B_data = [[], [], [(2,)], [(3,)], [], [(5,)], [], [(7,)], [(3, 5)], [(9,)], - [(3, 7)], [(11,), (3, 3, 5)], [(5, 7), (5, 3, 2, 2)], - [(13,), (3, 5, 5), (3, 3, 7)], [(5, 9), (3, 11), (3, 3, 3, 5)], - [(15,), (3, 5, 7), (3, 3, 9), (5, 3, 3, 2, 2)], - [(11, 5), (13, 3), (5, 5, 3, 3), (7, 3, 3, 3), (7, 5, 2, 2)], - [(17,), (7, 5, 5), (9, 3, 5), (9, 5, 3), (11, 3, 3), - (5, 3, 3, 3, 3), (5, 5, 3, 2, 2)]] +B_data: list[list[tuple]] = [[], [], [(2,)], [(3,)], [], [(5,)], [], + [(7,)], [(3, 5)], [(9,)], + [(3, 7)], [(11,), (3, 3, 5)], + [(5, 7), (5, 3, 2, 2)], + [(13,), (3, 5, 5), (3, 3, 7)], + [(5, 9), (3, 11), (3, 3, 3, 5)], + [(15,), (3, 5, 7), (3, 3, 9), (5, 3, 3, 2, 2)], + [(11, 5), (13, 3), (5, 5, 3, 3), + (7, 3, 3, 3), (7, 5, 2, 2)], + [(17,), (7, 5, 5), (9, 3, 5), (9, 5, 3), + (11, 3, 3), (5, 3, 3, 3, 3), (5, 5, 3, 2, 2)]] Words10 = Words((1, 0), infinite=False) @@ -1050,7 +1054,7 @@ def basis_filtration(self, d, reverse=False): dim = len(self((d,)).phi_as_vector()) V = VectorSpace(QQ, dim) U = V.subspace([]) - basis = [] + basis: list = [] k = 1 while len(basis) < dim: for c in Compositions(d, length=k): From 430e5a9c819221784468fa25658f9c40db7a8551 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 4 Jan 2025 10:37:27 +0530 Subject: [PATCH 098/175] Edited flats_to_generator_dict() method and kahler_algebras file --- src/sage/categories/kahler_algebras.py | 4 +- src/sage/matroids/chow_ring.py | 55 +++++--------------------- src/sage/matroids/chow_ring_ideal.py | 35 +++++++++++++++- 3 files changed, 46 insertions(+), 48 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index c699c080653..73ad0c761b1 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -82,7 +82,7 @@ def super_categories(self): class ParentMethods: @abstract_method - def poincare_pairing(): + def poincare_pairing(a,b): pass @abstract_method @@ -140,7 +140,7 @@ def hodge_riemann_relations(self, k): ... ValueError: k must be less than r < 2 """ - r = self._top_degree() + r = self.top_degree() if k > (r/2): raise ValueError("k must be less than r < 2") basis_k = [] diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 6153a1691d3..6fce4f9a2c3 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -10,6 +10,7 @@ from sage.rings.quotient_ring import QuotientRing_generic from sage.categories.kahler_algebras import KahlerAlgebras from sage.categories.commutative_rings import CommutativeRings +from sage.misc.cachefunc import cached_method class ChowRing(QuotientRing_generic): @@ -96,7 +97,7 @@ def __init__(self, R, M, augmented, presentation=None): self._ideal = AugmentedChowRingIdeal_atom_free(M, R) else: self._ideal = ChowRingIdeal_nonaug(M, R) - C = CommutativeRings().Quotients() & KahlerAlgebras(R).FiniteDimensional() + C = CommutativeRings().Quotients() & KahlerAlgebras(R) QuotientRing_generic.__init__(self, R=self._ideal.ring(), I=self._ideal, names=self._ideal.ring().variable_names(), @@ -197,43 +198,7 @@ def basis(self): monomial_basis = self._ideal.normal_basis() return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) - def flats_generator(self): - r""" - Return the corresponding generators of flats of the Chow ring. - - EXAMPLES:: - - sage: ch = matroids.catalog.NonFano().chow_ring(ZZ, True, 'atom-free') - sage: ch.flats_generator() - {frozenset({'a'}): Aa, - frozenset({'b'}): Ab, - frozenset({'c'}): Ac, - frozenset({'d'}): Ad, - frozenset({'e'}): Ae, - frozenset({'f'}): Af, - frozenset({'g'}): Ag, - frozenset({'a', 'b', 'f'}): Aabf, - frozenset({'a', 'c', 'e'}): Aace, - frozenset({'a', 'd', 'g'}): Aadg, - frozenset({'b', 'c', 'd'}): Abcd, - frozenset({'b', 'e', 'g'}): Abeg, - frozenset({'c', 'f', 'g'}): Acfg, - frozenset({'d', 'e'}): Ade, - frozenset({'d', 'f'}): Adf, - frozenset({'e', 'f'}): Aef, - frozenset({'a', 'b', 'c', 'd', 'e', 'f', 'g'}): Aabcdefg} - """ - flats = [X for i in range(1, self._matroid.rank() + 1) - for X in self._matroid.flats(i)] - gens = self.gens() - if not (self._augmented and self._presentation == 'fy'): - return dict(zip(flats, gens)) - flats_gen = {} - E = list(self.matroid().groundset()) - for i,F in enumerate(flats): - flats_gen[F] = gens[len(E) + i] - return flats_gen - + @cached_method def lefschetz_element(self): r""" Return one Lefschetz element of the given Chow ring. @@ -340,8 +305,9 @@ def lefschetz_element(self): sage: len(basis_deg[2]) 36 """ - w = sum(len(F) * (len(self.matroid().groundset()) - len(F)) * gen for F, gen in self.flats_generator().items()) - return w + w = sum(len(F) * (len(self.matroid().groundset()) - len(F)) * gen + for F, gen in self.defining_ideal().flat_to_generator_dict().items()) + return self.ElementClass(self,w) def poincare_pairing(self, el1, el2): r""" @@ -359,15 +325,14 @@ def poincare_pairing(self, el1, el2): sage: ch.poincare_pairing(v, u) 3 """ - r = self._top_degree() + r = self.top_degree() hom_components1 = el1.lift().homogeneous_components() hom_components2 = el2.lift().homogeneous_components() new_el = self.base_ring().zero() for i in hom_components1: - for j in hom_components2: - if r - i not in hom_components2: - continue - new_el += hom_components1[i] * hom_components2[j] + if r - i not in hom_components2: + continue + new_el += hom_components1[i] * hom_components2[r - i] return new_el.degree() class Element(QuotientRing_generic.Element): diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index f2a6c6cf477..906e6d59803 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -56,6 +56,39 @@ def _lattice_flats(self): chains = lattice_flats.chains() #Only chains return (ranks, chains) + def flats_to_generator_dict(self): + r""" + Return the corresponding generators of flats/groundset elements of + Chow ring ideal. + + EXAMPLES:: + + sage: ch = matroids.Uniform(4,6).chow_ring(QQ, True, 'atom-free') + sage: ch.defining_ideal().flats_to_generator_dict() + {frozenset({0}): A0, frozenset({1}): A1, frozenset({2}): A2, + frozenset({3}): A3, frozenset({4}): A4, frozenset({5}): A5, + frozenset({0, 1}): A01, frozenset({0, 2}): A02, + frozenset({0, 3}): A03, frozenset({0, 4}): A04, + frozenset({0, 5}): A05, frozenset({1, 2}): A12, + frozenset({1, 3}): A13, frozenset({1, 4}): A14, + frozenset({1, 5}): A15, frozenset({2, 3}): A23, + frozenset({2, 4}): A24, frozenset({2, 5}): A25, + frozenset({3, 4}): A34, frozenset({3, 5}): A35, + frozenset({4, 5}): A45, frozenset({0, 1, 2}): A012, + frozenset({0, 1, 3}): A013, frozenset({0, 1, 4}): A014, + frozenset({0, 1, 5}): A015, frozenset({0, 2, 3}): A023, + frozenset({0, 2, 4}): A024, frozenset({0, 2, 5}): A025, + frozenset({0, 3, 4}): A034, frozenset({0, 3, 5}): A035, + frozenset({0, 4, 5}): A045, frozenset({1, 2, 3}): A123, + frozenset({1, 2, 4}): A124, frozenset({1, 2, 5}): A125, + frozenset({1, 3, 4}): A134, frozenset({1, 3, 5}): A135, + frozenset({1, 4, 5}): A145, frozenset({2, 3, 4}): A234, + frozenset({2, 3, 5}): A235, frozenset({2, 4, 5}): A245, + frozenset({3, 4, 5}): A345, + frozenset({0, 1, 2, 3, 4, 5}): A012345} + """ + flats_gen = self._flats_generator + return flats_gen class ChowRingIdeal_nonaug(ChowRingIdeal): r""" @@ -118,7 +151,7 @@ def __init__(self, M, R): for X in self._matroid.flats(i)] names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] try: - poly_ring = PolynomialRing(R, names) #self.ring + poly_ring = PolynomialRing(R, names) # self.ring except ValueError: # variables are not proper names poly_ring = PolynomialRing(R, 'A', len(flats)) gens = poly_ring.gens() From 2c3cf57157b99a2933a3bd79aecd2fe52b74c954 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 4 Jan 2025 12:01:11 +0530 Subject: [PATCH 099/175] Changed top_degree() location --- .../categories/graded_algebras_with_basis.py | 27 ++++++++++--------- src/sage/categories/kahler_algebras.py | 14 ++++++++++ src/sage/matroids/chow_ring.py | 1 + 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/sage/categories/graded_algebras_with_basis.py b/src/sage/categories/graded_algebras_with_basis.py index 61ba58021c7..180760d1f32 100644 --- a/src/sage/categories/graded_algebras_with_basis.py +++ b/src/sage/categories/graded_algebras_with_basis.py @@ -156,21 +156,22 @@ class ElementMethods: pass class FiniteDimensional(CategoryWithAxiom_over_base_ring): - @cached_method - def top_degree(self): - r""" - Return the top degree of the finite dimensional graded algebra. + class ParentMethods: + @cached_method + def top_degree(self): + r""" + Return the top degree of the finite dimensional graded algebra. - EXAMPLES:: + EXAMPLES:: - sage: ch = matroids.Uniform(4,6).chow_ring(QQ, False) - sage: ch.top_degree() - 3 - sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') - sage: ch.top_degree() - 3 - """ - return max([b.degree() for b in self.basis()]) + sage: ch = matroids.Uniform(4,6).chow_ring(QQ, False) + sage: ch.top_degree() + 3 + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') + sage: ch.top_degree() + 3 + """ + return max([b.degree() for b in self.basis()]) class SignedTensorProducts(SignedTensorProductsCategory): """ diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 73ad0c761b1..3aa00cfaee6 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -83,6 +83,20 @@ def super_categories(self): class ParentMethods: @abstract_method def poincare_pairing(a,b): + r""" + Return the Poincaré pairing of two elements of the Kähler algebra. + + EXAMPLES:: + + sage: ch = matroids.catalog.Fano().chow_ring(QQ, True, 'fy') + sage: Ba, Bb, Bc, Bd, Be, Bf, Bg, Babf, Bace, Badg, Bbcd, Bbeg, Bcfg, Bdef, Babcdefg = ch.gens()[8:] + sage: u = ch(-Babf^2 + Bcfg^2 - 8/7*Bc*Babcdefg + 1/2*Bd*Babcdefg - Bf*Babcdefg - Bg*Babcdefg); u + -Babf^2 + Bcfg^2 - 8/7*Bc*Babcdefg + 1/2*Bd*Babcdefg - Bf*Babcdefg - Bg*Babcdefg + sage: v = ch(Bg - 2/37*Babf + Badg + Bbeg + Bcfg + Babcdefg); v + Bg - 2/37*Babf + Badg + Bbeg + Bcfg + Babcdefg + sage: ch.poincare_pairing(v, u) + 3 + """ pass @abstract_method diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 6fce4f9a2c3..4a148c9ec62 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -309,6 +309,7 @@ def lefschetz_element(self): for F, gen in self.defining_ideal().flat_to_generator_dict().items()) return self.ElementClass(self,w) + @cached_method def poincare_pairing(self, el1, el2): r""" Return the Poincaré pairing of any two elements of the From 89416b90f75fb9924a059a787926b8717b183234 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 4 Jan 2025 12:03:50 +0530 Subject: [PATCH 100/175] Edited chow_ring_ideal.py --- src/sage/matroids/chow_ring_ideal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 906e6d59803..3e72edacfc0 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -53,7 +53,7 @@ def _lattice_flats(self): flats = list(lattice_flats) flats.sort(key=lambda X: (len(X), sorted(X))) ranks = {F: self._matroid.rank(F) for F in flats} - chains = lattice_flats.chains() #Only chains + chains = lattice_flats.chains() # Only chains return (ranks, chains) def flats_to_generator_dict(self): @@ -151,7 +151,7 @@ def __init__(self, M, R): for X in self._matroid.flats(i)] names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] try: - poly_ring = PolynomialRing(R, names) # self.ring + poly_ring = PolynomialRing(R, names) # self.ring except ValueError: # variables are not proper names poly_ring = PolynomialRing(R, 'A', len(flats)) gens = poly_ring.gens() From f3152d335a91e2a5dec9da6a9aa324b561fceec5 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 4 Jan 2025 12:07:16 +0530 Subject: [PATCH 101/175] Edited chow_ring_ideal.py --- src/sage/matroids/chow_ring_ideal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 3e72edacfc0..58efa2a9bf3 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -151,7 +151,7 @@ def __init__(self, M, R): for X in self._matroid.flats(i)] names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] try: - poly_ring = PolynomialRing(R, names) # self.ring + poly_ring = PolynomialRing(R, names) # self.ring except ValueError: # variables are not proper names poly_ring = PolynomialRing(R, 'A', len(flats)) gens = poly_ring.gens() From e9efa6e5571d21b62db58a1a2660aa64d024ff9f Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 4 Jan 2025 12:07:58 +0530 Subject: [PATCH 102/175] Edited chow_ring_ideal.py --- src/sage/matroids/chow_ring_ideal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 58efa2a9bf3..88747e7673a 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -152,7 +152,7 @@ def __init__(self, M, R): names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] try: poly_ring = PolynomialRing(R, names) # self.ring - except ValueError: # variables are not proper names + except ValueError: # variables are not proper names poly_ring = PolynomialRing(R, 'A', len(flats)) gens = poly_ring.gens() self._flats_generator = dict(zip(flats, gens)) From df942f65a0bb7a35e96d5ed32091543a7c3904ce Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 4 Jan 2025 12:25:09 +0530 Subject: [PATCH 103/175] Corrected linting errors, doctests and added warning note --- src/sage/categories/category_types.py | 2 +- src/sage/matroids/chow_ring.py | 7 +++++-- src/sage/matroids/chow_ring_ideal.py | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/sage/categories/category_types.py b/src/sage/categories/category_types.py index 567e2b7d195..7f0d44c0f32 100644 --- a/src/sage/categories/category_types.py +++ b/src/sage/categories/category_types.py @@ -207,7 +207,7 @@ def _test_category_over_bases(self, **options): from .schemes import Schemes for cat in self.super_categories(): tester.assertTrue(isinstance(cat, (Category_singleton, Category_over_base, - CategoryWithAxiom_over_base_ring, + CategoryWithAxiom_over_base_ring, Bimodules, Schemes)), "The super categories of a category over base should" " be a category over base (or the related Bimodules)" diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 4a148c9ec62..2d00b04f312 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -53,6 +53,9 @@ class ChowRing(QuotientRing_generic): :mod:`sage.matroids.chow_ring_ideal` + An important note to be taken is that different presentations of Chow rings + of non-simple matroids may not be isomorphic to one another. + INPUT: - ``M`` -- matroid @@ -305,8 +308,8 @@ def lefschetz_element(self): sage: len(basis_deg[2]) 36 """ - w = sum(len(F) * (len(self.matroid().groundset()) - len(F)) * gen - for F, gen in self.defining_ideal().flat_to_generator_dict().items()) + w = sum(len(F) * (len(self.matroid().groundset()) - len(F)) * gen + for F, gen in self.defining_ideal().flats_to_generator_dict().items()) return self.ElementClass(self,w) @cached_method diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 88747e7673a..5f80d6de42f 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -68,7 +68,7 @@ def flats_to_generator_dict(self): {frozenset({0}): A0, frozenset({1}): A1, frozenset({2}): A2, frozenset({3}): A3, frozenset({4}): A4, frozenset({5}): A5, frozenset({0, 1}): A01, frozenset({0, 2}): A02, - frozenset({0, 3}): A03, frozenset({0, 4}): A04, + frozenset({0, 3}): A03, frozenset({0, 4}): A04, frozenset({0, 5}): A05, frozenset({1, 2}): A12, frozenset({1, 3}): A13, frozenset({1, 4}): A14, frozenset({1, 5}): A15, frozenset({2, 3}): A23, @@ -90,6 +90,7 @@ def flats_to_generator_dict(self): flats_gen = self._flats_generator return flats_gen + class ChowRingIdeal_nonaug(ChowRingIdeal): r""" The Chow ring ideal of a matroid `M`. From e1039a9bd384b127947765d67ad4f8a4ca1b60cc Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 4 Jan 2025 12:55:06 +0530 Subject: [PATCH 104/175] Debugged lefschetz_element() --- src/sage/matroids/chow_ring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 2d00b04f312..7dca223bb40 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -310,7 +310,7 @@ def lefschetz_element(self): """ w = sum(len(F) * (len(self.matroid().groundset()) - len(F)) * gen for F, gen in self.defining_ideal().flats_to_generator_dict().items()) - return self.ElementClass(self,w) + return self.element_class(self, w) @cached_method def poincare_pairing(self, el1, el2): From de240016a911f6f63574df7764288860ddb4cfd8 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sat, 4 Jan 2025 10:01:22 +0100 Subject: [PATCH 105/175] Fix tests with scipy 1.15 Increase numerical tolerance in one test, and replace usage of deprecated `sph_harm` in another one --- src/sage/functions/special.py | 9 +++++++-- src/sage/matrix/matrix2.pyx | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index 308171af3cd..f511190aeff 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -216,11 +216,16 @@ class SphericalHarmonic(BuiltinFunction): sage: spherical_harmonic(1, 1, pi/2, pi).n() # abs tol 1e-14 # needs sage.symbolic 0.345494149471335 - sage: from scipy.special import sph_harm # NB: arguments x and y are swapped # needs scipy sage: import numpy as np # needs scipy sage: if int(np.version.short_version[0]) > 1: # needs scipy ....: np.set_printoptions(legacy="1.25") # needs scipy - sage: sph_harm(1, 1, pi.n(), (pi/2).n()) # abs tol 1e-14 # needs scipy sage.symbolic + sage: import scipy.version + sage: if scipy.version.version < '1.15.0': + ....: from scipy.special import sph_harm # NB: arguments x and y are swapped # needs scipy + ....: sph_harm(1, 1, pi.n(), (pi/2).n()) # abs tol 1e-14 # needs scipy sage.symbolic + ....: else: + ....: from scipy.special import sph_harm_y # needs scipy + ....: sph_harm_y(1, 1, (pi/2).n(), pi.n()).item() # abs tol 1e-9 # needs scipy sage.symbolic (0.3454941494713355-4.231083042742082e-17j) Note that this convention differs from the one in Maxima, as revealed by diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index dec25a76e54..31aaf8b8234 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -15901,7 +15901,7 @@ cdef class Matrix(Matrix1): sage: a.exp() # needs sage.symbolic [ 1/11882424341266*((11*sqrt(227345670387496707609) + 5941212170633)*e^(3/1275529100*sqrt(227345670387496707609)) - 11*sqrt(227345670387496707609) + 5941212170633)*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200) 445243650/75781890129165569203*(sqrt(227345670387496707609)*e^(3/1275529100*sqrt(227345670387496707609)) - sqrt(227345670387496707609))*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200)] [ 10000/53470909535697*(sqrt(227345670387496707609)*e^(3/1275529100*sqrt(227345670387496707609)) - sqrt(227345670387496707609))*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200) -1/11882424341266*((11*sqrt(227345670387496707609) - 5941212170633)*e^(3/1275529100*sqrt(227345670387496707609)) - 11*sqrt(227345670387496707609) - 5941212170633)*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200)] - sage: a.change_ring(RDF).exp() # rel tol 6e-14 # needs sage.symbolic + sage: a.change_ring(RDF).exp() # rel tol 1e-13 # needs sage.symbolic [42748127.31532951 7368259.244159399] [234538976.1381042 40426191.45156228] From 8acd265fb015913d70494aa7c0740e76d58d59a7 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sat, 4 Jan 2025 17:55:37 +0800 Subject: [PATCH 106/175] Remove old deprecations in `algebras` and `categories` --- src/sage/algebras/algebra.py | 40 ---------------------------------- src/sage/algebras/meson.build | 1 - src/sage/categories/modules.py | 26 ++++------------------ 3 files changed, 4 insertions(+), 63 deletions(-) delete mode 100644 src/sage/algebras/algebra.py diff --git a/src/sage/algebras/algebra.py b/src/sage/algebras/algebra.py deleted file mode 100644 index 8d9395a3176..00000000000 --- a/src/sage/algebras/algebra.py +++ /dev/null @@ -1,40 +0,0 @@ -# sage.doctest: needs sage.combinat sage.modules -""" -Abstract base class for algebras -""" - -#***************************************************************************** -# Copyright (C) 2005 William Stein -# -# Distributed under the terms of the GNU General Public License (GPL) -# -# This code is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# The full text of the GPL is available at: -# -# http://www.gnu.org/licenses/ -#***************************************************************************** - -from sage.categories.algebras import Algebras - - -def is_Algebra(x): - r""" - Return ``True`` if `x` is an Algebra. - - EXAMPLES:: - - sage: from sage.algebras.algebra import is_Algebra - sage: R. = FreeAlgebra(QQ,2) - sage: is_Algebra(R) - doctest:warning... - DeprecationWarning: the function is_Algebra is deprecated; use '... in Algebras(base_ring)' instead - See https://github.com/sagemath/sage/issues/35253 for details. - True - """ - from sage.misc.superseded import deprecation - deprecation(35253, "the function is_Algebra is deprecated; use '... in Algebras(base_ring)' instead") - return x in Algebras(x.base_ring()) diff --git a/src/sage/algebras/meson.build b/src/sage/algebras/meson.build index d3483851743..bad93c41abf 100644 --- a/src/sage/algebras/meson.build +++ b/src/sage/algebras/meson.build @@ -1,7 +1,6 @@ py.install_sources( '__init__.py', 'affine_nil_temperley_lieb.py', - 'algebra.py', 'all.py', 'askey_wilson.py', 'associated_graded.py', diff --git a/src/sage/categories/modules.py b/src/sage/categories/modules.py index f9bc036910f..0f7ec03001a 100644 --- a/src/sage/categories/modules.py +++ b/src/sage/categories/modules.py @@ -967,16 +967,10 @@ def construction(self): (Free Algebra on 2 generators (None0, None1) over Rational Field, Free Algebra on 2 generators (None0, None1) over Rational Field)) """ - try: - factors = self.tensor_factors() - except (TypeError, NotImplementedError): - from sage.misc.superseded import deprecation - deprecation(34393, "implementations of Modules().TensorProducts() now must define the method tensor_factors") - return None - return (TensorProductFunctor(), - factors) - - @abstract_method(optional=True) + factors = self.tensor_factors() + return (TensorProductFunctor(), factors) + + @abstract_method def tensor_factors(self): """ Return the tensor factors of this tensor product. @@ -992,16 +986,4 @@ def tensor_factors(self): F # G sage: T.tensor_factors() (F, G) - - TESTS:: - - sage: Cat = ModulesWithBasis(ZZ).FiniteDimensional().TensorProducts() - sage: M = CombinatorialFreeModule(ZZ, # needs sage.modules - ....: ((1, 1), (1, 2), (2, 1), (2, 2)), - ....: category=Cat) - sage: M.construction() # needs sage.modules - doctest:warning... - DeprecationWarning: implementations of Modules().TensorProducts() now must define the method tensor_factors - See https://github.com/sagemath/sage/issues/34393 for details. - (VectorFunctor, Integer Ring) """ From 814c92b4664385c6368ec312fe21e24422fdb63a Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 4 Jan 2025 11:37:06 +0100 Subject: [PATCH 107/175] add parameter immutable to some digraph generators --- src/sage/graphs/digraph_generators.py | 200 ++++++++++++++++---------- 1 file changed, 125 insertions(+), 75 deletions(-) diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index b374392163e..f1754134778 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -150,6 +150,9 @@ class DiGraphGenerators: dense data structure. See the documentation of :class:`~sage.graphs.graph.Graph`. + - ``immutable`` -- boolean (default: ``False``); whether to return immutable + or mutable digraphs. + EXAMPLES: Print digraphs on 2 or less vertices:: @@ -203,7 +206,7 @@ class DiGraphGenerators: 218 """ - def ButterflyGraph(self, n, vertices='strings'): + def ButterflyGraph(self, n, vertices='strings', immutable=False): r""" Return a `n`-dimensional butterfly graph. @@ -223,6 +226,9 @@ def ButterflyGraph(self, n, vertices='strings'): vertices are zero-one strings (default) or tuples over GF(2) (``vertices='vectors'``) + - ``immutable`` -- boolean (default: ``False``); whether to return + an immutable or mutable digraph. + EXAMPLES:: sage: digraphs.ButterflyGraph(2).edges(sort=True, labels=False) @@ -323,9 +329,10 @@ def ButterflyGraph(self, n, vertices='strings'): for x in range(n + 1): pos[v, x] = (dec * x, i) return DiGraph([pos.keys(), E], format='vertices_and_edges', pos=pos, - name="{}-dimensional Butterfly".format(n)) + name="{}-dimensional Butterfly".format(n), + immutable=immutable) - def Path(self, n): + def Path(self, n, immutable=False): r""" Return a directed path on `n` vertices. @@ -333,6 +340,9 @@ def Path(self, n): - ``n`` -- integer; number of vertices in the path + - ``immutable`` -- boolean (default: ``False``); whether to return + an immutable or mutable digraph. + EXAMPLES:: sage: g = digraphs.Path(5) @@ -343,15 +353,13 @@ def Path(self, n): sage: g.automorphism_group().cardinality() # needs sage.groups 1 """ - g = DiGraph(n, name='Path') - - if n: - g.add_path(list(range(n))) - + g = DiGraph([range(n), zip(range(n - 1), range(1, n))], + format='vertices_and_edges', name='Path', + immutable=immutable) g.set_pos({i: (i, 0) for i in range(n)}) return g - def StronglyRegular(self, n): + def StronglyRegular(self, n, immutable=False): r""" Return a Strongly Regular digraph with `n` vertices. @@ -362,6 +370,9 @@ def StronglyRegular(self, n): - ``n`` -- integer; the number of vertices of the digraph + - ``immutable`` -- boolean (default: ``False``); whether to return + an immutable or mutable digraph. + .. SEEALSO:: - :func:`sage.combinat.matrices.hadamard_matrix.skew_hadamard_matrix` @@ -397,15 +408,23 @@ def StronglyRegular(self, n): H = skew_hadamard_matrix(n + 1, skew_normalize=True) M = H[1:, 1:] M = (M + ones_matrix(n)) / 2 - identity_matrix(n) - return DiGraph(M, format='adjacency_matrix', name='Strongly regular digraph') + return DiGraph(M, format='adjacency_matrix', immutable=immutable, + name='Strongly regular digraph') - def Paley(self, q): + def Paley(self, q, immutable=False): r""" Return a Paley digraph on `q` vertices. Parameter `q` must be the power of a prime number and congruent to 3 mod 4. + INPUT: + + - ``q`` -- integer; the number of vertices of the digraph + + - ``immutable`` -- boolean (default: ``False``); whether to return + an immutable or mutable digraph. + .. SEEALSO:: - :wikipedia:`Paley_graph` @@ -448,13 +467,12 @@ def Paley(self, q): raise ValueError("parameter q must be a prime power") if not mod(q, 4) == 3: raise ValueError("parameter q must be congruent to 3 mod 4") - g = DiGraph([FiniteField(q, 'a'), - lambda i, j: (i != j) and (j - i).is_square()], - loops=False, - name="Paley digraph with parameter {}".format(q)) - return g + return DiGraph([FiniteField(q, 'a'), + lambda i, j: (i != j) and (j - i).is_square()], + format='rule', loops=False, immutable=immutable, + name="Paley digraph with parameter {}".format(q)) - def TransitiveTournament(self, n): + def TransitiveTournament(self, n, immutable=False): r""" Return a transitive tournament on `n` vertices. @@ -466,6 +484,9 @@ def TransitiveTournament(self, n): - ``n`` -- integer; number of vertices in the tournament + - ``immutable`` -- boolean (default: ``False``); whether to return + an immutable or mutable digraph. + EXAMPLES:: sage: g = digraphs.TransitiveTournament(5) @@ -490,17 +511,17 @@ def TransitiveTournament(self, n): ... ValueError: the number of vertices cannot be strictly negative """ - g = DiGraph(n, name="Transitive Tournament") - - for i in range(n - 1): - for j in range(i + 1, n): - g.add_edge(i, j) + if n < 0: + raise ValueError('the number of vertices cannot be strictly negative') + from itertools import combinations + g = DiGraph([range(n), combinations(range(n), 2)], + format='vertices_and_edges', immutable=immutable, + name="Transitive Tournament") g._circle_embedding(list(range(n))) - return g - def RandomTournament(self, n): + def RandomTournament(self, n, immutable=False): r""" Return a random tournament on `n` vertices. @@ -512,6 +533,9 @@ def RandomTournament(self, n): - ``n`` -- integer; number of vertices + - ``immutable`` -- boolean (default: ``False``); whether to return + an immutable or mutable digraph. + EXAMPLES:: sage: T = digraphs.RandomTournament(10); T @@ -533,15 +557,17 @@ def RandomTournament(self, n): - :meth:`~sage.graphs.digraph_generators.DiGraphGenerators.Complete` - :meth:`~sage.graphs.digraph_generators.DiGraphGenerators.RandomSemiComplete` """ - from sage.misc.prandom import random - g = DiGraph(n, name="Random Tournament") + if n < 0: + raise ValueError('the number of vertices cannot be strictly negative') - for i in range(n - 1): - for j in range(i + 1, n): - if random() <= .5: - g.add_edge(i, j) - else: - g.add_edge(j, i) + from itertools import combinations + from sage.misc.prandom import getrandbits + + bits = getrandbits(n * (n - 1) // 2) + edges = ((i, j) if (bits >> k) & 1 else (j, i) + for k, (i, j) in enumerate(combinations(range(n), 2))) + g = DiGraph([range(n), edges], format='vertices_and_edges', + immutable=immutable, name="Random Tournament") g._circle_embedding(list(range(n))) @@ -549,7 +575,8 @@ def RandomTournament(self, n): def tournaments_nauty(self, n, min_out_degree=None, max_out_degree=None, - strongly_connected=False, debug=False, options=""): + strongly_connected=False, debug=False, options="", + immutable=False): r""" Iterator over all tournaments on `n` vertices using Nauty. @@ -571,6 +598,9 @@ def tournaments_nauty(self, n, to Nauty's gentourng. See its documentation for more information : ``_. + - ``immutable`` -- boolean (default: ``False``); whether to return + immutable or mutable digraphs. + EXAMPLES:: sage: for g in digraphs.tournaments_nauty(4): @@ -612,22 +642,11 @@ def tournaments_nauty(self, n, if debug: yield sp.stderr.readline() - gen = sp.stdout - while True: - try: - s = bytes_to_str(next(gen)) - except StopIteration: - # Exhausted list of graphs from nauty geng - return - - G = DiGraph(n) + def edges(s): i = 0 j = 1 for b in s[:-1]: - if b == '0': - G.add_edge(i, j) - else: - G.add_edge(j, i) + yield (i, j) if b == '0' else (j, i) if j == n - 1: i += 1 @@ -635,9 +654,18 @@ def tournaments_nauty(self, n, else: j += 1 - yield G + gen = sp.stdout + while True: + try: + s = bytes_to_str(next(gen)) + except StopIteration: + # Exhausted list of graphs from nauty geng + return + + yield DiGraph([range(n), edges(s)], format='vertices_and_edges', + immutable=immutable) - def nauty_directg(self, graphs, options='', debug=False): + def nauty_directg(self, graphs, options='', debug=False, immutable=False): r""" Return an iterator yielding digraphs using nauty's ``directg`` program. @@ -669,6 +697,9 @@ def nauty_directg(self, graphs, options='', debug=False): - ``debug`` -- boolean (default: ``False``); if ``True`` ``directg`` standard error and standard output are displayed + - ``immutable`` -- boolean (default: ``False``); whether to return + immutable or mutable digraphs. + EXAMPLES:: sage: gen = graphs.nauty_geng("-c 3") @@ -759,9 +790,9 @@ def nauty_directg(self, graphs, options='', debug=False): # digraph6 specifications: # http://users.cecs.anu.edu.au/~bdm/data/formats.txt if line and line[0] == '&': - yield DiGraph(line[1:], format='dig6') + yield DiGraph(line[1:], format='dig6', immutable=immutable) - def nauty_posetg(self, options='', debug=False): + def nauty_posetg(self, options='', debug=False, immutable=False): r""" Return a generator which creates all posets using ``nauty``. @@ -782,6 +813,9 @@ def nauty_posetg(self, options='', debug=False): the program with some information on the arguments, while a line beginning with ">E" indicates an error with the input. + - ``immutable`` -- boolean (default: ``False``); whether to return + immutable or mutable posets. + The possible options, obtained as output of ``genposetg --help``:: n: the number of vertices, between 0 and 16 @@ -815,10 +849,9 @@ def nauty_posetg(self, options='', debug=False): except StopIteration: # Exhausted list of graphs from nauty genposetg return - G = DiGraph(s[1:-1], format='dig6') - yield G + yield DiGraph(s[1:-1], format='dig6', immutable=immutable) - def Complete(self, n, loops=False): + def Complete(self, n, loops=False, immutable=False): r""" Return the complete digraph on `n` vertices. @@ -829,6 +862,9 @@ def Complete(self, n, loops=False): - ``loops`` -- boolean (default: ``False``); whether to add loops or not, i.e., edges from `u` to itself + - ``immutable`` -- boolean (default: ``False``); whether to return + an immutable or mutable digraph. + .. SEEALSO:: - :meth:`~sage.graphs.digraph_generators.DiGraphGenerators.RandomSemiComplete` @@ -851,24 +887,32 @@ def Complete(self, n, loops=False): ... ValueError: the number of vertices cannot be strictly negative """ - G = DiGraph(n, name="Complete digraph" + (" with loops" if loops else ''), loops=loops) - - if loops: - G.add_edges((u, u) for u in range(n)) + if n < 0: + raise ValueError('the number of vertices cannot be strictly negative') - G.add_edges((u, v) for u in range(n) for v in range(n) if u != v) + edges = ((u, v) for u in range(n) for v in range(n) if u != v or loops) + G = DiGraph([range(n), edges], format='vertices_and_edges', + loops=loops, immutable=immutable, + name="Complete digraph" + (" with loops" if loops else '')) G._circle_embedding(list(range(n))) return G - def Circuit(self, n): + def Circuit(self, n, immutable=False): r""" Return the circuit on `n` vertices. The circuit is an oriented :meth:`~sage.graphs.graph_generators.GraphGenerators.CycleGraph`. + INPUT: + + - ``n`` -- integer; number of vertices + + - ``immutable`` -- boolean (default: ``False``); whether to return + an immutable or mutable digraph. + EXAMPLES: A circuit is the smallest strongly connected digraph:: @@ -877,19 +921,20 @@ def Circuit(self, n): sage: len(circuit.strongly_connected_components()) == 1 True """ - g = DiGraph(n, name='Circuit') - + if n < 0: + raise ValueError('the number of vertices cannot be strictly negative') if n == 1: - g.allow_loops(True) - g.add_edge(0, 0) - return g - elif n: - g.add_edges(zip(range(n - 1), range(1, n))) - g.add_edge(n - 1, 0) - g._circle_embedding(list(range(n))) + return DiGraph([(0, 0)], format='list_of_edges', loops=True, + immutable=immutable, name='Circuit') + + from itertools import chain + edges = zip(range(n), chain(range(1, n), [0])) + g = DiGraph([range(n), edges], format='vertices_and_edges', + immutable=immutable, name='Circuit') + g._circle_embedding(list(range(n))) return g - def Circulant(self, n, integers): + def Circulant(self, n, integers, immutable=False): r""" Return a circulant digraph on `n` vertices from a set of integers. @@ -904,6 +949,9 @@ def Circulant(self, n, integers): that there is an edge from `i` to `j` if and only if `(j-i) \pmod{n}` is an integer + - ``immutable`` -- boolean (default: ``False``); whether to return + an immutable or mutable digraph. + EXAMPLES: Construct and show the circulant graph [3, 5, 7], a digraph on 13 @@ -942,15 +990,14 @@ def Circulant(self, n, integers): if not i % n: loops = True - G = DiGraph(n, name="Circulant graph (" + str(integers) + ")", loops=loops) - + edges = ((v, (v + j) % n) for j in integers for v in range(n)) + G = DiGraph([range(n), edges], format='vertices_and_edges', + loops=loops, immutable=immutable, + name="Circulant graph (" + str(integers) + ")") G._circle_embedding(list(range(n))) - for v in range(n): - G.add_edges((v, (v + j) % n) for j in integers) - return G - def DeBruijn(self, k, n, vertices='strings'): + def DeBruijn(self, k, n, vertices='strings', immutable=False): r""" Return the De Bruijn digraph with parameters `k,n`. @@ -977,6 +1024,9 @@ def DeBruijn(self, k, n, vertices='strings'): are words over an alphabet (default) or integers (``vertices='string'``) + - ``immutable`` -- boolean (default: ``False``); whether to return + an immutable or mutable digraph. + EXAMPLES: de Bruijn digraph of degree 2 and diameter 2:: From 964010014b8cbe4f829310a92f3101da8db9db88 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 4 Jan 2025 11:48:11 +0100 Subject: [PATCH 108/175] #39264: revert a change --- src/sage/graphs/digraph_generators.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index f1754134778..d484b948eb7 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -150,9 +150,6 @@ class DiGraphGenerators: dense data structure. See the documentation of :class:`~sage.graphs.graph.Graph`. - - ``immutable`` -- boolean (default: ``False``); whether to return immutable - or mutable digraphs. - EXAMPLES: Print digraphs on 2 or less vertices:: @@ -997,7 +994,7 @@ def Circulant(self, n, integers, immutable=False): G._circle_embedding(list(range(n))) return G - def DeBruijn(self, k, n, vertices='strings', immutable=False): + def DeBruijn(self, k, n, vertices='strings'): r""" Return the De Bruijn digraph with parameters `k,n`. @@ -1024,9 +1021,6 @@ def DeBruijn(self, k, n, vertices='strings', immutable=False): are words over an alphabet (default) or integers (``vertices='string'``) - - ``immutable`` -- boolean (default: ``False``); whether to return - an immutable or mutable digraph. - EXAMPLES: de Bruijn digraph of degree 2 and diameter 2:: From 1e32894c6baf6a9433e9d102fd9f1122ad88c753 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 4 Jan 2025 15:46:47 +0100 Subject: [PATCH 109/175] fix issue #39270 --- .../graphs/base/static_sparse_backend.pyx | 101 ++++++++++++++++-- 1 file changed, 94 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/base/static_sparse_backend.pyx b/src/sage/graphs/base/static_sparse_backend.pyx index e51fc238ac5..62bce67f5c0 100644 --- a/src/sage/graphs/base/static_sparse_backend.pyx +++ b/src/sage/graphs/base/static_sparse_backend.pyx @@ -557,9 +557,28 @@ cdef class StaticSparseBackend(CGraphBackend): """ return v in self._vertex_to_int + def add_vertex(self, object v): + r""" + Add a vertex to the graph. No way + + INPUT: + + - ``v`` -- a vertex (or not?) + + TESTS:: + + sage: from sage.graphs.base.static_sparse_backend import StaticSparseBackend + sage: g = StaticSparseBackend(graphs.PetersenGraph()) + sage: g.add_vertex(123) + Traceback (most recent call last): + ... + ValueError: graph is immutable; please change a copy instead (use function copy()) + """ + raise ValueError("graph is immutable; please change a copy instead (use function copy())") + cpdef add_edge(self, object u, object v, object l, bint directed): r""" - Set edge label. No way. + Add an edge to the graph. No way. TESTS:: @@ -572,9 +591,13 @@ cdef class StaticSparseBackend(CGraphBackend): """ raise ValueError("graph is immutable; please change a copy instead (use function copy())") - def add_edges(self, edges, directed): + def add_edges(self, edges, directed, remove_loops=False): r""" - Set edge label. No way. + Add edges to the graph. No way. + + INPUT: + + - ``edges`` -- a list of edges (or not?) TESTS:: @@ -589,7 +612,11 @@ cdef class StaticSparseBackend(CGraphBackend): def add_vertices(self, vertices): r""" - Set edge label. No way. + Add vertices to the graph. No way. + + INPUT: + + - ``vertices`` -- a list of vertices (or not?) TESTS:: @@ -602,15 +629,75 @@ cdef class StaticSparseBackend(CGraphBackend): """ raise ValueError("graph is immutable; please change a copy instead (use function copy())") - cpdef del_edge(self, object u, object v, object l, bint directed): + def del_vertex(self, object v): r""" - Set edge label. No way. + Delete a vertex from the graph. No way + + INPUT: + + - ``v`` -- a vertex (or not?) TESTS:: sage: from sage.graphs.base.static_sparse_backend import StaticSparseBackend sage: g = StaticSparseBackend(graphs.PetersenGraph()) - sage: g.set_edge_label(1,2,3,True) + sage: g.del_vertex(123) + Traceback (most recent call last): + ... + ValueError: graph is immutable; please change a copy instead (use function copy()) + + Check that :issue:`39270` is fixed:: + + sage: g.del_vertex('a') + Traceback (most recent call last): + ... + ValueError: graph is immutable; please change a copy instead (use function copy()) + """ + raise ValueError("graph is immutable; please change a copy instead (use function copy())") + + def del_vertices(self, vertices): + r""" + Delete vertices from the graph. No way + + INPUT: + + - ``vertices`` -- a list of vertices (or not?) + + TESTS:: + + sage: from sage.graphs.base.static_sparse_backend import StaticSparseBackend + sage: g = StaticSparseBackend(graphs.PetersenGraph()) + sage: g.del_vertices([123, 234]) + Traceback (most recent call last): + ... + ValueError: graph is immutable; please change a copy instead (use function copy()) + """ + raise ValueError("graph is immutable; please change a copy instead (use function copy())") + + def del_edge(self, object u, object v, object l, bint directed): + r""" + Delete an edge of the graph. No way. + + TESTS:: + + sage: from sage.graphs.base.static_sparse_backend import StaticSparseBackend + sage: g = StaticSparseBackend(graphs.PetersenGraph()) + sage: g.del_edge(1,2,3,True) + Traceback (most recent call last): + ... + ValueError: graph is immutable; please change a copy instead (use function copy()) + """ + raise ValueError("graph is immutable; please change a copy instead (use function copy())") + + def del_edges(self, edges, directed): + r""" + Delete edges of the graph. No way. + + TESTS:: + + sage: from sage.graphs.base.static_sparse_backend import StaticSparseBackend + sage: g = StaticSparseBackend(graphs.PetersenGraph()) + sage: g.del_edges([[1,2,3]], True) Traceback (most recent call last): ... ValueError: graph is immutable; please change a copy instead (use function copy()) From 43f897364b38f26296980329febad783b2e25269 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 4 Jan 2025 22:28:41 +0530 Subject: [PATCH 110/175] Edited doctests --- src/sage/categories/kahler_algebras.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 3aa00cfaee6..6ef68a62f33 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -70,7 +70,7 @@ class KahlerAlgebras(Category_over_base_ring): Category of kahler algebras over Rational Field sage: sorted(C.super_categories(), key=str) [Category of finite dimensional algebras with basis over Rational - Field, Category of graded algebras with basis over Rational Field] + Field] TESTS:: From 56cbf63e49f95ba7d4ae4f5f65711ba0ec1de1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 4 Jan 2025 20:15:27 +0100 Subject: [PATCH 111/175] fix and activate the ruff check for F811 --- src/sage/algebras/weyl_algebra.py | 1 - src/sage/categories/basic.py | 1 - src/sage/coding/guruswami_sudan/gs_decoder.py | 7 +++---- src/sage/modules/with_basis/representation.py | 1 - src/sage/rings/finite_rings/integer_mod_ring.py | 3 +-- src/sage/rings/polynomial/polynomial_ring.py | 1 - src/sage/schemes/curves/affine_curve.py | 1 - src/sage/schemes/elliptic_curves/ell_point.py | 2 -- src/sage/symbolic/expression_conversions.py | 4 +--- src/tox.ini | 2 +- 10 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/sage/algebras/weyl_algebra.py b/src/sage/algebras/weyl_algebra.py index dc7cbef3058..b5554d901f5 100644 --- a/src/sage/algebras/weyl_algebra.py +++ b/src/sage/algebras/weyl_algebra.py @@ -21,7 +21,6 @@ from sage.misc.latex import latex, LatexExpr from sage.misc.lazy_attribute import lazy_attribute from sage.misc.misc_c import prod -from sage.structure.element import Element from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation from sage.categories.action import Action diff --git a/src/sage/categories/basic.py b/src/sage/categories/basic.py index cfc385513cb..30c4b0fa9e7 100644 --- a/src/sage/categories/basic.py +++ b/src/sage/categories/basic.py @@ -47,7 +47,6 @@ from sage.categories.principal_ideal_domains import PrincipalIdealDomains from sage.categories.euclidean_domains import EuclideanDomains from sage.categories.unique_factorization_domains import UniqueFactorizationDomains -from sage.categories.complete_discrete_valuation import CompleteDiscreteValuationRings from sage.categories.fields import Fields from sage.categories.quotient_fields import QuotientFields diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index e909c3a0bf3..3df7b5c1884 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -14,7 +14,7 @@ - David Lucas, ported the original implementation in Sage """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2015 David Lucas # 2015 Johan S. R. Nielsen # @@ -22,10 +22,9 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** -from sage.arith.misc import integer_floor as floor from sage.coding.grs_code import GeneralizedReedSolomonCode from sage.rings.integer_ring import ZZ from sage.coding.decoder import Decoder diff --git a/src/sage/modules/with_basis/representation.py b/src/sage/modules/with_basis/representation.py index 3bdcc165692..61e65409e21 100644 --- a/src/sage/modules/with_basis/representation.py +++ b/src/sage/modules/with_basis/representation.py @@ -21,7 +21,6 @@ from sage.misc.cachefunc import cached_method from sage.structure.element import Element from sage.combinat.free_module import CombinatorialFreeModule, CombinatorialFreeModule_Tensor -from sage.modules.with_basis.subquotient import SubmoduleWithBasis from sage.categories.modules import Modules from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 893fde4e929..6d5b7c6b36c 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -69,7 +69,6 @@ from sage.arith.misc import CRT_basis from sage.rings.ring import Field, CommutativeRing from sage.misc.mrange import cartesian_product_iterator -import sage.rings.ring as ring import sage.rings.abc from sage.rings.finite_rings import integer_mod import sage.rings.integer as integer @@ -2030,7 +2029,7 @@ def crt(v): 1027 """ if len(v) == 0: - return IntegerModRing(1)(1) + return IntegerModRing(1).one() x = v[0] for i in range(1, len(v)): x = x.crt(v[i]) diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 6be288de70f..1d98f3db11f 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -230,7 +230,6 @@ def is_PolynomialRing(x): sage: type(R) """ - from sage.misc.superseded import deprecation deprecation(38266, "The function is_PolynomialRing is deprecated; " "use 'isinstance(..., PolynomialRing_generic)' instead.") diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py index 0b647c8411b..127530a9bb7 100644 --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -141,7 +141,6 @@ from sage.rings.polynomial.multi_polynomial_element import degree_lowest_rational_function from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import RationalField -from sage.rings.infinity import infinity from sage.schemes.affine.affine_space import AffineSpace, AffineSpace_generic from sage.schemes.affine.affine_subscheme import (AlgebraicScheme_subscheme_affine, diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index d05196240a1..9bac016fe3a 100644 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -140,10 +140,8 @@ from sage.rings.integer_ring import ZZ from sage.rings.padics.precision_error import PrecisionError from sage.rings.rational_field import QQ -from sage.rings.finite_rings.integer_mod import Mod from sage.rings.real_mpfr import RealField, RR from sage.rings.quotient_ring import QuotientRing_generic -import sage.groups.generic as generic from sage.structure.element import AdditiveGroupElement from sage.structure.sequence import Sequence diff --git a/src/sage/symbolic/expression_conversions.py b/src/sage/symbolic/expression_conversions.py index 2d59c66293c..0a2b25d4a8a 100644 --- a/src/sage/symbolic/expression_conversions.py +++ b/src/sage/symbolic/expression_conversions.py @@ -23,7 +23,7 @@ from sage.misc.lazy_import import lazy_import from sage.symbolic.ring import SR from sage.structure.element import Expression -from sage.functions.all import exp +from sage.functions.log import exp from sage.symbolic.operators import arithmetic_operators, relation_operators, FDerivativeOperator, add_vararg, mul_vararg from sage.rings.number_field.number_field_element_base import NumberFieldElement_base from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField @@ -1651,7 +1651,6 @@ class Exponentialize(ExpressionTreeWalker): # the same canned results dictionary at each call. from sage.calculus.var import function from sage.functions.hyperbolic import sinh, cosh, sech, csch, tanh, coth - from sage.functions.log import exp from sage.functions.trig import sin, cos, sec, csc, tan, cot from sage.rings.integer import Integer from sage.symbolic.constants import e, I @@ -1749,7 +1748,6 @@ def composition(self, ex, op): sage: s.composition(q, q.operator()) (cos(b) + I*sin(b))*e^a """ - from sage.functions.log import exp if op is not exp: # return super().composition(ex, op) return op(*[self(oper) for oper in ex.operands()]) diff --git a/src/tox.ini b/src/tox.ini index d99936f09a9..29dd3fcaa15 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -311,7 +311,7 @@ passenv = RUFF_OUTPUT_FORMAT # 1 F402 [ ] Import `factor` from line 259 shadowed by loop variable # 1 PLC0208 [*] Use a sequence type instead of a `set` when iterating over values # -commands = ruff check --ignore 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/} +commands = ruff check --ignore E402,E721,E731,E741,E742,E743,F401,F402,F403,F405,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 9a73e16ad3cf8f1df9324e3f1551882840de94c1 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 5 Jan 2025 10:29:36 +0700 Subject: [PATCH 112/175] Fix tests for Python 3.13 --- src/sage/repl/ipython_extension.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index 9f705d863b8..05468142142 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -433,8 +433,8 @@ def cython(self, line, cell): sage: shell.run_cell(''' ....: %%cython --view-annotate=xx ....: print(1) - ....: ''') - UsageError: argument --view-annotate: invalid choice: 'xx' (choose from 'none', 'auto', 'webbrowser', 'displayhtml') + ....: ''') # exact error message differ between Python 3.11/3.13 + UsageError: argument --view-annotate: invalid choice: 'xx' (choose from ...) Test ``--view-annotate=displayhtml`` (note that in a notebook environment an inline HTML frame will be displayed):: From 1803510ccb658ecab37c6d673bad7edcf3c7d244 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 5 Jan 2025 19:58:50 +0800 Subject: [PATCH 113/175] Remove failing modular ci tests --- .github/workflows/build.yml | 102 +----------------------------------- 1 file changed, 2 insertions(+), 100 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 535c2948c39..bbecdf481b6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,7 +29,7 @@ concurrency: # # The three workflows: # -# - build.yml (with jobs test-new, test-mod, test-long), +# - build.yml (with jobs test-new, test-long), # - doc-build.yml, # - doc-build-pdf.yml # @@ -50,7 +50,7 @@ concurrency: # This baseline is transparently improved by our use of the GH Actions cache, # see https://docs.docker.com/build/ci/github-actions/cache/#cache-backend-api. # -# Jobs test-mod and test-long are only started after test-new completed; +# Jobs test-long is only started after test-new completed; # but the workflows doc-build.yml and doc-build-pdf.yml are started independently. # # - When nothing is cached and the 3 workflows are launched in parallel, @@ -254,104 +254,6 @@ jobs: ./sage -t --long --format github -p4 ${{ steps.changed-files.outputs.doctests_all_changed_files }} shell: sh .ci/docker-exec-script.sh BUILD /sage {0} - test-mod: - runs-on: ubuntu-latest - needs: [test-new] - services: - # https://docs.docker.com/build/ci/github-actions/local-registry/ - registry: - image: registry:2 - ports: - - 5000:5000 - strategy: - fail-fast: false - matrix: - targets: - - sagemath_categories-check - steps: - - name: Maximize build disk space - uses: easimon/maximize-build-space@v10 - with: - # need space in /var for Docker images - root-reserve-mb: 30000 - remove-dotnet: true - remove-android: true - remove-haskell: true - remove-codeql: true - remove-docker-images: true - - - name: Checkout - id: checkout - uses: actions/checkout@v4 - - - name: Install test prerequisites - # From docker.yml - run: | - sudo DEBIAN_FRONTEND=noninteractive apt-get update - sudo DEBIAN_FRONTEND=noninteractive apt-get install tox - sudo apt-get clean - df -h - - - name: Merge CI fixes from sagemath/sage - # From docker.yml - # This step needs to happen after the commit sha is put in DOCKER_TAG - # so that multi-stage builds can work correctly. - run: | - .ci/merge-fixes.sh - env: - GH_TOKEN: ${{ github.token }} - - # Building - - - name: Generate Dockerfile - # From docker.yml - run: | - tox -e ${{ env.TOX_ENV }} - cp .tox/${{ env.TOX_ENV }}/Dockerfile . - env: - # Only generate the Dockerfile, do not run 'docker build' here - DOCKER_TARGETS: "" - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - driver-opts: network=host - - - name: Build Docker image - id: image - uses: docker/build-push-action@v6 - with: - push: true - load: false - context: . - tags: ${{ env.BUILD_IMAGE }} - target: with-targets - cache-from: type=gha - cache-to: type=gha,mode=max - build-args: | - NUMPROC=6 - USE_MAKEFLAGS=-k V=0 SAGE_NUM_THREADS=4 --output-sync=recurse - TARGETS_PRE=build/make/Makefile - TARGETS=${{ needs.test-new.outputs.build_targets }} - - - name: Start container - id: container - if: (success() || failure()) - run: | - docker run --name BUILD -dit \ - --mount type=bind,src=$(pwd),dst=$(pwd) \ - --workdir $(pwd) \ - ${{ env.BUILD_IMAGE }} /bin/sh - - # Testing - - - name: Test modularized distributions - if: (success() || failure()) && steps.container.outcome == 'success' - run: | - export MAKE="make -j2 --output-sync=recurse" SAGE_NUM_THREADS=4 - make V=0 tox-ensure && make ${{ matrix.targets }} - shell: sh .ci/docker-exec-script.sh BUILD /sage {0} - test-long: runs-on: ubuntu-latest needs: [test-new] From cf878ac5737af897fb43a4c1819abd1add67dc14 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sun, 5 Jan 2025 21:08:23 +0900 Subject: [PATCH 114/175] Escape specials characters in release notes --- .github/workflows/dist.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index 191fd1c8fad..b8800c8854b 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -135,6 +135,8 @@ jobs: \"tag_name\": \"${{ github.ref_name }}\", \"previous_tag_name\": \"$latest_release_tag\" }" | jq -r '.body') + # escape special characters for json + release_notes=$(jq -R -s '.' <<< "$release_notes") curl -L \ -X POST \ -H "Accept: application/vnd.github+json" \ @@ -144,7 +146,7 @@ jobs: -d "{ \"tag_name\": \"${{ github.ref_name }}\", \"prerelease\": ${{ contains(github.ref, 'beta') || contains(github.ref, 'rc') }}, - \"body\": \"$release_notes\" + \"body\": $release_notes }" - name: Create release assets uses: softprops/action-gh-release@v2 From 93dd61689bab82266e718bcfc27c7d98cf5d0b41 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 5 Jan 2025 17:40:43 +0530 Subject: [PATCH 115/175] Corrected doctests --- src/sage/categories/kahler_algebras.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 6ef68a62f33..17eeddaf142 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -69,8 +69,7 @@ class KahlerAlgebras(Category_over_base_ring): sage: C = KahlerAlgebras(QQ); C Category of kahler algebras over Rational Field sage: sorted(C.super_categories(), key=str) - [Category of finite dimensional algebras with basis over Rational - Field] + [Category of finite dimensional algebras with basis over Rational Field] TESTS:: From b9f30115feb839c6e2b5db290b75d32865f96df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Sun, 5 Jan 2025 13:06:09 -0300 Subject: [PATCH 116/175] spyx_tmp(): improve comment --- src/sage/misc/temporary_file.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/misc/temporary_file.py b/src/sage/misc/temporary_file.py index 820d5cf2e95..4e9ece019d2 100644 --- a/src/sage/misc/temporary_file.py +++ b/src/sage/misc/temporary_file.py @@ -542,7 +542,9 @@ def spyx_tmp() -> str: return _spyx_tmp # We don't use `tempfile.TemporaryDirectory()` here because it - # will be cleaned up on child exit (e.g. for parallel testing) + # is not clear when it will or will not be cleaned. Sometimes it + # might not be cleaned up at all, and starting in python 3.13 it + # might be cleaned up on child exit, breaking parallel testing. # For some reason this doesn't affect the `TemporaryDirectory` # stored in the global `TMP_DIR_FILENAME_BASE`. _spyx_tmp = tmp_dir(name='spyx_') From 44d0d2da94f578e0c1144744d56d5bc86be839b3 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 5 Jan 2025 21:37:00 +0530 Subject: [PATCH 117/175] Edited doctests --- src/sage/categories/kahler_algebras.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 17eeddaf142..02a679c4c4c 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -69,7 +69,8 @@ class KahlerAlgebras(Category_over_base_ring): sage: C = KahlerAlgebras(QQ); C Category of kahler algebras over Rational Field sage: sorted(C.super_categories(), key=str) - [Category of finite dimensional algebras with basis over Rational Field] + [Category of finite dimensional graded algebras with basis over + Rational Field] TESTS:: From 122e4403d6e4381d7e673424e87cd070c6ccdda8 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sat, 4 Jan 2025 20:32:39 +0800 Subject: [PATCH 118/175] Upgrade dependency requirements in accordance with Spec 0 --- pyproject.toml | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e2b17964399..f3f60bcd729 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ requires = [ 'cython >=3.0, != 3.0.3', 'gmpy2 ~=2.1.b999', 'memory_allocator', - 'numpy >=1.19', + 'numpy >=1.25', 'jinja2' ] [project] @@ -26,7 +26,7 @@ dependencies = [ 'gmpy2 ~=2.1.b999', 'lrcalc ~=2.1', 'memory_allocator', - 'numpy >=1.19', + 'numpy >=1.25', # Issue #30922: pplpy 0.8.4 and earlier do not declare dependencies correctly 'pplpy >=0.8.6', 'primecountpy', @@ -34,21 +34,13 @@ dependencies = [ # According to https://github.com/python/typing_extensions/blob/main/CHANGELOG.md, # version 4.4.0 adds another Python 3.11 typing backport 'typing_extensions >= 4.4.0; python_version<"3.11"', - 'ipython >=7.13.0', + 'ipython >=8.9.0', 'pexpect >=4.8.0', 'sphinx >=5.2, <9', - 'networkx >=2.4', - # 1.8 is known good version. - # Per https://docs.scipy.org/doc/scipy/dev/core-dev/index.html#version-numbering - # and https://docs.scipy.org/doc/scipy/dev/core-dev/index.html#deprecations, - # deprecations cannot be introduced in micro releases. - # SciPy devs wait "at least 6 months", "in practice two (minor) releases" - # from deprecation to removal of a feature. - 'scipy >=1.5', + 'networkx >=3.1', + 'scipy >=1.11', 'sympy >=1.6, <2.0', - # Issue #33642: Set lower bound for use of matplotlib color maps introduced in #33491, - # and to suppress deprecation warnings (https://github.com/matplotlib/matplotlib/pull/21073) - 'matplotlib >=3.5.1', + 'matplotlib >=3.7.0', 'pillow >=7.2.0', 'mpmath >=1.1.0', 'ipykernel >=5.2.1', From 854dbbd78f9599632202f040e1e4b4440e70a318 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 19 Dec 2024 10:44:42 +0800 Subject: [PATCH 119/175] Update conda to use Python 3.12, drop 3.9 and 3.10 --- .github/workflows/ci-conda.yml | 15 +- .github/workflows/ci-meson.yml | 2 +- .gitignore | 10 +- environment-3.11-linux-aarch64.yml | 249 ++++++------- environment-3.11-linux.yml | 249 ++++++------- environment-3.11-macos-x86_64.yml | 220 ++++++------ environment-3.11-macos.yml | 220 ++++++------ ....yml => environment-3.12-linux-aarch64.yml | 289 +++++++-------- ...10-linux.yml => environment-3.12-linux.yml | 289 +++++++-------- ...4.yml => environment-3.12-macos-x86_64.yml | 260 +++++++------- ...10-macos.yml => environment-3.12-macos.yml | 260 +++++++------- environment-3.9-linux-aarch64.yml | 337 ----------------- environment-3.9-linux.yml | 338 ------------------ environment-3.9-macos-x86_64.yml | 290 --------------- environment-3.9-macos.yml | 292 --------------- pyproject.toml | 8 +- tools/update-conda.py | 2 +- 17 files changed, 1044 insertions(+), 2286 deletions(-) rename environment-3.10-linux-aarch64.yml => environment-3.12-linux-aarch64.yml (54%) rename environment-3.10-linux.yml => environment-3.12-linux.yml (54%) rename environment-3.10-macos-x86_64.yml => environment-3.12-macos-x86_64.yml (52%) rename environment-3.10-macos.yml => environment-3.12-macos.yml (53%) delete mode 100644 environment-3.9-linux-aarch64.yml delete mode 100644 environment-3.9-linux.yml delete mode 100644 environment-3.9-macos-x86_64.yml delete mode 100644 environment-3.9-macos.yml diff --git a/.github/workflows/ci-conda.yml b/.github/workflows/ci-conda.yml index 23a86a25824..4b22d9669a0 100644 --- a/.github/workflows/ci-conda.yml +++ b/.github/workflows/ci-conda.yml @@ -26,23 +26,12 @@ jobs: # On pushes to tags or branches, test the whole matrix. os: >- ${{ github.event_name == 'pull_request' - && fromJson('["ubuntu-latest"]') + && fromJson('["ubuntu-latest", "macos-latest"]') || fromJson('["ubuntu-latest", "macos-latest", "macos-13"]') }} - python: >- - ${{ github.event_name == 'pull_request' - && fromJson('["3.9"]') - || fromJson('["3.9", "3.10", "3.11"]') }} + python: ['3.11', '3.12'] # Optional environment is disabled for now as its not yet working # environment: [environment, environment-optional] conda-env: [environment] - # On pull requests, only test two jobs: - # Ubuntu with Python 3.9, macOS (arm64) with Python 3.11. - # Build & Test currently uses Python 3.10 (on ubuntu-jammy). - # Together, they cover the supported minor Python versions. - include: >- - ${{ github.event_name == 'pull_request' - && fromJson('[{"os": "macos-latest", "python": "3.11", "conda-env": "environment"}]') - || fromJson('[]') }} steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/ci-meson.yml b/.github/workflows/ci-meson.yml index 9a8a888eb62..ab073aae87c 100644 --- a/.github/workflows/ci-meson.yml +++ b/.github/workflows/ci-meson.yml @@ -23,7 +23,7 @@ jobs: fail-fast: false matrix: os: [ubuntu] - python: ['3.9', '3.10', '3.11'] + python: ['3.11', '3.12'] steps: - uses: actions/checkout@v4 diff --git a/.gitignore b/.gitignore index 60ea5f51490..b8bfc364a26 100644 --- a/.gitignore +++ b/.gitignore @@ -26,13 +26,11 @@ # no longer generated, but may still be in user worktrees /src/lib/pkgconfig -# Conda environment files -# The files without Python version, with -dev or in src are no longer generated -# but may still be in users' directories. +# Conda environment files (auto-generated) +/environment-3.[0-9].yml +/environment-3.[0-9][0-9].yml +# The following files are no longer generated but may still be in users' directories /environment.yml -/environment-3.9.yml -/environment-3.10.yml -/environment-3.11.yml /environment-dev-3.9.yml /environment-dev-3.10.yml /environment-dev-3.11.yml diff --git a/environment-3.11-linux-aarch64.yml b/environment-3.11-linux-aarch64.yml index daa751968c1..c17c3395c99 100644 --- a/environment-3.11-linux-aarch64.yml +++ b/environment-3.11-linux-aarch64.yml @@ -1,64 +1,64 @@ name: sage-dev # Generated by conda-lock. # platform: linux-aarch64 -# input_hash: 5270b05aa1455cb2fb4e045553ae697357d66135a4d3a7e7bc0f417323eb4d22 +# input_hash: 09e3b72a7aa5c065370cb8a339e14ed42ad43f0c89abc55b38713be2d4560fd9 channels: - conda-forge dependencies: - _openmp_mutex=4.5=2_kmp_llvm - - alabaster=1.0.0=pyhd8ed1ab_0 + - alabaster=1.0.0=pyhd8ed1ab_1 - alsa-lib=1.2.13=h86ecc28_0 - arpack=3.9.1=nompi_hd363cd0_101 - - asttokens=2.4.1=pyhd8ed1ab_0 + - asttokens=3.0.0=pyhd8ed1ab_1 - autoconf=2.71=pl5321h2148fe1_1 - automake=1.17=pl5321h8af1aa0_0 - - babel=2.16.0=pyhd8ed1ab_0 + - babel=2.16.0=pyhd8ed1ab_1 - bdw-gc=8.0.6=hd62202e_0 - - beautifulsoup4=4.12.3=pyha770c72_0 + - beautifulsoup4=4.12.3=pyha770c72_1 - binutils=2.43=hf1166c9_2 - binutils_impl_linux-aarch64=2.43=h4c662bb_2 - binutils_linux-aarch64=2.43=hf1166c9_2 - - blas=2.125=openblas - - blas-devel=3.9.0=25_linuxaarch64_openblas + - blas=2.126=openblas + - blas-devel=3.9.0=26_linuxaarch64_openblas - boost-cpp=1.85.0=hdad291f_4 - brial=1.2.12=pyh694c41f_3 - brotli=1.1.0=h86ecc28_2 - brotli-bin=1.1.0=h86ecc28_2 - brotli-python=1.1.0=py311h89d996e_2 - bzip2=1.0.8=h68df207_7 - - c-ares=1.34.3=h86ecc28_1 + - c-ares=1.34.4=h86ecc28_0 - c-compiler=1.8.0=h6561dab_1 - - ca-certificates=2024.8.30=hcefe29a_0 - - cairo=1.18.0=hdb1a16f_3 + - ca-certificates=2024.12.14=hcefe29a_0 + - cairo=1.18.2=h83712da_1 - cddlib=1!0.94m=h719063d_0 - - certifi=2024.8.30=pyhd8ed1ab_0 + - certifi=2024.12.14=pyhd8ed1ab_0 - cffi=1.17.1=py311h14e8bb7_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 + - charset-normalizer=3.4.0=pyhd8ed1ab_1 - cliquer=1.22=h31becfc_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 + - colorama=0.4.6=pyhd8ed1ab_1 + - comm=0.2.2=pyhd8ed1ab_1 - contourpy=1.3.1=py311hc07b1fb_0 - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py311ha09ea12_0 - - cpython=3.11.10=py311hd8ed1ab_3 + - coverage=7.6.9=py311ha09ea12_0 + - cpython=3.11.11=py311hd8ed1ab_1 - cxx-compiler=1.8.0=heb6c788_1 - - cycler=0.12.1=pyhd8ed1ab_0 + - cycler=0.12.1=pyhd8ed1ab_1 - cypari2=2.1.5=py311h5ab95f0_0 - cyrus-sasl=2.1.27=hf6b2984_7 - cysignals=1.11.2=py311h644d908_3 - cython=3.0.11=py311hac78f04_3 - dbus=1.13.6=h12b9eeb_3 - - debugpy=1.8.9=py311h89d996e_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 + - debugpy=1.8.11=py311h89d996e_0 + - decorator=5.1.1=pyhd8ed1ab_1 + - docutils=0.21.2=pyhd8ed1ab_1 - double-conversion=3.3.0=h2f0025b_0 - ecl=24.5.10=h5567cc5_0 - - eclib=20231212=he26bab5_0 + - eclib=20231212=h154513d_1 - ecm=7.0.5=ha2d0fc4_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 + - exceptiongroup=1.2.2=pyhd8ed1ab_1 + - execnet=2.1.1=pyhd8ed1ab_1 + - executing=2.1.0=pyhd8ed1ab_1 - expat=2.6.4=h5ad3122_0 - fflas-ffpack=2.5.0=h503e619_0 - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 @@ -68,18 +68,18 @@ dependencies: - fontconfig=2.15.0=h8dda3cd_1 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 - - fonttools=4.55.0=py311h58d527c_0 + - fonttools=4.55.3=py311h58d527c_0 - fortran-compiler=1.8.0=h25a59a9_1 - fplll=5.4.5=hb3a790e_0 - fpylll=0.6.1=py311h5d3d69a_0 - freetype=2.12.1=hf0a5ef3_2 - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h16511ff_0 - - gap-defaults=4.13.1=h8af1aa0_0 + - gap-core=4.14.0=h1754e88_1 + - gap-defaults=4.14.0=h8af1aa0_1 - gcc=13.3.0=h8a56e6e_1 - gcc_impl_linux-aarch64=13.3.0=hcdea9b6_1 - gcc_linux-aarch64=13.3.0=h1cd514b_7 - - gf2x=1.3.0=h1b3b3a3_2 + - gf2x=1.3.0=h9af5f66_3 - gfan=0.6.2=h5f589ec_1003 - gfortran=13.3.0=h8a56e6e_1 - gfortran_impl_linux-aarch64=13.3.0=h174a3c4_1 @@ -88,31 +88,31 @@ dependencies: - givaro=4.2.0=h364d21b_0 - glpk=5.0=h66325d0_0 - gmp=6.3.0=h0a1ffab_2 - - gmpy2=2.1.5=py311h8dd2ae4_2 + - gmpy2=2.1.5=py311h8dd2ae4_3 - graphite2=1.3.13=h2f0025b_1003 - gsl=2.7=h294027d_0 - gxx=13.3.0=h8a56e6e_1 - gxx_impl_linux-aarch64=13.3.0=h1211b58_1 - gxx_linux-aarch64=13.3.0=h2864abd_7 - - h2=4.1.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_1 - harfbuzz=9.0.0=hbf49d6b_1 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 + - hpack=4.0.0=pyhd8ed1ab_1 + - hyperframe=6.0.1=pyhd8ed1ab_1 - icu=75.1=hf9b3779_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=h207f3e5_0 + - idna=3.10=pyhd8ed1ab_1 + - igraph=0.10.15=h207f3e5_1 - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h15043fe_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 + - importlib-metadata=8.5.0=pyha770c72_1 + - iniconfig=2.0.0=pyhd8ed1ab_1 - ipykernel=6.29.5=pyh3099207_0 - - ipython=8.29.0=pyh707e725_0 - - ipywidgets=8.1.5=pyhd8ed1ab_0 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 + - ipython=8.30.0=pyh707e725_0 + - ipywidgets=8.1.5=pyhd8ed1ab_1 + - jedi=0.19.2=pyhd8ed1ab_1 + - jinja2=3.1.4=pyhd8ed1ab_1 + - jupyter_client=8.6.3=pyhd8ed1ab_1 - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.13=pyhd8ed1ab_1 - kernel-headers_linux-aarch64=4.18.0=h05a177a_18 - keyutils=1.6.1=h4e544f5_0 - kiwisolver=1.4.7=py311h75754e6_0 @@ -121,7 +121,7 @@ dependencies: - lcms2=2.16=h922389a_0 - ld_impl_linux-aarch64=2.43=h80caac9_2 - lerc=4.0.0=h4de3ea5_0 - - libblas=3.9.0=25_linuxaarch64_openblas + - libblas=3.9.0=26_linuxaarch64_openblas - libboost=1.85.0=h9fa81b4_4 - libboost-devel=1.85.0=h37bb5a9_4 - libboost-headers=1.85.0=h8af1aa0_4 @@ -130,19 +130,19 @@ dependencies: - libbrotlicommon=1.1.0=h86ecc28_2 - libbrotlidec=1.1.0=h86ecc28_2 - libbrotlienc=1.1.0=h86ecc28_2 - - libcblas=3.9.0=25_linuxaarch64_openblas - - libclang-cpp19.1=19.1.4=default_he324ac1_0 - - libclang13=19.1.4=default_h4390ef5_0 + - libcblas=3.9.0=26_linuxaarch64_openblas + - libclang-cpp19.1=19.1.6=default_he324ac1_0 + - libclang13=19.1.6=default_h4390ef5_0 - libcups=2.3.3=h405e4a8_4 - - libcurl=8.10.1=h3ec0cbf_0 - - libdeflate=1.22=h86ecc28_0 - - libdrm=2.4.123=h86ecc28_0 + - libcurl=8.11.1=h6702fde_0 + - libdeflate=1.23=h5e3c512_0 + - libdrm=2.4.124=h86ecc28_0 - libedit=3.1.20191231=he28a2e2_2 - libegl=1.7.0=hd24410f_2 - libev=4.33=h31becfc_2 - libexpat=2.6.4=h5ad3122_0 - libffi=3.4.2=h3557bc0_5 - - libflint=3.0.1=h0433c20_103 + - libflint=3.1.2=h0433c20_101 - libgcc=14.2.0=he277a41_1 - libgcc-devel_linux-aarch64=13.3.0=h0c07274_101 - libgcc-ng=14.2.0=he9431aa_1 @@ -158,9 +158,11 @@ dependencies: - libhomfly=1.02r6=h31becfc_1 - libiconv=1.17=h31becfc_2 - libjpeg-turbo=3.0.0=h31becfc_1 - - liblapack=3.9.0=25_linuxaarch64_openblas - - liblapacke=3.9.0=25_linuxaarch64_openblas - - libllvm19=19.1.4=h2edbd07_1 + - liblapack=3.9.0=26_linuxaarch64_openblas + - liblapacke=3.9.0=26_linuxaarch64_openblas + - libllvm19=19.1.6=h2edbd07_0 + - liblzma=5.6.3=h86ecc28_1 + - liblzma-devel=5.6.3=h86ecc28_1 - libnghttp2=1.64.0=hc8609a4_0 - libnsl=2.0.1=h31becfc_0 - libntlm=1.4=hf897c2e_1002 @@ -168,142 +170,142 @@ dependencies: - libopengl=1.7.0=hd24410f_2 - libpciaccess=0.18=h31becfc_0 - libpng=1.6.44=hc4a20ef_0 - - libpq=17.2=h081282e_0 + - libpq=17.2=hd56632b_1 - libsanitizer=13.3.0=ha58e236_1 - libsodium=1.0.20=h68df207_0 - - libsqlite=3.47.0=hc4a20ef_1 + - libsqlite=3.47.2=h5eb1b54_0 - libssh2=1.11.1=ha41c0db_0 - libstdcxx=14.2.0=h3f4de04_1 - libstdcxx-devel_linux-aarch64=13.3.0=h0c07274_101 - libstdcxx-ng=14.2.0=hf1166c9_1 - - libtiff=4.7.0=hec21d91_1 + - libtiff=4.7.0=h88f7998_3 - libuuid=2.38.1=hb4cce97_0 - libwebp-base=1.4.0=h31becfc_0 - libxcb=1.17.0=h262b8f6_0 - libxcrypt=4.4.36=h31becfc_1 - libxkbcommon=1.7.0=h46f2afe_1 - - libxml2=2.13.5=hf4efe5d_0 + - libxml2=2.13.5=h2e0c361_1 - libxslt=1.1.39=h1cc9640_0 - libzlib=1.3.1=h86ecc28_2 - - linbox=1.7.0=h681a5ee_0 - - llvm-openmp=19.1.4=h013ceaa_0 + - linbox=1.7.0=hf74d613_1 + - llvm-openmp=19.1.6=h013ceaa_0 - lrcalc=2.1=h5ad3122_7 - m4=1.4.18=h516909a_1001 - m4ri=20140914=hedfd65a_1006 - - m4rie=20150908=hf0a5ef3_1002 - - markupsafe=3.0.2=py311ha09ea12_0 - - matplotlib=3.9.2=py311hfecb2dc_2 - - matplotlib-base=3.9.2=py311h0385ec1_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 + - m4rie=20200125=hedfd65a_0 + - markupsafe=3.0.2=py311ha09ea12_1 + - matplotlib=3.10.0=py311hfecb2dc_0 + - matplotlib-base=3.10.0=py311h0385ec1_0 + - matplotlib-inline=0.1.7=pyhd8ed1ab_1 - maxima=5.47.0=h043f013_3 - memory-allocator=0.1.3=py311ha879c10_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 + - meson=1.6.1=pyhd8ed1ab_0 + - meson-python=0.17.1=pyh70fd9c4_1 - mpc=1.3.1=h783934e_1 - mpfi=1.5.4=h846f343_1001 - mpfr=4.2.1=h2305555_3 - - mpmath=1.3.0=pyhd8ed1ab_0 + - mpmath=1.3.0=pyhd8ed1ab_1 - munkres=1.1.4=pyh9f0ad1d_0 - - mysql-common=9.0.1=h3f5c77f_2 - - mysql-libs=9.0.1=h11569fd_2 + - mysql-common=9.0.1=h3f5c77f_3 + - mysql-libs=9.0.1=h11569fd_3 - nauty=2.8.8=h31becfc_1 - ncurses=6.5=hcccb83c_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_1 - networkx=3.4.2=pyh267e887_2 - ninja=1.12.1=h70be974_0 - ntl=11.4.3=h0d7519b_1 - numpy=1.26.4=py311h69ead2a_0 - openblas=0.3.28=pthreads_h3a8cbd8_1 - - openjpeg=2.5.2=h0d9d63b_0 + - openjpeg=2.5.3=h3f56577_0 - openldap=2.6.9=h30c48ee_0 - openssl=3.4.0=h86ecc28_0 - - packaging=24.2=pyhff2d567_1 + - packaging=24.2=pyhd8ed1ab_2 - palp=2.20=hb9de7d4_0 - pari=2.15.5=h169c2a7_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 + - parso=0.8.4=pyhd8ed1ab_1 - pcre2=10.44=h070dd5b_2 - perl=5.32.1=7_h31becfc_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 + - pexpect=4.9.0=pyhd8ed1ab_1 + - pickleshare=0.7.5=pyhd8ed1ab_1004 - pillow=11.0.0=py311hb2a0dd2_0 - - pip=24.3.1=pyh8b19718_0 - - pixman=0.43.4=h2f0025b_0 + - pip=24.3.1=pyh8b19718_2 + - pixman=0.44.2=h86a87f0_0 - pkg-config=0.29.2=hce167ba_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgconfig=1.5.5=pyhd8ed1ab_5 - planarity=3.0.2.0=h31becfc_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 + - platformdirs=4.3.6=pyhd8ed1ab_1 + - pluggy=1.5.0=pyhd8ed1ab_1 - ppl=1.2=h984aac9_1006 - pplpy=0.8.9=py311ha3770eb_1 - primecount=7.9=hd600fc2_0 - primecountpy=0.1.0=py311h098ece5_4 - primesieve=11.1=h2f0025b_0 - - prompt-toolkit=3.0.48=pyha770c72_0 + - prompt-toolkit=3.0.48=pyha770c72_1 - psutil=6.1.0=py311ha879c10_0 - pthread-stubs=0.4=h86ecc28_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pyside6=6.8.0.2=py311habb2604_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.11.10=h5d932e8_3_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 + - ptyprocess=0.7.0=pyhd8ed1ab_1 + - pure_eval=0.2.3=pyhd8ed1ab_1 + - pycparser=2.22=pyh29332c3_1 + - pygments=2.18.0=pyhd8ed1ab_1 + - pyparsing=3.2.0=pyhd8ed1ab_2 + - pyproject-metadata=0.9.0=pyhd8ed1ab_1 + - pyside6=6.8.1=py311habb2604_0 + - pysocks=1.7.1=pyha55dd90_7 + - pytest=8.3.4=pyhd8ed1ab_1 + - pytest-xdist=3.6.1=pyhd8ed1ab_1 + - python=3.11.11=h1683364_1_cpython + - python-dateutil=2.9.0.post0=pyhff2d567_1 - python-lrcalc=2.1=py311h89d996e_7 - python_abi=3.11=5_cp311 - - pytz=2024.2=pyhd8ed1ab_0 + - pytz=2024.2=pyhd8ed1ab_1 - pyzmq=26.2.0=py311h826da9f_3 - qd=2.3.22=h05efe27_1004 - qhull=2020.2=h70be974_5 - - qt6-main=6.8.0=h666f7c6_0 + - qt6-main=6.8.1=h0d3cc05_0 - readline=8.2=h8fc344f_1 - - requests=2.32.3=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_1 - rw=0.9=h31becfc_2 - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - sagemath-db-graphs=20210214=hd8ed1ab_0 - sagemath-db-polytopes=20170220=1 - - scipy=1.14.1=py311h5912639_1 + - scipy=1.14.1=py311h5912639_2 - setuptools=75.6.0=pyhff2d567_1 - - singular=4.4.0=h9a92511_0 - - six=1.16.0=pyh6c4a22f_0 + - singular=4.4.0=hee12f27_1 + - six=1.17.0=pyhd8ed1ab_0 - snowballstemmer=2.2.0=pyhd8ed1ab_0 - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=8.1.3=pyhd8ed1ab_0 + - sphinx=8.1.3=pyhd8ed1ab_1 - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=h578a6b9_1 - - stack_data=0.6.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_1 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_1 + - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_1 + - sqlite=3.47.2=h578a6b9_0 + - stack_data=0.6.3=pyhd8ed1ab_1 - symmetrica=3.0.1=hd600fc2_0 - sympow=2.023.6=h157afb5_3 - sympy=1.13.3=pyh2585a3b_104 - sysroot_linux-aarch64=2.17=h5b4a56d_18 - tachyon=0.99b6=ha0bfc61_1002 - tk=8.6.13=h194ca79_0 - - tomli=2.1.0=pyhff2d567_0 + - tomli=2.2.1=pyhd8ed1ab_1 - tornado=6.4.2=py311h5487e9b_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 + - traitlets=5.14.3=pyhd8ed1ab_1 + - typing_extensions=4.12.2=pyha770c72_1 - tzdata=2024b=hc8b5060_0 - unicodedata2=15.1.0=py311ha879c10_1 - - urllib3=2.2.3=pyhd8ed1ab_0 + - urllib3=2.2.3=pyhd8ed1ab_1 - wayland=1.23.1=h698ed42_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_1 + - wheel=0.45.1=pyhd8ed1ab_1 + - widgetsnbextension=4.0.13=pyhd8ed1ab_1 - xcb-util=0.4.1=h5c728e9_2 - xcb-util-cursor=0.1.5=h86ecc28_0 - xcb-util-image=0.4.0=h5c728e9_2 @@ -311,10 +313,10 @@ dependencies: - xcb-util-renderutil=0.3.10=h5c728e9_0 - xcb-util-wm=0.4.2=h5c728e9_0 - xkeyboard-config=2.43=h86ecc28_0 - - xorg-libice=1.1.1=h57736b2_1 - - xorg-libsm=1.2.4=hbac51e1_1 - - xorg-libx11=1.8.9=he755bbd_2 - - xorg-libxau=1.0.11=h86ecc28_1 + - xorg-libice=1.1.2=h86ecc28_0 + - xorg-libsm=1.2.5=h0808dbd_0 + - xorg-libx11=1.8.10=hca56bd8_1 + - xorg-libxau=1.0.12=h86ecc28_0 - xorg-libxcomposite=0.4.6=h86ecc28_2 - xorg-libxcursor=1.2.3=h86ecc28_0 - xorg-libxdamage=1.1.6=h86ecc28_0 @@ -323,11 +325,12 @@ dependencies: - xorg-libxfixes=6.0.1=h57736b2_0 - xorg-libxi=1.8.2=h57736b2_0 - xorg-libxrandr=1.5.4=h86ecc28_0 - - xorg-libxrender=0.9.11=h57736b2_1 + - xorg-libxrender=0.9.12=h86ecc28_0 - xorg-libxtst=1.2.5=h57736b2_3 - - xorg-libxxf86vm=1.1.5=h57736b2_4 - - xorg-xorgproto=2024.1=h86ecc28_1 - - xz=5.2.6=h9cdd2b7_0 + - xorg-libxxf86vm=1.1.6=h86ecc28_0 + - xz=5.6.3=h2dbfc1b_1 + - xz-gpl-tools=5.6.3=h2dbfc1b_1 + - xz-tools=5.6.3=h86ecc28_1 - zeromq=4.3.5=h5efb499_7 - zipp=3.21.0=pyhd8ed1ab_1 - zlib=1.3.1=h86ecc28_2 diff --git a/environment-3.11-linux.yml b/environment-3.11-linux.yml index c18abc2b254..2d99c14d61c 100644 --- a/environment-3.11-linux.yml +++ b/environment-3.11-linux.yml @@ -1,65 +1,65 @@ name: sage-dev # Generated by conda-lock. # platform: linux-64 -# input_hash: 48b95e0f20684f5ff684784c6c674a2251078ce14af62d4a59b6cc8c47dcd320 +# input_hash: 71d6929e3ba448868bcdf30d6cb1d190d88758e7272df5cf428554adbbf0ff6a channels: - conda-forge dependencies: - _libgcc_mutex=0.1=conda_forge - _openmp_mutex=4.5=2_kmp_llvm - - alabaster=1.0.0=pyhd8ed1ab_0 + - alabaster=1.0.0=pyhd8ed1ab_1 - alsa-lib=1.2.13=hb9d3cd8_0 - arpack=3.9.1=nompi_h77f6705_101 - - asttokens=2.4.1=pyhd8ed1ab_0 + - asttokens=3.0.0=pyhd8ed1ab_1 - autoconf=2.71=pl5321h2b4cb7a_1 - automake=1.17=pl5321ha770c72_0 - - babel=2.16.0=pyhd8ed1ab_0 + - babel=2.16.0=pyhd8ed1ab_1 - bdw-gc=8.0.6=h4bd325d_0 - - beautifulsoup4=4.12.3=pyha770c72_0 + - beautifulsoup4=4.12.3=pyha770c72_1 - binutils=2.43=h4852527_2 - binutils_impl_linux-64=2.43=h4bf12b8_2 - binutils_linux-64=2.43=h4852527_2 - - blas=2.125=openblas - - blas-devel=3.9.0=25_linux64_openblas + - blas=2.126=openblas + - blas-devel=3.9.0=26_linux64_openblas - boost-cpp=1.85.0=h3c6214e_4 - brial=1.2.12=pyh694c41f_3 - brotli=1.1.0=hb9d3cd8_2 - brotli-bin=1.1.0=hb9d3cd8_2 - brotli-python=1.1.0=py311hfdbb021_2 - bzip2=1.0.8=h4bc722e_7 - - c-ares=1.34.3=hb9d3cd8_1 + - c-ares=1.34.4=hb9d3cd8_0 - c-compiler=1.8.0=h2b85faf_1 - - ca-certificates=2024.8.30=hbcca054_0 - - cairo=1.18.0=hebfffa5_3 + - ca-certificates=2024.12.14=hbcca054_0 + - cairo=1.18.2=h3394656_1 - cddlib=1!0.94m=h9202a9a_0 - - certifi=2024.8.30=pyhd8ed1ab_0 + - certifi=2024.12.14=pyhd8ed1ab_0 - cffi=1.17.1=py311hf29c0ef_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 + - charset-normalizer=3.4.0=pyhd8ed1ab_1 - cliquer=1.22=hd590300_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 + - colorama=0.4.6=pyhd8ed1ab_1 + - comm=0.2.2=pyhd8ed1ab_1 - contourpy=1.3.1=py311hd18a35c_0 - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py311h2dc5d0c_0 - - cpython=3.11.10=py311hd8ed1ab_3 + - coverage=7.6.9=py311h2dc5d0c_0 + - cpython=3.11.11=py311hd8ed1ab_1 - cxx-compiler=1.8.0=h1a2810e_1 - - cycler=0.12.1=pyhd8ed1ab_0 + - cycler=0.12.1=pyhd8ed1ab_1 - cypari2=2.1.5=py311hd2352ae_0 - cyrus-sasl=2.1.27=h54b06d7_7 - cysignals=1.11.2=py311h82528dc_3 - cython=3.0.11=py311h55d416d_3 - dbus=1.13.6=h5008d03_3 - - debugpy=1.8.9=py311hfdbb021_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 + - debugpy=1.8.11=py311hfdbb021_0 + - decorator=5.1.1=pyhd8ed1ab_1 + - docutils=0.21.2=pyhd8ed1ab_1 - double-conversion=3.3.0=h59595ed_0 - ecl=24.5.10=h0f3afd4_0 - - eclib=20231212=h96f522a_0 + - eclib=20231212=h43e5eba_1 - ecm=7.0.5=h9458935_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 + - exceptiongroup=1.2.2=pyhd8ed1ab_1 + - execnet=2.1.1=pyhd8ed1ab_1 + - executing=2.1.0=pyhd8ed1ab_1 - expat=2.6.4=h5888daf_0 - fflas-ffpack=2.5.0=h4f9960b_0 - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 @@ -69,18 +69,18 @@ dependencies: - fontconfig=2.15.0=h7e30c49_1 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 - - fonttools=4.55.0=py311h2dc5d0c_0 + - fonttools=4.55.3=py311h2dc5d0c_0 - fortran-compiler=1.8.0=h36df796_1 - fplll=5.4.5=h384768b_0 - fpylll=0.6.1=py311hcfae7cf_0 - freetype=2.12.1=h267a509_2 - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h94f18e1_0 - - gap-defaults=4.13.1=ha770c72_0 + - gap-core=4.14.0=h3b03731_1 + - gap-defaults=4.14.0=ha770c72_1 - gcc=13.3.0=h9576a4e_1 - gcc_impl_linux-64=13.3.0=hfea6d02_1 - gcc_linux-64=13.3.0=hc28eda2_7 - - gf2x=1.3.0=ha476b99_2 + - gf2x=1.3.0=h55551d5_3 - gfan=0.6.2=hb86e20a_1003 - gfortran=13.3.0=h9576a4e_1 - gfortran_impl_linux-64=13.3.0=h10434e7_1 @@ -89,31 +89,31 @@ dependencies: - givaro=4.2.0=hb789bce_0 - glpk=5.0=h445213a_0 - gmp=6.3.0=hac33072_2 - - gmpy2=2.1.5=py311h0f6cedb_2 + - gmpy2=2.1.5=py311h0f6cedb_3 - graphite2=1.3.13=h59595ed_1003 - gsl=2.7=he838d99_0 - gxx=13.3.0=h9576a4e_1 - gxx_impl_linux-64=13.3.0=hdbfa832_1 - gxx_linux-64=13.3.0=h6834431_7 - - h2=4.1.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_1 - harfbuzz=9.0.0=hda332d3_1 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 + - hpack=4.0.0=pyhd8ed1ab_1 + - hyperframe=6.0.1=pyhd8ed1ab_1 - icu=75.1=he02047a_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=he44f51b_0 + - idna=3.10=pyhd8ed1ab_1 + - igraph=0.10.15=he44f51b_1 - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h623f65a_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 + - importlib-metadata=8.5.0=pyha770c72_1 + - iniconfig=2.0.0=pyhd8ed1ab_1 - ipykernel=6.29.5=pyh3099207_0 - - ipython=8.29.0=pyh707e725_0 - - ipywidgets=8.1.5=pyhd8ed1ab_0 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 + - ipython=8.30.0=pyh707e725_0 + - ipywidgets=8.1.5=pyhd8ed1ab_1 + - jedi=0.19.2=pyhd8ed1ab_1 + - jinja2=3.1.4=pyhd8ed1ab_1 + - jupyter_client=8.6.3=pyhd8ed1ab_1 - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.13=pyhd8ed1ab_1 - kernel-headers_linux-64=3.10.0=he073ed8_18 - keyutils=1.6.1=h166bdaf_0 - kiwisolver=1.4.7=py311hd18a35c_0 @@ -122,7 +122,7 @@ dependencies: - lcms2=2.16=hb7c19ff_0 - ld_impl_linux-64=2.43=h712a8e2_2 - lerc=4.0.0=h27087fc_0 - - libblas=3.9.0=25_linux64_openblas + - libblas=3.9.0=26_linux64_openblas - libboost=1.85.0=h0ccab89_4 - libboost-devel=1.85.0=h00ab1b0_4 - libboost-headers=1.85.0=ha770c72_4 @@ -131,19 +131,19 @@ dependencies: - libbrotlicommon=1.1.0=hb9d3cd8_2 - libbrotlidec=1.1.0=hb9d3cd8_2 - libbrotlienc=1.1.0=hb9d3cd8_2 - - libcblas=3.9.0=25_linux64_openblas - - libclang-cpp19.1=19.1.4=default_hb5137d0_0 - - libclang13=19.1.4=default_h9c6a7e4_0 + - libcblas=3.9.0=26_linux64_openblas + - libclang-cpp19.1=19.1.6=default_hb5137d0_0 + - libclang13=19.1.6=default_h9c6a7e4_0 - libcups=2.3.3=h4637d8d_4 - - libcurl=8.10.1=hbbe4b11_0 - - libdeflate=1.22=hb9d3cd8_0 - - libdrm=2.4.123=hb9d3cd8_0 + - libcurl=8.11.1=h332b0f4_0 + - libdeflate=1.23=h4ddbbb0_0 + - libdrm=2.4.124=hb9d3cd8_0 - libedit=3.1.20191231=he28a2e2_2 - libegl=1.7.0=ha4b6fd6_2 - libev=4.33=hd590300_2 - libexpat=2.6.4=h5888daf_0 - libffi=3.4.2=h7f98852_5 - - libflint=3.0.1=h6fb9888_103 + - libflint=3.1.2=h6fb9888_101 - libgcc=14.2.0=h77fa898_1 - libgcc-devel_linux-64=13.3.0=h84ea5a7_101 - libgcc-ng=14.2.0=h69a702a_1 @@ -159,9 +159,11 @@ dependencies: - libhomfly=1.02r6=hd590300_1 - libiconv=1.17=hd590300_2 - libjpeg-turbo=3.0.0=hd590300_1 - - liblapack=3.9.0=25_linux64_openblas - - liblapacke=3.9.0=25_linux64_openblas - - libllvm19=19.1.4=ha7bfdaf_1 + - liblapack=3.9.0=26_linux64_openblas + - liblapacke=3.9.0=26_linux64_openblas + - libllvm19=19.1.6=ha7bfdaf_0 + - liblzma=5.6.3=hb9d3cd8_1 + - liblzma-devel=5.6.3=hb9d3cd8_1 - libnghttp2=1.64.0=h161d5f1_0 - libnsl=2.0.1=hd590300_0 - libntlm=1.4=h7f98852_1002 @@ -169,142 +171,142 @@ dependencies: - libopengl=1.7.0=ha4b6fd6_2 - libpciaccess=0.18=hd590300_0 - libpng=1.6.44=hadc24fc_0 - - libpq=17.2=h04577a9_0 + - libpq=17.2=h3b95a9b_1 - libsanitizer=13.3.0=heb74ff8_1 - libsodium=1.0.20=h4ab18f5_0 - - libsqlite=3.47.0=hadc24fc_1 + - libsqlite=3.47.2=hee588c1_0 - libssh2=1.11.1=hf672d98_0 - libstdcxx=14.2.0=hc0a3c3a_1 - libstdcxx-devel_linux-64=13.3.0=h84ea5a7_101 - libstdcxx-ng=14.2.0=h4852527_1 - - libtiff=4.7.0=he137b08_1 + - libtiff=4.7.0=hd9ff511_3 - libuuid=2.38.1=h0b41bf4_0 - libwebp-base=1.4.0=hd590300_0 - libxcb=1.17.0=h8a09558_0 - libxcrypt=4.4.36=hd590300_1 - libxkbcommon=1.7.0=h2c5496b_1 - - libxml2=2.13.5=hb346dea_0 + - libxml2=2.13.5=h8d12d68_1 - libxslt=1.1.39=h76b75d6_0 - libzlib=1.3.1=hb9d3cd8_2 - - linbox=1.7.0=ha329b40_0 - - llvm-openmp=19.1.4=h024ca30_0 + - linbox=1.7.0=h7298d08_1 + - llvm-openmp=19.1.6=h024ca30_0 - lrcalc=2.1=h5888daf_7 - m4=1.4.18=h516909a_1001 - m4ri=20140914=hae5d5c5_1006 - - m4rie=20150908=h267a509_1002 - - markupsafe=3.0.2=py311h2dc5d0c_0 - - matplotlib=3.9.2=py311h38be061_2 - - matplotlib-base=3.9.2=py311h2b939e6_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 + - m4rie=20200125=h051dbe0_0 + - markupsafe=3.0.2=py311h2dc5d0c_1 + - matplotlib=3.10.0=py311h38be061_0 + - matplotlib-base=3.10.0=py311h2b939e6_0 + - matplotlib-inline=0.1.7=pyhd8ed1ab_1 - maxima=5.47.0=h75482ee_3 - memory-allocator=0.1.3=py311h9ecbd09_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 + - meson=1.6.1=pyhd8ed1ab_0 + - meson-python=0.17.1=pyh70fd9c4_1 - mpc=1.3.1=h24ddda3_1 - mpfi=1.5.4=h9f54685_1001 - mpfr=4.2.1=h90cbb55_3 - - mpmath=1.3.0=pyhd8ed1ab_0 + - mpmath=1.3.0=pyhd8ed1ab_1 - munkres=1.1.4=pyh9f0ad1d_0 - - mysql-common=9.0.1=h266115a_2 - - mysql-libs=9.0.1=he0572af_2 + - mysql-common=9.0.1=h266115a_3 + - mysql-libs=9.0.1=he0572af_3 - nauty=2.8.8=hd590300_1 - ncurses=6.5=he02047a_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_1 - networkx=3.4.2=pyh267e887_2 - ninja=1.12.1=h297d8ca_0 - ntl=11.4.3=hef3c4d3_1 - numpy=1.26.4=py311h64a7726_0 - openblas=0.3.28=pthreads_h6ec200e_1 - - openjpeg=2.5.2=h488ebb8_0 + - openjpeg=2.5.3=h5fbd93e_0 - openldap=2.6.9=he970967_0 - openssl=3.4.0=hb9d3cd8_0 - - packaging=24.2=pyhff2d567_1 + - packaging=24.2=pyhd8ed1ab_2 - palp=2.20=h36c2ea0_0 - pari=2.15.5=h4d4ae9b_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 + - parso=0.8.4=pyhd8ed1ab_1 - pcre2=10.44=hba22ea6_2 - perl=5.32.1=7_hd590300_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 + - pexpect=4.9.0=pyhd8ed1ab_1 + - pickleshare=0.7.5=pyhd8ed1ab_1004 - pillow=11.0.0=py311h49e9ac3_0 - - pip=24.3.1=pyh8b19718_0 - - pixman=0.43.2=h59595ed_0 + - pip=24.3.1=pyh8b19718_2 + - pixman=0.44.2=h29eaf8c_0 - pkg-config=0.29.2=h4bc722e_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgconfig=1.5.5=pyhd8ed1ab_5 - planarity=3.0.2.0=hd590300_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 + - platformdirs=4.3.6=pyhd8ed1ab_1 + - pluggy=1.5.0=pyhd8ed1ab_1 - ppl=1.2=h6ec01c2_1006 - pplpy=0.8.9=py311ha9f9f00_1 - primecount=7.9=hcb278e6_0 - primecountpy=0.1.0=py311h9547e67_4 - primesieve=11.1=h59595ed_0 - - prompt-toolkit=3.0.48=pyha770c72_0 + - prompt-toolkit=3.0.48=pyha770c72_1 - psutil=6.1.0=py311h9ecbd09_0 - pthread-stubs=0.4=hb9d3cd8_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pyside6=6.8.0.2=py311h9053184_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.11.10=hc5c86c4_3_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 + - ptyprocess=0.7.0=pyhd8ed1ab_1 + - pure_eval=0.2.3=pyhd8ed1ab_1 + - pycparser=2.22=pyh29332c3_1 + - pygments=2.18.0=pyhd8ed1ab_1 + - pyparsing=3.2.0=pyhd8ed1ab_2 + - pyproject-metadata=0.9.0=pyhd8ed1ab_1 + - pyside6=6.8.1=py311h9053184_0 + - pysocks=1.7.1=pyha55dd90_7 + - pytest=8.3.4=pyhd8ed1ab_1 + - pytest-xdist=3.6.1=pyhd8ed1ab_1 + - python=3.11.11=h9e4cc4f_1_cpython + - python-dateutil=2.9.0.post0=pyhff2d567_1 - python-lrcalc=2.1=py311hfdbb021_7 - python_abi=3.11=5_cp311 - - pytz=2024.2=pyhd8ed1ab_0 + - pytz=2024.2=pyhd8ed1ab_1 - pyzmq=26.2.0=py311h7deb3e3_3 - qd=2.3.22=h2cc385e_1004 - qhull=2020.2=h434a139_5 - - qt6-main=6.8.0=h6e8976b_0 + - qt6-main=6.8.1=h9d28a51_0 - readline=8.2=h8228510_1 - - requests=2.32.3=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_1 - rw=0.9=hd590300_2 - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - sagemath-db-graphs=20210214=hd8ed1ab_0 - sagemath-db-polytopes=20170220=1 - - scipy=1.14.1=py311he9a78e4_1 + - scipy=1.14.1=py311he9a78e4_2 - setuptools=75.6.0=pyhff2d567_1 - - singular=4.4.0=h8a38e62_0 - - six=1.16.0=pyh6c4a22f_0 + - singular=4.4.0=hc910cb2_1 + - six=1.17.0=pyhd8ed1ab_0 - snowballstemmer=2.2.0=pyhd8ed1ab_0 - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=8.1.3=pyhd8ed1ab_0 + - sphinx=8.1.3=pyhd8ed1ab_1 - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=h9eae976_1 - - stack_data=0.6.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_1 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_1 + - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_1 + - sqlite=3.47.2=h9eae976_0 + - stack_data=0.6.3=pyhd8ed1ab_1 - symmetrica=3.0.1=hcb278e6_0 - sympow=2.023.6=hc6ab17c_3 - sympy=1.13.3=pyh2585a3b_104 - sysroot_linux-64=2.17=h4a8ded7_18 - tachyon=0.99b6=hba7d16a_1002 - tk=8.6.13=noxft_h4845f30_101 - - tomli=2.1.0=pyhff2d567_0 + - tomli=2.2.1=pyhd8ed1ab_1 - tornado=6.4.2=py311h9ecbd09_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 + - traitlets=5.14.3=pyhd8ed1ab_1 + - typing_extensions=4.12.2=pyha770c72_1 - tzdata=2024b=hc8b5060_0 - unicodedata2=15.1.0=py311h9ecbd09_1 - - urllib3=2.2.3=pyhd8ed1ab_0 + - urllib3=2.2.3=pyhd8ed1ab_1 - wayland=1.23.1=h3e06ad9_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_1 + - wheel=0.45.1=pyhd8ed1ab_1 + - widgetsnbextension=4.0.13=pyhd8ed1ab_1 - xcb-util=0.4.1=hb711507_2 - xcb-util-cursor=0.1.5=hb9d3cd8_0 - xcb-util-image=0.4.0=hb711507_2 @@ -312,10 +314,10 @@ dependencies: - xcb-util-renderutil=0.3.10=hb711507_0 - xcb-util-wm=0.4.2=hb711507_0 - xkeyboard-config=2.43=hb9d3cd8_0 - - xorg-libice=1.1.1=hb9d3cd8_1 - - xorg-libsm=1.2.4=he73a12e_1 - - xorg-libx11=1.8.10=h4f16b4b_0 - - xorg-libxau=1.0.11=hb9d3cd8_1 + - xorg-libice=1.1.2=hb9d3cd8_0 + - xorg-libsm=1.2.5=he73a12e_0 + - xorg-libx11=1.8.10=h4f16b4b_1 + - xorg-libxau=1.0.12=hb9d3cd8_0 - xorg-libxcomposite=0.4.6=hb9d3cd8_2 - xorg-libxcursor=1.2.3=hb9d3cd8_0 - xorg-libxdamage=1.1.6=hb9d3cd8_0 @@ -324,11 +326,12 @@ dependencies: - xorg-libxfixes=6.0.1=hb9d3cd8_0 - xorg-libxi=1.8.2=hb9d3cd8_0 - xorg-libxrandr=1.5.4=hb9d3cd8_0 - - xorg-libxrender=0.9.11=hb9d3cd8_1 + - xorg-libxrender=0.9.12=hb9d3cd8_0 - xorg-libxtst=1.2.5=hb9d3cd8_3 - - xorg-libxxf86vm=1.1.5=hb9d3cd8_4 - - xorg-xorgproto=2024.1=hb9d3cd8_1 - - xz=5.2.6=h166bdaf_0 + - xorg-libxxf86vm=1.1.6=hb9d3cd8_0 + - xz=5.6.3=hbcc6ac9_1 + - xz-gpl-tools=5.6.3=hbcc6ac9_1 + - xz-tools=5.6.3=hb9d3cd8_1 - zeromq=4.3.5=h3b0a872_7 - zipp=3.21.0=pyhd8ed1ab_1 - zlib=1.3.1=hb9d3cd8_2 diff --git a/environment-3.11-macos-x86_64.yml b/environment-3.11-macos-x86_64.yml index bb44b958990..fb34c25a567 100644 --- a/environment-3.11-macos-x86_64.yml +++ b/environment-3.11-macos-x86_64.yml @@ -1,37 +1,37 @@ name: sage-dev # Generated by conda-lock. # platform: osx-64 -# input_hash: 2555438d4f4434f9195688dd6b45c84e2c965157dd440bc593c0f833080e765a +# input_hash: 58971dc791eb5f5f7e12b0e44db07ecd9b2fc48def89f671effaabd2bd0720d6 channels: - conda-forge dependencies: - - alabaster=1.0.0=pyhd8ed1ab_0 - - appnope=0.1.4=pyhd8ed1ab_0 + - alabaster=1.0.0=pyhd8ed1ab_1 + - appnope=0.1.4=pyhd8ed1ab_1 - arpack=3.9.1=nompi_hf81eadf_101 - - asttokens=2.4.1=pyhd8ed1ab_0 + - asttokens=3.0.0=pyhd8ed1ab_1 - autoconf=2.71=pl5321hed12c24_1 - automake=1.17=pl5321h694c41f_0 - - babel=2.16.0=pyhd8ed1ab_0 + - babel=2.16.0=pyhd8ed1ab_1 - bdw-gc=8.0.6=h940c156_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - blas=2.125=openblas - - blas-devel=3.9.0=25_osx64_openblas + - beautifulsoup4=4.12.3=pyha770c72_1 + - blas=2.126=openblas + - blas-devel=3.9.0=26_osx64_openblas - boost-cpp=1.85.0=hfcd56d9_4 - brial=1.2.12=pyh694c41f_3 - brotli=1.1.0=h00291cd_2 - brotli-bin=1.1.0=h00291cd_2 - brotli-python=1.1.0=py311hd89902b_2 - bzip2=1.0.8=hfdf4475_7 - - c-ares=1.34.3=hf13058a_1 + - c-ares=1.34.4=hf13058a_0 - c-compiler=1.8.0=hfc4bf79_1 - - ca-certificates=2024.8.30=h8857fd0_0 + - ca-certificates=2024.12.14=h8857fd0_0 - cctools=1010.6=h5b2de21_2 - cctools_osx-64=1010.6=hea4301f_2 - cddlib=1!0.94m=h0f52abe_0 - - certifi=2024.8.30=pyhd8ed1ab_0 + - certifi=2024.12.14=pyhd8ed1ab_0 - cffi=1.17.1=py311h137bacd_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 + - charset-normalizer=3.4.0=pyhd8ed1ab_1 - clang=17.0.6=default_he371ed4_7 - clang-17=17.0.6=default_hb173f14_7 - clang_impl_osx-64=17.0.6=h1af8efd_23 @@ -40,28 +40,28 @@ dependencies: - clangxx_impl_osx-64=17.0.6=hc3430b7_23 - clangxx_osx-64=17.0.6=h7e5c614_23 - cliquer=1.22=h10d778d_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 + - colorama=0.4.6=pyhd8ed1ab_1 + - comm=0.2.2=pyhd8ed1ab_1 - compiler-rt=17.0.6=h1020d70_2 - compiler-rt_osx-64=17.0.6=hf2b8a54_2 - contourpy=1.3.1=py311h4e34fa0_0 - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py311ha3cf9ac_0 - - cpython=3.11.10=py311hd8ed1ab_3 + - coverage=7.6.9=py311ha3cf9ac_0 + - cpython=3.11.11=py311hd8ed1ab_1 - cxx-compiler=1.8.0=h385f146_1 - - cycler=0.12.1=pyhd8ed1ab_0 + - cycler=0.12.1=pyhd8ed1ab_1 - cypari2=2.1.5=py311h4fde0ae_0 - cysignals=1.11.2=py311h8a58447_3 - cython=3.0.11=py311h4cb39f0_3 - - debugpy=1.8.9=py311hc356e98_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 + - debugpy=1.8.11=py311hc356e98_0 + - decorator=5.1.1=pyhd8ed1ab_1 + - docutils=0.21.2=pyhd8ed1ab_1 - ecl=24.5.10=h56bac16_0 - - eclib=20231212=h02435c3_0 + - eclib=20231212=h960c116_1 - ecm=7.0.5=h4f6b447_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 + - exceptiongroup=1.2.2=pyhd8ed1ab_1 + - execnet=2.1.1=pyhd8ed1ab_1 + - executing=2.1.0=pyhd8ed1ab_1 - expat=2.6.4=h240833e_0 - fflas-ffpack=2.5.0=h5898d61_0 - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 @@ -71,17 +71,17 @@ dependencies: - fontconfig=2.15.0=h37eeddb_1 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 - - fonttools=4.55.0=py311ha3cf9ac_0 + - fonttools=4.55.3=py311ha3cf9ac_0 - fortran-compiler=1.8.0=h33d1f46_1 - fplll=5.4.5=hb7981ad_0 - fpylll=0.6.1=py311h85fbf69_0 - freetype=2.12.1=h60636b9_2 - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h2299be9_0 - - gap-defaults=4.13.1=h694c41f_0 + - gap-core=4.14.0=hb9686a1_1 + - gap-defaults=4.14.0=h694c41f_1 - gettext=0.22.5=hdfe23c8_3 - gettext-tools=0.22.5=hdfe23c8_3 - - gf2x=1.3.0=hb2a7efb_2 + - gf2x=1.3.0=h35ac7d9_3 - gfan=0.6.2=hd793b56_1003 - gfortran=13.2.0=h2c809b3_1 - gfortran_impl_osx-64=13.2.0=h2bc304d_3 @@ -90,27 +90,27 @@ dependencies: - givaro=4.2.0=h1b3d6f7_0 - glpk=5.0=h3cb5acd_0 - gmp=6.3.0=hf036a51_2 - - gmpy2=2.1.5=py311hf411314_2 + - gmpy2=2.1.5=py311h7945f45_3 - gsl=2.7=h93259b0_0 - - h2=4.1.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_1 + - hpack=4.0.0=pyhd8ed1ab_1 + - hyperframe=6.0.1=pyhd8ed1ab_1 - icu=75.1=h120a0e1_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=h5479cbe_0 + - idna=3.10=pyhd8ed1ab_1 + - igraph=0.10.15=h5479cbe_1 - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h61918c1_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 + - importlib-metadata=8.5.0=pyha770c72_1 + - iniconfig=2.0.0=pyhd8ed1ab_1 - ipykernel=6.29.5=pyh57ce528_0 - - ipython=8.29.0=pyh707e725_0 - - ipywidgets=8.1.5=pyhd8ed1ab_0 + - ipython=8.30.0=pyh707e725_0 + - ipywidgets=8.1.5=pyhd8ed1ab_1 - isl=0.26=imath32_h2e86a7b_101 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 + - jedi=0.19.2=pyhd8ed1ab_1 + - jinja2=3.1.4=pyhd8ed1ab_1 + - jupyter_client=8.6.3=pyhd8ed1ab_1 - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.13=pyhd8ed1ab_1 - kiwisolver=1.4.7=py311hf2f7c97_0 - krb5=1.21.3=h37d8d59_0 - lcalc=2.0.5=h547a6ed_2 @@ -120,7 +120,7 @@ dependencies: - lerc=4.0.0=hb486fe8_0 - libasprintf=0.22.5=hdfe23c8_3 - libasprintf-devel=0.22.5=hdfe23c8_3 - - libblas=3.9.0=25_osx64_openblas + - libblas=3.9.0=26_osx64_openblas - libboost=1.85.0=hcca3243_4 - libboost-devel=1.85.0=h2b186f8_4 - libboost-headers=1.85.0=h694c41f_4 @@ -129,17 +129,17 @@ dependencies: - libbrotlicommon=1.1.0=h00291cd_2 - libbrotlidec=1.1.0=h00291cd_2 - libbrotlienc=1.1.0=h00291cd_2 - - libcblas=3.9.0=25_osx64_openblas + - libcblas=3.9.0=26_osx64_openblas - libclang-cpp17=17.0.6=default_hb173f14_7 - - libcurl=8.10.1=h58e7537_0 - - libcxx=19.1.4=hf95d169_0 + - libcurl=8.11.1=h5dec5d8_0 + - libcxx=19.1.6=hf95d169_1 - libcxx-devel=17.0.6=h8f8a49f_6 - - libdeflate=1.22=h00291cd_0 + - libdeflate=1.23=he65b83e_0 - libedit=3.1.20191231=h0678c8f_2 - libev=4.33=h10d778d_2 - libexpat=2.6.4=h240833e_0 - libffi=3.4.2=h0d85af4_5 - - libflint=3.0.1=h1d27844_103 + - libflint=3.1.2=h1d27844_101 - libgd=2.3.3=h2e77e4f_10 - libgettextpo=0.22.5=hdfe23c8_3 - libgettextpo-devel=0.22.5=hdfe23c8_3 @@ -151,136 +151,140 @@ dependencies: - libintl=0.22.5=hdfe23c8_3 - libintl-devel=0.22.5=hdfe23c8_3 - libjpeg-turbo=3.0.0=h0dc2134_1 - - liblapack=3.9.0=25_osx64_openblas - - liblapacke=3.9.0=25_osx64_openblas + - liblapack=3.9.0=26_osx64_openblas + - liblapacke=3.9.0=26_osx64_openblas - libllvm17=17.0.6=hbedff68_1 + - liblzma=5.6.3=hd471939_1 + - liblzma-devel=5.6.3=hd471939_1 - libnghttp2=1.64.0=hc7306c3_0 - libopenblas=0.3.28=openmp_hbf64a52_1 - libpng=1.6.44=h4b8f8c9_0 - libsodium=1.0.20=hfdf4475_0 - - libsqlite=3.47.0=h2f8c449_1 + - libsqlite=3.47.2=hdb6dae5_0 - libssh2=1.11.1=h3dc7d44_0 - - libtiff=4.7.0=h583c2ba_1 + - libtiff=4.7.0=hb77a491_3 - libwebp-base=1.4.0=h10d778d_0 - libxcb=1.17.0=hf1f96e2_0 - - libxml2=2.13.5=h495214b_0 + - libxml2=2.13.5=hebb159f_1 - libzlib=1.3.1=hd23fc13_2 - - linbox=1.7.0=h7061c92_0 - - llvm-openmp=19.1.4=ha54dae1_0 + - linbox=1.7.0=h9325161_1 + - llvm-openmp=19.1.6=ha54dae1_0 - llvm-tools=17.0.6=hbedff68_1 - lrcalc=2.1=hac325c4_7 - m4=1.4.18=haf1e3a3_1001 - m4ri=20140914=hd82a5f3_1006 - - m4rie=20150908=hc616cfc_1002 - - markupsafe=3.0.2=py311h8b4e8a7_0 - - matplotlib=3.9.2=py311h6eed73b_2 - - matplotlib-base=3.9.2=py311h8b21175_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 + - m4rie=20200125=hd82a5f3_0 + - markupsafe=3.0.2=py311ha3cf9ac_1 + - matplotlib=3.10.0=py311h6eed73b_0 + - matplotlib-base=3.10.0=py311h19a4563_0 + - matplotlib-inline=0.1.7=pyhd8ed1ab_1 - maxima=5.47.0=h3080a4d_3 - memory-allocator=0.1.3=py311h3336109_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 + - meson=1.6.1=pyhd8ed1ab_0 + - meson-python=0.17.1=pyh70fd9c4_1 - mpc=1.3.1=h9d8efa1_1 - mpfi=1.5.4=h52b28e3_1001 - mpfr=4.2.1=haed47dc_3 - - mpmath=1.3.0=pyhd8ed1ab_0 + - mpmath=1.3.0=pyhd8ed1ab_1 - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h10d778d_1 - ncurses=6.5=hf036a51_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_1 - networkx=3.4.2=pyh267e887_2 - ninja=1.12.1=h3c5361c_0 - ntl=11.4.3=h0ab3c2f_1 - numpy=1.26.4=py311hc43a94b_0 - openblas=0.3.28=openmp_h30af337_1 - - openjpeg=2.5.2=h7310d3a_0 + - openjpeg=2.5.3=h7fd6d84_0 - openssl=3.4.0=hd471939_0 - - packaging=24.2=pyhff2d567_1 + - packaging=24.2=pyhd8ed1ab_2 - palp=2.20=hbcb3906_0 - pari=2.15.5=h7ba67ff_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 + - parso=0.8.4=pyhd8ed1ab_1 - perl=5.32.1=7_h10d778d_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 + - pexpect=4.9.0=pyhd8ed1ab_1 + - pickleshare=0.7.5=pyhd8ed1ab_1004 - pillow=11.0.0=py311h1f68098_0 - - pip=24.3.1=pyh8b19718_0 + - pip=24.3.1=pyh8b19718_2 - pkg-config=0.29.2=hf7e621a_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgconfig=1.5.5=pyhd8ed1ab_5 - planarity=3.0.2.0=h10d778d_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 + - platformdirs=4.3.6=pyhd8ed1ab_1 + - pluggy=1.5.0=pyhd8ed1ab_1 - ppl=1.2=ha60d53e_1006 - pplpy=0.8.9=py311h922ec50_1 - primecount=7.6=ha894c9a_0 - primecountpy=0.1.0=py311h5fe6e05_4 - primesieve=11.0=hf0c8a7f_0 - - prompt-toolkit=3.0.48=pyha770c72_0 + - prompt-toolkit=3.0.48=pyha770c72_1 - psutil=6.1.0=py311h1314207_0 - pthread-stubs=0.4=h00291cd_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.11.10=ha513fb2_3_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 + - ptyprocess=0.7.0=pyhd8ed1ab_1 + - pure_eval=0.2.3=pyhd8ed1ab_1 + - pycparser=2.22=pyh29332c3_1 + - pygments=2.18.0=pyhd8ed1ab_1 + - pyparsing=3.2.0=pyhd8ed1ab_2 + - pyproject-metadata=0.9.0=pyhd8ed1ab_1 + - pysocks=1.7.1=pyha55dd90_7 + - pytest=8.3.4=pyhd8ed1ab_1 + - pytest-xdist=3.6.1=pyhd8ed1ab_1 + - python=3.11.11=h9ccd52b_1_cpython + - python-dateutil=2.9.0.post0=pyhff2d567_1 - python-lrcalc=2.1=py311hd89902b_7 - python_abi=3.11=5_cp311 - - pytz=2024.2=pyhd8ed1ab_0 + - pytz=2024.2=pyhd8ed1ab_1 - pyzmq=26.2.0=py311h4d3da15_3 - qd=2.3.22=h2beb688_1004 - qhull=2020.2=h3c5361c_5 - readline=8.2=h9e318b2_1 - - requests=2.32.3=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_1 - rw=0.9=h10d778d_2 - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - sagemath-db-graphs=20210214=hd8ed1ab_0 - sagemath-db-polytopes=20170220=1 - - scipy=1.14.1=py311hed734c1_1 + - scipy=1.14.1=py311h86b91e6_2 - setuptools=75.6.0=pyhff2d567_1 - sigtool=0.1.3=h88f4db0_0 - - singular=4.4.0=h0c52cc7_0 - - six=1.16.0=pyh6c4a22f_0 + - singular=4.4.0=h604985e_1 + - six=1.17.0=pyhd8ed1ab_0 - snowballstemmer=2.2.0=pyhd8ed1ab_0 - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=8.1.3=pyhd8ed1ab_0 + - sphinx=8.1.3=pyhd8ed1ab_1 - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=h6285a30_1 - - stack_data=0.6.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_1 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_1 + - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_1 + - sqlite=3.47.2=h2e4c9dc_0 + - stack_data=0.6.3=pyhd8ed1ab_1 - symmetrica=3.0.1=hf0c8a7f_0 - sympow=2.023.6=h115ba6a_3 - sympy=1.13.3=pyh2585a3b_104 - tachyon=0.99b6=h3a1d103_1002 - tapi=1300.6.5=h390ca13_0 - tk=8.6.13=h1abcd95_1 - - tomli=2.1.0=pyhff2d567_0 + - tomli=2.2.1=pyhd8ed1ab_1 - tornado=6.4.2=py311h4d7f069_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 + - traitlets=5.14.3=pyhd8ed1ab_1 + - typing_extensions=4.12.2=pyha770c72_1 - tzdata=2024b=hc8b5060_0 - unicodedata2=15.1.0=py311h1314207_1 - - urllib3=2.2.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=h00291cd_1 + - urllib3=2.2.3=pyhd8ed1ab_1 + - wcwidth=0.2.13=pyhd8ed1ab_1 + - wheel=0.45.1=pyhd8ed1ab_1 + - widgetsnbextension=4.0.13=pyhd8ed1ab_1 + - xorg-libxau=1.0.12=h6e16a3a_0 - xorg-libxdmcp=1.1.5=h00291cd_0 - - xz=5.2.6=h775f41a_0 + - xz=5.6.3=h357f2ed_1 + - xz-gpl-tools=5.6.3=h357f2ed_1 + - xz-tools=5.6.3=hd471939_1 - zeromq=4.3.5=h7130eaa_7 - zipp=3.21.0=pyhd8ed1ab_1 - zlib=1.3.1=hd23fc13_2 diff --git a/environment-3.11-macos.yml b/environment-3.11-macos.yml index 7a5da98494f..ec10b78a4b5 100644 --- a/environment-3.11-macos.yml +++ b/environment-3.11-macos.yml @@ -1,37 +1,37 @@ name: sage-dev # Generated by conda-lock. # platform: osx-arm64 -# input_hash: b9cf5847a6035915dcfdcda638f2e631b4f5776a7a21e332d8bc6ef819fc55c3 +# input_hash: 4396163dbc4fafd471282f306c16bb7bd73ecc3c006335c8faf512742014e1e4 channels: - conda-forge dependencies: - - alabaster=1.0.0=pyhd8ed1ab_0 - - appnope=0.1.4=pyhd8ed1ab_0 + - alabaster=1.0.0=pyhd8ed1ab_1 + - appnope=0.1.4=pyhd8ed1ab_1 - arpack=3.9.1=nompi_h593882a_101 - - asttokens=2.4.1=pyhd8ed1ab_0 + - asttokens=3.0.0=pyhd8ed1ab_1 - autoconf=2.71=pl5321hcd07c0c_1 - automake=1.17=pl5321hce30654_0 - - babel=2.16.0=pyhd8ed1ab_0 + - babel=2.16.0=pyhd8ed1ab_1 - bdw-gc=8.0.6=hc021e02_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - blas=2.125=openblas - - blas-devel=3.9.0=25_osxarm64_openblas + - beautifulsoup4=4.12.3=pyha770c72_1 + - blas=2.126=openblas + - blas-devel=3.9.0=26_osxarm64_openblas - boost-cpp=1.85.0=h103c1d6_4 - brial=1.2.12=pyh694c41f_3 - brotli=1.1.0=hd74edd7_2 - brotli-bin=1.1.0=hd74edd7_2 - brotli-python=1.1.0=py311h3f08180_2 - bzip2=1.0.8=h99b78c6_7 - - c-ares=1.34.3=h5505292_1 + - c-ares=1.34.4=h5505292_0 - c-compiler=1.8.0=hf48404e_1 - - ca-certificates=2024.8.30=hf0a4a13_0 + - ca-certificates=2024.12.14=hf0a4a13_0 - cctools=1010.6=hf67d63f_2 - cctools_osx-arm64=1010.6=h623e0ac_2 - cddlib=1!0.94m=h6d7a090_0 - - certifi=2024.8.30=pyhd8ed1ab_0 + - certifi=2024.12.14=pyhd8ed1ab_0 - cffi=1.17.1=py311h3a79f62_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 + - charset-normalizer=3.4.0=pyhd8ed1ab_1 - clang=17.0.6=default_h360f5da_7 - clang-17=17.0.6=default_h146c034_7 - clang_impl_osx-arm64=17.0.6=he47c785_23 @@ -40,28 +40,28 @@ dependencies: - clangxx_impl_osx-arm64=17.0.6=h50f59cd_23 - clangxx_osx-arm64=17.0.6=h07b0088_23 - cliquer=1.22=h93a5062_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 + - colorama=0.4.6=pyhd8ed1ab_1 + - comm=0.2.2=pyhd8ed1ab_1 - compiler-rt=17.0.6=h856b3c1_2 - compiler-rt_osx-arm64=17.0.6=h832e737_2 - contourpy=1.3.1=py311h210dab8_0 - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py311h4921393_0 - - cpython=3.11.10=py311hd8ed1ab_3 + - coverage=7.6.9=py311h4921393_0 + - cpython=3.11.11=py311hd8ed1ab_1 - cxx-compiler=1.8.0=h18dbf2f_1 - - cycler=0.12.1=pyhd8ed1ab_0 + - cycler=0.12.1=pyhd8ed1ab_1 - cypari2=2.1.5=py311h2c49a9d_0 - cysignals=1.11.2=py311he42fc87_3 - cython=3.0.11=py311hf7f79b8_3 - - debugpy=1.8.9=py311h155a34a_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 + - debugpy=1.8.11=py311h155a34a_0 + - decorator=5.1.1=pyhd8ed1ab_1 + - docutils=0.21.2=pyhd8ed1ab_1 - ecl=23.9.9=h1d9728a_0 - - eclib=20231212=h7f07de4_0 + - eclib=20231212=h3d50bd9_1 - ecm=7.0.5=h41d338b_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 + - exceptiongroup=1.2.2=pyhd8ed1ab_1 + - execnet=2.1.1=pyhd8ed1ab_1 + - executing=2.1.0=pyhd8ed1ab_1 - expat=2.6.4=h286801f_0 - fflas-ffpack=2.5.0=h4bc3318_0 - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 @@ -71,17 +71,17 @@ dependencies: - fontconfig=2.15.0=h1383a14_1 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 - - fonttools=4.55.0=py311h4921393_0 + - fonttools=4.55.3=py311h4921393_0 - fortran-compiler=1.8.0=hc3477c4_1 - fplll=5.4.5=hb7d509d_0 - fpylll=0.6.1=py311h341b96b_0 - freetype=2.12.1=hadb7bae_2 - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h4cbeff9_0 - - gap-defaults=4.13.1=hce30654_0 + - gap-core=4.14.0=h25f1785_1 + - gap-defaults=4.14.0=hce30654_1 - gettext=0.22.5=h8414b35_3 - gettext-tools=0.22.5=h8414b35_3 - - gf2x=1.3.0=hdaa854c_2 + - gf2x=1.3.0=hf8f8af4_3 - gfan=0.6.2=hec08f5c_1003 - gfortran=13.2.0=h1ca8e4b_1 - gfortran_impl_osx-arm64=13.2.0=h252ada1_3 @@ -90,27 +90,27 @@ dependencies: - givaro=4.2.0=h018886a_0 - glpk=5.0=h6d7a090_0 - gmp=6.3.0=h7bae524_2 - - gmpy2=2.1.5=py311hb5ce3a2_2 + - gmpy2=2.1.5=py311hb5d9ff4_3 - gsl=2.7=h6e638da_0 - - h2=4.1.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_1 + - hpack=4.0.0=pyhd8ed1ab_1 + - hyperframe=6.0.1=pyhd8ed1ab_1 - icu=75.1=hfee45f7_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=h3fe6531_0 + - idna=3.10=pyhd8ed1ab_1 + - igraph=0.10.15=h3fe6531_1 - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=hd73f12c_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 + - importlib-metadata=8.5.0=pyha770c72_1 + - iniconfig=2.0.0=pyhd8ed1ab_1 - ipykernel=6.29.5=pyh57ce528_0 - - ipython=8.29.0=pyh707e725_0 - - ipywidgets=8.1.5=pyhd8ed1ab_0 + - ipython=8.30.0=pyh707e725_0 + - ipywidgets=8.1.5=pyhd8ed1ab_1 - isl=0.26=imath32_h347afa1_101 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 + - jedi=0.19.2=pyhd8ed1ab_1 + - jinja2=3.1.4=pyhd8ed1ab_1 + - jupyter_client=8.6.3=pyhd8ed1ab_1 - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.13=pyhd8ed1ab_1 - kiwisolver=1.4.7=py311h2c37856_0 - krb5=1.21.3=h237132a_0 - lcalc=2.0.5=h4a402bc_2 @@ -120,7 +120,7 @@ dependencies: - lerc=4.0.0=h9a09cb3_0 - libasprintf=0.22.5=h8414b35_3 - libasprintf-devel=0.22.5=h8414b35_3 - - libblas=3.9.0=25_osxarm64_openblas + - libblas=3.9.0=26_osxarm64_openblas - libboost=1.85.0=hf763ba5_4 - libboost-devel=1.85.0=hf450f58_4 - libboost-headers=1.85.0=hce30654_4 @@ -129,17 +129,17 @@ dependencies: - libbrotlicommon=1.1.0=hd74edd7_2 - libbrotlidec=1.1.0=hd74edd7_2 - libbrotlienc=1.1.0=hd74edd7_2 - - libcblas=3.9.0=25_osxarm64_openblas + - libcblas=3.9.0=26_osxarm64_openblas - libclang-cpp17=17.0.6=default_h146c034_7 - - libcurl=8.10.1=h13a7ad3_0 - - libcxx=19.1.4=ha82da77_0 + - libcurl=8.11.1=h73640d1_0 + - libcxx=19.1.6=ha82da77_1 - libcxx-devel=17.0.6=h86353a2_6 - - libdeflate=1.22=hd74edd7_0 + - libdeflate=1.23=hec38601_0 - libedit=3.1.20191231=hc8eb9b7_2 - libev=4.33=h93a5062_2 - libexpat=2.6.4=h286801f_0 - libffi=3.4.2=h3422bc3_5 - - libflint=3.0.1=he28cf6d_103 + - libflint=3.1.2=he28cf6d_101 - libgd=2.3.3=hac1b3a8_10 - libgettextpo=0.22.5=h8414b35_3 - libgettextpo-devel=0.22.5=h8414b35_3 @@ -152,137 +152,141 @@ dependencies: - libintl=0.22.5=h8414b35_3 - libintl-devel=0.22.5=h8414b35_3 - libjpeg-turbo=3.0.0=hb547adb_1 - - liblapack=3.9.0=25_osxarm64_openblas - - liblapacke=3.9.0=25_osxarm64_openblas + - liblapack=3.9.0=26_osxarm64_openblas + - liblapacke=3.9.0=26_osxarm64_openblas - libllvm17=17.0.6=h5090b49_2 + - liblzma=5.6.3=h39f12f2_1 + - liblzma-devel=5.6.3=h39f12f2_1 - libnghttp2=1.64.0=h6d7220d_0 - libopenblas=0.3.28=openmp_hf332438_1 - libpng=1.6.44=hc14010f_0 - libsodium=1.0.20=h99b78c6_0 - - libsqlite=3.47.0=hbaaea75_1 + - libsqlite=3.47.2=h3f77e49_0 - libssh2=1.11.1=h9cc3647_0 - - libtiff=4.7.0=hfce79cd_1 + - libtiff=4.7.0=h551f018_3 - libwebp-base=1.4.0=h93a5062_0 - libxcb=1.17.0=hdb1d25a_0 - - libxml2=2.13.5=hbbdcc80_0 + - libxml2=2.13.5=h178c5d8_1 - libzlib=1.3.1=h8359307_2 - - linbox=1.7.0=h3afee3a_0 - - llvm-openmp=19.1.4=hdb05f8b_0 + - linbox=1.7.0=h9da6ecd_1 + - llvm-openmp=19.1.6=hdb05f8b_0 - llvm-tools=17.0.6=h5090b49_2 - lrcalc=2.1=hf9b8971_7 - m4=1.4.18=h642e427_1001 - m4ri=20140914=hc97c1ff_1006 - - m4rie=20150908=h22b9e9d_1002 - - markupsafe=3.0.2=py311h56c23cb_0 - - matplotlib=3.9.2=py311ha1ab1f8_2 - - matplotlib-base=3.9.2=py311hbe3227e_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 + - m4rie=20200125=hc97c1ff_0 + - markupsafe=3.0.2=py311h4921393_1 + - matplotlib=3.10.0=py311ha1ab1f8_0 + - matplotlib-base=3.10.0=py311h031da69_0 + - matplotlib-inline=0.1.7=pyhd8ed1ab_1 - maxima=5.47.0=h2bbcd85_2 - memory-allocator=0.1.3=py311h460d6c5_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 + - meson=1.6.1=pyhd8ed1ab_0 + - meson-python=0.17.1=pyh70fd9c4_1 - mpc=1.3.1=h8f1351a_1 - mpfi=1.5.4=hbde5f5b_1001 - mpfr=4.2.1=hb693164_3 - - mpmath=1.3.0=pyhd8ed1ab_0 + - mpmath=1.3.0=pyhd8ed1ab_1 - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h93a5062_1 - ncurses=6.5=h7bae524_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_1 - networkx=3.4.2=pyh267e887_2 - ninja=1.12.1=h420ef59_0 - ntl=11.4.3=hbb3f309_1 - numpy=1.26.4=py311h7125741_0 - openblas=0.3.28=openmp_hea878ba_1 - - openjpeg=2.5.2=h9f1df11_0 + - openjpeg=2.5.3=h8a3d83b_0 - openssl=3.4.0=h39f12f2_0 - - packaging=24.2=pyhff2d567_1 + - packaging=24.2=pyhd8ed1ab_2 - palp=2.20=h27ca646_0 - pari=2.15.5=h4f2304c_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 + - parso=0.8.4=pyhd8ed1ab_1 - pcre2=10.44=h297a79d_2 - perl=5.32.1=7_h4614cfb_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 + - pexpect=4.9.0=pyhd8ed1ab_1 + - pickleshare=0.7.5=pyhd8ed1ab_1004 - pillow=11.0.0=py311h3894ae9_0 - - pip=24.3.1=pyh8b19718_0 + - pip=24.3.1=pyh8b19718_2 - pkg-config=0.29.2=hde07d2e_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgconfig=1.5.5=pyhd8ed1ab_5 - planarity=3.0.2.0=h93a5062_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 + - platformdirs=4.3.6=pyhd8ed1ab_1 + - pluggy=1.5.0=pyhd8ed1ab_1 - ppl=1.2=h8b147cf_1006 - pplpy=0.8.9=py311h3d77d83_1 - primecount=7.6=hb6e4faa_0 - primecountpy=0.1.0=py311he4fd1f5_4 - primesieve=11.0=hb7217d7_0 - - prompt-toolkit=3.0.48=pyha770c72_0 + - prompt-toolkit=3.0.48=pyha770c72_1 - psutil=6.1.0=py311hae2e1ce_0 - pthread-stubs=0.4=hd74edd7_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.11.10=hc51fdd5_3_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 + - ptyprocess=0.7.0=pyhd8ed1ab_1 + - pure_eval=0.2.3=pyhd8ed1ab_1 + - pycparser=2.22=pyh29332c3_1 + - pygments=2.18.0=pyhd8ed1ab_1 + - pyparsing=3.2.0=pyhd8ed1ab_2 + - pyproject-metadata=0.9.0=pyhd8ed1ab_1 + - pysocks=1.7.1=pyha55dd90_7 + - pytest=8.3.4=pyhd8ed1ab_1 + - pytest-xdist=3.6.1=pyhd8ed1ab_1 + - python=3.11.11=hc22306f_1_cpython + - python-dateutil=2.9.0.post0=pyhff2d567_1 - python-lrcalc=2.1=py311h3f08180_7 - python_abi=3.11=5_cp311 - - pytz=2024.2=pyhd8ed1ab_0 + - pytz=2024.2=pyhd8ed1ab_1 - pyzmq=26.2.0=py311h730b646_3 - qd=2.3.22=hbec66e7_1004 - qhull=2020.2=h420ef59_5 - readline=8.2=h92ec313_1 - - requests=2.32.3=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_1 - rw=0.9=h93a5062_2 - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - sagemath-db-graphs=20210214=hd8ed1ab_0 - sagemath-db-polytopes=20170220=1 - - scipy=1.14.1=py311hf1db568_1 + - scipy=1.14.1=py311hf056e50_2 - setuptools=75.6.0=pyhff2d567_1 - sigtool=0.1.3=h44b9a77_0 - - singular=4.4.0=h8aafc33_0 - - six=1.16.0=pyh6c4a22f_0 + - singular=4.4.0=h5a8969a_1 + - six=1.17.0=pyhd8ed1ab_0 - snowballstemmer=2.2.0=pyhd8ed1ab_0 - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=8.1.3=pyhd8ed1ab_0 + - sphinx=8.1.3=pyhd8ed1ab_1 - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=hcd14bea_1 - - stack_data=0.6.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_1 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_1 + - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_1 + - sqlite=3.47.2=hd7222ec_0 + - stack_data=0.6.3=pyhd8ed1ab_1 - symmetrica=3.0.1=hb7217d7_0 - sympow=2.023.6=hb0babe8_3 - sympy=1.13.3=pyh2585a3b_104 - tachyon=0.99b6=hb8a568e_1002 - tapi=1300.6.5=h03f4b80_0 - tk=8.6.13=h5083fa2_1 - - tomli=2.1.0=pyhff2d567_0 + - tomli=2.2.1=pyhd8ed1ab_1 - tornado=6.4.2=py311h917b07b_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 + - traitlets=5.14.3=pyhd8ed1ab_1 + - typing_extensions=4.12.2=pyha770c72_1 - tzdata=2024b=hc8b5060_0 - unicodedata2=15.1.0=py311hae2e1ce_1 - - urllib3=2.2.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=hd74edd7_1 + - urllib3=2.2.3=pyhd8ed1ab_1 + - wcwidth=0.2.13=pyhd8ed1ab_1 + - wheel=0.45.1=pyhd8ed1ab_1 + - widgetsnbextension=4.0.13=pyhd8ed1ab_1 + - xorg-libxau=1.0.12=h5505292_0 - xorg-libxdmcp=1.1.5=hd74edd7_0 - - xz=5.2.6=h57fd34a_0 + - xz=5.6.3=h9a6d368_1 + - xz-gpl-tools=5.6.3=h9a6d368_1 + - xz-tools=5.6.3=h39f12f2_1 - zeromq=4.3.5=hc1bb282_7 - zipp=3.21.0=pyhd8ed1ab_1 - zlib=1.3.1=h8359307_2 diff --git a/environment-3.10-linux-aarch64.yml b/environment-3.12-linux-aarch64.yml similarity index 54% rename from environment-3.10-linux-aarch64.yml rename to environment-3.12-linux-aarch64.yml index f5504885ec5..b97f90268d1 100644 --- a/environment-3.10-linux-aarch64.yml +++ b/environment-3.12-linux-aarch64.yml @@ -1,64 +1,64 @@ name: sage-dev # Generated by conda-lock. # platform: linux-aarch64 -# input_hash: db49741f7e4afa9923e001ba84b429b390761405055f59782e7fd09d34903087 +# input_hash: 28dba81f3f7cbaa4e6f35a34c9679049f47c3d73414a0a80eda04a53603e8a12 channels: - conda-forge dependencies: - _openmp_mutex=4.5=2_kmp_llvm - - alabaster=1.0.0=pyhd8ed1ab_0 + - alabaster=1.0.0=pyhd8ed1ab_1 - alsa-lib=1.2.13=h86ecc28_0 - arpack=3.9.1=nompi_hd363cd0_101 - - asttokens=2.4.1=pyhd8ed1ab_0 + - asttokens=3.0.0=pyhd8ed1ab_1 - autoconf=2.71=pl5321h2148fe1_1 - automake=1.17=pl5321h8af1aa0_0 - - babel=2.16.0=pyhd8ed1ab_0 + - babel=2.16.0=pyhd8ed1ab_1 - bdw-gc=8.0.6=hd62202e_0 - - beautifulsoup4=4.12.3=pyha770c72_0 + - beautifulsoup4=4.12.3=pyha770c72_1 - binutils=2.43=hf1166c9_2 - binutils_impl_linux-aarch64=2.43=h4c662bb_2 - binutils_linux-aarch64=2.43=hf1166c9_2 - - blas=2.125=openblas - - blas-devel=3.9.0=25_linuxaarch64_openblas + - blas=2.126=openblas + - blas-devel=3.9.0=26_linuxaarch64_openblas - boost-cpp=1.85.0=hdad291f_4 - brial=1.2.12=pyh694c41f_3 - brotli=1.1.0=h86ecc28_2 - brotli-bin=1.1.0=h86ecc28_2 - - brotli-python=1.1.0=py310he30c3ed_2 + - brotli-python=1.1.0=py312h6f74592_2 - bzip2=1.0.8=h68df207_7 - - c-ares=1.34.3=h86ecc28_1 + - c-ares=1.34.4=h86ecc28_0 - c-compiler=1.8.0=h6561dab_1 - - ca-certificates=2024.8.30=hcefe29a_0 - - cairo=1.18.0=hdb1a16f_3 + - ca-certificates=2024.12.14=hcefe29a_0 + - cairo=1.18.2=h83712da_1 - cddlib=1!0.94m=h719063d_0 - - certifi=2024.8.30=pyhd8ed1ab_0 - - cffi=1.17.1=py310h1451162_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 + - certifi=2024.12.14=pyhd8ed1ab_0 + - cffi=1.17.1=py312hac81daf_0 + - charset-normalizer=3.4.0=pyhd8ed1ab_1 - cliquer=1.22=h31becfc_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 - - contourpy=1.3.1=py310hf54e67a_0 + - colorama=0.4.6=pyhd8ed1ab_1 + - comm=0.2.2=pyhd8ed1ab_1 + - contourpy=1.3.1=py312h451a7dd_0 - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py310h66848f9_0 - - cpython=3.10.15=py310hd8ed1ab_2 + - coverage=7.6.9=py312h74ce7d3_0 + - cpython=3.12.8=py312hd8ed1ab_1 - cxx-compiler=1.8.0=heb6c788_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py310h4cbba44_0 + - cycler=0.12.1=pyhd8ed1ab_1 + - cypari2=2.1.5=py312h7f7bc3d_0 - cyrus-sasl=2.1.27=hf6b2984_7 - - cysignals=1.11.2=py310h485802a_3 - - cython=3.0.11=py310he223470_3 + - cysignals=1.11.2=py312haf3d6d2_3 + - cython=3.0.11=py312hdfe4e29_3 - dbus=1.13.6=h12b9eeb_3 - - debugpy=1.8.9=py310he30c3ed_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 + - debugpy=1.8.11=py312h6f74592_0 + - decorator=5.1.1=pyhd8ed1ab_1 + - docutils=0.21.2=pyhd8ed1ab_1 - double-conversion=3.3.0=h2f0025b_0 - ecl=24.5.10=h5567cc5_0 - - eclib=20231212=he26bab5_0 + - eclib=20231212=h154513d_1 - ecm=7.0.5=ha2d0fc4_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 + - exceptiongroup=1.2.2=pyhd8ed1ab_1 + - execnet=2.1.1=pyhd8ed1ab_1 + - executing=2.1.0=pyhd8ed1ab_1 - expat=2.6.4=h5ad3122_0 - fflas-ffpack=2.5.0=h503e619_0 - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 @@ -68,18 +68,18 @@ dependencies: - fontconfig=2.15.0=h8dda3cd_1 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 - - fonttools=4.55.0=py310heeae437_0 + - fonttools=4.55.3=py312hcc812fe_0 - fortran-compiler=1.8.0=h25a59a9_1 - fplll=5.4.5=hb3a790e_0 - - fpylll=0.6.1=py310hfdbf2a6_0 + - fpylll=0.6.1=py312h8b93be1_0 - freetype=2.12.1=hf0a5ef3_2 - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h16511ff_0 - - gap-defaults=4.13.1=h8af1aa0_0 + - gap-core=4.14.0=h1754e88_1 + - gap-defaults=4.14.0=h8af1aa0_1 - gcc=13.3.0=h8a56e6e_1 - gcc_impl_linux-aarch64=13.3.0=hcdea9b6_1 - gcc_linux-aarch64=13.3.0=h1cd514b_7 - - gf2x=1.3.0=h1b3b3a3_2 + - gf2x=1.3.0=h9af5f66_3 - gfan=0.6.2=h5f589ec_1003 - gfortran=13.3.0=h8a56e6e_1 - gfortran_impl_linux-aarch64=13.3.0=h174a3c4_1 @@ -88,40 +88,40 @@ dependencies: - givaro=4.2.0=h364d21b_0 - glpk=5.0=h66325d0_0 - gmp=6.3.0=h0a1ffab_2 - - gmpy2=2.1.5=py310h615e639_2 + - gmpy2=2.1.5=py312he9d48ea_3 - graphite2=1.3.13=h2f0025b_1003 - gsl=2.7=h294027d_0 - gxx=13.3.0=h8a56e6e_1 - gxx_impl_linux-aarch64=13.3.0=h1211b58_1 - gxx_linux-aarch64=13.3.0=h2864abd_7 - - h2=4.1.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_1 - harfbuzz=9.0.0=hbf49d6b_1 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 + - hpack=4.0.0=pyhd8ed1ab_1 + - hyperframe=6.0.1=pyhd8ed1ab_1 - icu=75.1=hf9b3779_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=h207f3e5_0 + - idna=3.10=pyhd8ed1ab_1 + - igraph=0.10.15=h207f3e5_1 - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h15043fe_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 + - importlib-metadata=8.5.0=pyha770c72_1 + - iniconfig=2.0.0=pyhd8ed1ab_1 - ipykernel=6.29.5=pyh3099207_0 - - ipython=8.29.0=pyh707e725_0 - - ipywidgets=8.1.5=pyhd8ed1ab_0 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 + - ipython=8.30.0=pyh707e725_0 + - ipywidgets=8.1.5=pyhd8ed1ab_1 + - jedi=0.19.2=pyhd8ed1ab_1 + - jinja2=3.1.4=pyhd8ed1ab_1 + - jupyter_client=8.6.3=pyhd8ed1ab_1 - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.13=pyhd8ed1ab_1 - kernel-headers_linux-aarch64=4.18.0=h05a177a_18 - keyutils=1.6.1=h4e544f5_0 - - kiwisolver=1.4.7=py310h5d7f10c_0 + - kiwisolver=1.4.7=py312h88dc405_0 - krb5=1.21.3=h50a48e9_0 - lcalc=2.0.5=he588f68_2 - lcms2=2.16=h922389a_0 - ld_impl_linux-aarch64=2.43=h80caac9_2 - lerc=4.0.0=h4de3ea5_0 - - libblas=3.9.0=25_linuxaarch64_openblas + - libblas=3.9.0=26_linuxaarch64_openblas - libboost=1.85.0=h9fa81b4_4 - libboost-devel=1.85.0=h37bb5a9_4 - libboost-headers=1.85.0=h8af1aa0_4 @@ -130,19 +130,19 @@ dependencies: - libbrotlicommon=1.1.0=h86ecc28_2 - libbrotlidec=1.1.0=h86ecc28_2 - libbrotlienc=1.1.0=h86ecc28_2 - - libcblas=3.9.0=25_linuxaarch64_openblas - - libclang-cpp19.1=19.1.4=default_he324ac1_0 - - libclang13=19.1.4=default_h4390ef5_0 + - libcblas=3.9.0=26_linuxaarch64_openblas + - libclang-cpp19.1=19.1.6=default_he324ac1_0 + - libclang13=19.1.6=default_h4390ef5_0 - libcups=2.3.3=h405e4a8_4 - - libcurl=8.10.1=h3ec0cbf_0 - - libdeflate=1.22=h86ecc28_0 - - libdrm=2.4.123=h86ecc28_0 + - libcurl=8.11.1=h6702fde_0 + - libdeflate=1.23=h5e3c512_0 + - libdrm=2.4.124=h86ecc28_0 - libedit=3.1.20191231=he28a2e2_2 - libegl=1.7.0=hd24410f_2 - libev=4.33=h31becfc_2 - libexpat=2.6.4=h5ad3122_0 - libffi=3.4.2=h3557bc0_5 - - libflint=3.0.1=h0433c20_103 + - libflint=3.1.2=h0433c20_101 - libgcc=14.2.0=he277a41_1 - libgcc-devel_linux-aarch64=13.3.0=h0c07274_101 - libgcc-ng=14.2.0=he9431aa_1 @@ -158,9 +158,11 @@ dependencies: - libhomfly=1.02r6=h31becfc_1 - libiconv=1.17=h31becfc_2 - libjpeg-turbo=3.0.0=h31becfc_1 - - liblapack=3.9.0=25_linuxaarch64_openblas - - liblapacke=3.9.0=25_linuxaarch64_openblas - - libllvm19=19.1.4=h2edbd07_1 + - liblapack=3.9.0=26_linuxaarch64_openblas + - liblapacke=3.9.0=26_linuxaarch64_openblas + - libllvm19=19.1.6=h2edbd07_0 + - liblzma=5.6.3=h86ecc28_1 + - liblzma-devel=5.6.3=h86ecc28_1 - libnghttp2=1.64.0=hc8609a4_0 - libnsl=2.0.1=h31becfc_0 - libntlm=1.4=hf897c2e_1002 @@ -168,142 +170,142 @@ dependencies: - libopengl=1.7.0=hd24410f_2 - libpciaccess=0.18=h31becfc_0 - libpng=1.6.44=hc4a20ef_0 - - libpq=17.2=h081282e_0 + - libpq=17.2=hd56632b_1 - libsanitizer=13.3.0=ha58e236_1 - libsodium=1.0.20=h68df207_0 - - libsqlite=3.47.0=hc4a20ef_1 + - libsqlite=3.47.2=h5eb1b54_0 - libssh2=1.11.1=ha41c0db_0 - libstdcxx=14.2.0=h3f4de04_1 - libstdcxx-devel_linux-aarch64=13.3.0=h0c07274_101 - libstdcxx-ng=14.2.0=hf1166c9_1 - - libtiff=4.7.0=hec21d91_1 + - libtiff=4.7.0=h88f7998_3 - libuuid=2.38.1=hb4cce97_0 - libwebp-base=1.4.0=h31becfc_0 - libxcb=1.17.0=h262b8f6_0 - libxcrypt=4.4.36=h31becfc_1 - libxkbcommon=1.7.0=h46f2afe_1 - - libxml2=2.13.5=hf4efe5d_0 + - libxml2=2.13.5=h2e0c361_1 - libxslt=1.1.39=h1cc9640_0 - libzlib=1.3.1=h86ecc28_2 - - linbox=1.7.0=h681a5ee_0 - - llvm-openmp=19.1.4=h013ceaa_0 + - linbox=1.7.0=hf74d613_1 + - llvm-openmp=19.1.6=h013ceaa_0 - lrcalc=2.1=h5ad3122_7 - m4=1.4.18=h516909a_1001 - m4ri=20140914=hedfd65a_1006 - - m4rie=20150908=hf0a5ef3_1002 - - markupsafe=3.0.2=py310h66848f9_0 - - matplotlib=3.9.2=py310hbbe02a8_2 - - matplotlib-base=3.9.2=py310h2cc5e2d_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 + - m4rie=20200125=hedfd65a_0 + - markupsafe=3.0.2=py312h74ce7d3_1 + - matplotlib=3.10.0=py312h8025657_0 + - matplotlib-base=3.10.0=py312h965bf68_0 + - matplotlib-inline=0.1.7=pyhd8ed1ab_1 - maxima=5.47.0=h043f013_3 - - memory-allocator=0.1.3=py310ha766c32_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 + - memory-allocator=0.1.3=py312hb2c0f52_1 + - meson=1.6.1=pyhd8ed1ab_0 + - meson-python=0.17.1=pyh70fd9c4_1 - mpc=1.3.1=h783934e_1 - mpfi=1.5.4=h846f343_1001 - mpfr=4.2.1=h2305555_3 - - mpmath=1.3.0=pyhd8ed1ab_0 + - mpmath=1.3.0=pyhd8ed1ab_1 - munkres=1.1.4=pyh9f0ad1d_0 - - mysql-common=9.0.1=h3f5c77f_2 - - mysql-libs=9.0.1=h11569fd_2 + - mysql-common=9.0.1=h3f5c77f_3 + - mysql-libs=9.0.1=h11569fd_3 - nauty=2.8.8=h31becfc_1 - ncurses=6.5=hcccb83c_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_1 - networkx=3.4.2=pyh267e887_2 - ninja=1.12.1=h70be974_0 - ntl=11.4.3=h0d7519b_1 - - numpy=1.26.4=py310hcbab775_0 + - numpy=1.26.4=py312h470d778_0 - openblas=0.3.28=pthreads_h3a8cbd8_1 - - openjpeg=2.5.2=h0d9d63b_0 + - openjpeg=2.5.3=h3f56577_0 - openldap=2.6.9=h30c48ee_0 - openssl=3.4.0=h86ecc28_0 - - packaging=24.2=pyhff2d567_1 + - packaging=24.2=pyhd8ed1ab_2 - palp=2.20=hb9de7d4_0 - pari=2.15.5=h169c2a7_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 + - parso=0.8.4=pyhd8ed1ab_1 - pcre2=10.44=h070dd5b_2 - perl=5.32.1=7_h31becfc_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=11.0.0=py310h825f53c_0 - - pip=24.3.1=pyh8b19718_0 - - pixman=0.43.4=h2f0025b_0 + - pexpect=4.9.0=pyhd8ed1ab_1 + - pickleshare=0.7.5=pyhd8ed1ab_1004 + - pillow=11.0.0=py312h5ab5af3_0 + - pip=24.3.1=pyh8b19718_2 + - pixman=0.44.2=h86a87f0_0 - pkg-config=0.29.2=hce167ba_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgconfig=1.5.5=pyhd8ed1ab_5 - planarity=3.0.2.0=h31becfc_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 + - platformdirs=4.3.6=pyhd8ed1ab_1 + - pluggy=1.5.0=pyhd8ed1ab_1 - ppl=1.2=h984aac9_1006 - - pplpy=0.8.9=py310h6665419_1 + - pplpy=0.8.9=py312hbd99ab9_1 - primecount=7.9=hd600fc2_0 - - primecountpy=0.1.0=py310h586407a_4 + - primecountpy=0.1.0=py312h8f0b210_4 - primesieve=11.1=h2f0025b_0 - - prompt-toolkit=3.0.48=pyha770c72_0 - - psutil=6.1.0=py310ha766c32_0 + - prompt-toolkit=3.0.48=pyha770c72_1 + - psutil=6.1.0=py312hb2c0f52_0 - pthread-stubs=0.4=h86ecc28_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pyside6=6.8.0.2=py310hee8ad4f_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.10.15=hbf90c55_2_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 - - python-lrcalc=2.1=py310he30c3ed_7 - - python_abi=3.10=5_cp310 - - pytz=2024.2=pyhd8ed1ab_0 - - pyzmq=26.2.0=py310h55e1596_3 + - ptyprocess=0.7.0=pyhd8ed1ab_1 + - pure_eval=0.2.3=pyhd8ed1ab_1 + - pycparser=2.22=pyh29332c3_1 + - pygments=2.18.0=pyhd8ed1ab_1 + - pyparsing=3.2.0=pyhd8ed1ab_2 + - pyproject-metadata=0.9.0=pyhd8ed1ab_1 + - pyside6=6.8.1=py312hdd999d0_0 + - pysocks=1.7.1=pyha55dd90_7 + - pytest=8.3.4=pyhd8ed1ab_1 + - pytest-xdist=3.6.1=pyhd8ed1ab_1 + - python=3.12.8=h1683364_1_cpython + - python-dateutil=2.9.0.post0=pyhff2d567_1 + - python-lrcalc=2.1=py312h6f74592_7 + - python_abi=3.12=5_cp312 + - pytz=2024.2=pyhd8ed1ab_1 + - pyzmq=26.2.0=py312h2427ae1_3 - qd=2.3.22=h05efe27_1004 - qhull=2020.2=h70be974_5 - - qt6-main=6.8.0=h666f7c6_0 + - qt6-main=6.8.1=h0d3cc05_0 - readline=8.2=h8fc344f_1 - - requests=2.32.3=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_1 - rw=0.9=h31becfc_2 - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - sagemath-db-graphs=20210214=hd8ed1ab_0 - sagemath-db-polytopes=20170220=1 - - scipy=1.14.1=py310h317fb5c_1 + - scipy=1.14.1=py312hcbff3fa_2 - setuptools=75.6.0=pyhff2d567_1 - - singular=4.4.0=h9a92511_0 - - six=1.16.0=pyh6c4a22f_0 + - singular=4.4.0=hee12f27_1 + - six=1.17.0=pyhd8ed1ab_0 - snowballstemmer=2.2.0=pyhd8ed1ab_0 - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=8.1.3=pyhd8ed1ab_0 + - sphinx=8.1.3=pyhd8ed1ab_1 - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=h578a6b9_1 - - stack_data=0.6.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_1 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_1 + - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_1 + - sqlite=3.47.2=h578a6b9_0 + - stack_data=0.6.3=pyhd8ed1ab_1 - symmetrica=3.0.1=hd600fc2_0 - sympow=2.023.6=h157afb5_3 - sympy=1.13.3=pyh2585a3b_104 - sysroot_linux-aarch64=2.17=h5b4a56d_18 - tachyon=0.99b6=ha0bfc61_1002 - tk=8.6.13=h194ca79_0 - - tomli=2.1.0=pyhff2d567_0 - - tornado=6.4.2=py310h78583b1_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 + - tomli=2.2.1=pyhd8ed1ab_1 + - tornado=6.4.2=py312h52516f5_0 + - traitlets=5.14.3=pyhd8ed1ab_1 + - typing_extensions=4.12.2=pyha770c72_1 - tzdata=2024b=hc8b5060_0 - - unicodedata2=15.1.0=py310ha766c32_1 - - urllib3=2.2.3=pyhd8ed1ab_0 + - unicodedata2=15.1.0=py312hb2c0f52_1 + - urllib3=2.2.3=pyhd8ed1ab_1 - wayland=1.23.1=h698ed42_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_1 + - wheel=0.45.1=pyhd8ed1ab_1 + - widgetsnbextension=4.0.13=pyhd8ed1ab_1 - xcb-util=0.4.1=h5c728e9_2 - xcb-util-cursor=0.1.5=h86ecc28_0 - xcb-util-image=0.4.0=h5c728e9_2 @@ -311,10 +313,10 @@ dependencies: - xcb-util-renderutil=0.3.10=h5c728e9_0 - xcb-util-wm=0.4.2=h5c728e9_0 - xkeyboard-config=2.43=h86ecc28_0 - - xorg-libice=1.1.1=h57736b2_1 - - xorg-libsm=1.2.4=hbac51e1_1 - - xorg-libx11=1.8.9=he755bbd_2 - - xorg-libxau=1.0.11=h86ecc28_1 + - xorg-libice=1.1.2=h86ecc28_0 + - xorg-libsm=1.2.5=h0808dbd_0 + - xorg-libx11=1.8.10=hca56bd8_1 + - xorg-libxau=1.0.12=h86ecc28_0 - xorg-libxcomposite=0.4.6=h86ecc28_2 - xorg-libxcursor=1.2.3=h86ecc28_0 - xorg-libxdamage=1.1.6=h86ecc28_0 @@ -323,13 +325,14 @@ dependencies: - xorg-libxfixes=6.0.1=h57736b2_0 - xorg-libxi=1.8.2=h57736b2_0 - xorg-libxrandr=1.5.4=h86ecc28_0 - - xorg-libxrender=0.9.11=h57736b2_1 + - xorg-libxrender=0.9.12=h86ecc28_0 - xorg-libxtst=1.2.5=h57736b2_3 - - xorg-libxxf86vm=1.1.5=h57736b2_4 - - xorg-xorgproto=2024.1=h86ecc28_1 - - xz=5.2.6=h9cdd2b7_0 + - xorg-libxxf86vm=1.1.6=h86ecc28_0 + - xz=5.6.3=h2dbfc1b_1 + - xz-gpl-tools=5.6.3=h2dbfc1b_1 + - xz-tools=5.6.3=h86ecc28_1 - zeromq=4.3.5=h5efb499_7 - zipp=3.21.0=pyhd8ed1ab_1 - zlib=1.3.1=h86ecc28_2 - - zstandard=0.23.0=py310h6a57b22_1 + - zstandard=0.23.0=py312hb698573_1 - zstd=1.5.6=h02f22dd_0 diff --git a/environment-3.10-linux.yml b/environment-3.12-linux.yml similarity index 54% rename from environment-3.10-linux.yml rename to environment-3.12-linux.yml index 2a6bea964fd..7b2496e151e 100644 --- a/environment-3.10-linux.yml +++ b/environment-3.12-linux.yml @@ -1,65 +1,65 @@ name: sage-dev # Generated by conda-lock. # platform: linux-64 -# input_hash: 03730b69363db4869061e8fcbd2108c24d97003d10dd9719ff461b66cc7d1046 +# input_hash: 40be535db1c7eaa6a4654bde814ad7958eb5c8b150e3158a6897927158b3bd6f channels: - conda-forge dependencies: - _libgcc_mutex=0.1=conda_forge - _openmp_mutex=4.5=2_kmp_llvm - - alabaster=1.0.0=pyhd8ed1ab_0 + - alabaster=1.0.0=pyhd8ed1ab_1 - alsa-lib=1.2.13=hb9d3cd8_0 - arpack=3.9.1=nompi_h77f6705_101 - - asttokens=2.4.1=pyhd8ed1ab_0 + - asttokens=3.0.0=pyhd8ed1ab_1 - autoconf=2.71=pl5321h2b4cb7a_1 - automake=1.17=pl5321ha770c72_0 - - babel=2.16.0=pyhd8ed1ab_0 + - babel=2.16.0=pyhd8ed1ab_1 - bdw-gc=8.0.6=h4bd325d_0 - - beautifulsoup4=4.12.3=pyha770c72_0 + - beautifulsoup4=4.12.3=pyha770c72_1 - binutils=2.43=h4852527_2 - binutils_impl_linux-64=2.43=h4bf12b8_2 - binutils_linux-64=2.43=h4852527_2 - - blas=2.125=openblas - - blas-devel=3.9.0=25_linux64_openblas + - blas=2.126=openblas + - blas-devel=3.9.0=26_linux64_openblas - boost-cpp=1.85.0=h3c6214e_4 - brial=1.2.12=pyh694c41f_3 - brotli=1.1.0=hb9d3cd8_2 - brotli-bin=1.1.0=hb9d3cd8_2 - - brotli-python=1.1.0=py310hf71b8c6_2 + - brotli-python=1.1.0=py312h2ec8cdc_2 - bzip2=1.0.8=h4bc722e_7 - - c-ares=1.34.3=hb9d3cd8_1 + - c-ares=1.34.4=hb9d3cd8_0 - c-compiler=1.8.0=h2b85faf_1 - - ca-certificates=2024.8.30=hbcca054_0 - - cairo=1.18.0=hebfffa5_3 + - ca-certificates=2024.12.14=hbcca054_0 + - cairo=1.18.2=h3394656_1 - cddlib=1!0.94m=h9202a9a_0 - - certifi=2024.8.30=pyhd8ed1ab_0 - - cffi=1.17.1=py310h8deb56e_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 + - certifi=2024.12.14=pyhd8ed1ab_0 + - cffi=1.17.1=py312h06ac9bb_0 + - charset-normalizer=3.4.0=pyhd8ed1ab_1 - cliquer=1.22=hd590300_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 - - contourpy=1.3.1=py310h3788b33_0 + - colorama=0.4.6=pyhd8ed1ab_1 + - comm=0.2.2=pyhd8ed1ab_1 + - contourpy=1.3.1=py312h68727a3_0 - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py310h89163eb_0 - - cpython=3.10.15=py310hd8ed1ab_2 + - coverage=7.6.9=py312h178313f_0 + - cpython=3.12.8=py312hd8ed1ab_1 - cxx-compiler=1.8.0=h1a2810e_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py310h14ed79e_0 + - cycler=0.12.1=pyhd8ed1ab_1 + - cypari2=2.1.5=py312h597db99_0 - cyrus-sasl=2.1.27=h54b06d7_7 - - cysignals=1.11.2=py310h945e7c7_3 - - cython=3.0.11=py310h5b1441d_3 + - cysignals=1.11.2=py312h9d3d55b_3 + - cython=3.0.11=py312h8fd2918_3 - dbus=1.13.6=h5008d03_3 - - debugpy=1.8.9=py310hf71b8c6_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 + - debugpy=1.8.11=py312h2ec8cdc_0 + - decorator=5.1.1=pyhd8ed1ab_1 + - docutils=0.21.2=pyhd8ed1ab_1 - double-conversion=3.3.0=h59595ed_0 - ecl=24.5.10=h0f3afd4_0 - - eclib=20231212=h96f522a_0 + - eclib=20231212=h43e5eba_1 - ecm=7.0.5=h9458935_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 + - exceptiongroup=1.2.2=pyhd8ed1ab_1 + - execnet=2.1.1=pyhd8ed1ab_1 + - executing=2.1.0=pyhd8ed1ab_1 - expat=2.6.4=h5888daf_0 - fflas-ffpack=2.5.0=h4f9960b_0 - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 @@ -69,18 +69,18 @@ dependencies: - fontconfig=2.15.0=h7e30c49_1 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 - - fonttools=4.55.0=py310h89163eb_0 + - fonttools=4.55.3=py312h178313f_0 - fortran-compiler=1.8.0=h36df796_1 - fplll=5.4.5=h384768b_0 - - fpylll=0.6.1=py310h7e26f94_0 + - fpylll=0.6.1=py312h59a3f1e_0 - freetype=2.12.1=h267a509_2 - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h94f18e1_0 - - gap-defaults=4.13.1=ha770c72_0 + - gap-core=4.14.0=h3b03731_1 + - gap-defaults=4.14.0=ha770c72_1 - gcc=13.3.0=h9576a4e_1 - gcc_impl_linux-64=13.3.0=hfea6d02_1 - gcc_linux-64=13.3.0=hc28eda2_7 - - gf2x=1.3.0=ha476b99_2 + - gf2x=1.3.0=h55551d5_3 - gfan=0.6.2=hb86e20a_1003 - gfortran=13.3.0=h9576a4e_1 - gfortran_impl_linux-64=13.3.0=h10434e7_1 @@ -89,40 +89,40 @@ dependencies: - givaro=4.2.0=hb789bce_0 - glpk=5.0=h445213a_0 - gmp=6.3.0=hac33072_2 - - gmpy2=2.1.5=py310he8512ff_2 + - gmpy2=2.1.5=py312h7201bc8_3 - graphite2=1.3.13=h59595ed_1003 - gsl=2.7=he838d99_0 - gxx=13.3.0=h9576a4e_1 - gxx_impl_linux-64=13.3.0=hdbfa832_1 - gxx_linux-64=13.3.0=h6834431_7 - - h2=4.1.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_1 - harfbuzz=9.0.0=hda332d3_1 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 + - hpack=4.0.0=pyhd8ed1ab_1 + - hyperframe=6.0.1=pyhd8ed1ab_1 - icu=75.1=he02047a_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=he44f51b_0 + - idna=3.10=pyhd8ed1ab_1 + - igraph=0.10.15=he44f51b_1 - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h623f65a_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 + - importlib-metadata=8.5.0=pyha770c72_1 + - iniconfig=2.0.0=pyhd8ed1ab_1 - ipykernel=6.29.5=pyh3099207_0 - - ipython=8.29.0=pyh707e725_0 - - ipywidgets=8.1.5=pyhd8ed1ab_0 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 + - ipython=8.30.0=pyh707e725_0 + - ipywidgets=8.1.5=pyhd8ed1ab_1 + - jedi=0.19.2=pyhd8ed1ab_1 + - jinja2=3.1.4=pyhd8ed1ab_1 + - jupyter_client=8.6.3=pyhd8ed1ab_1 - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.13=pyhd8ed1ab_1 - kernel-headers_linux-64=3.10.0=he073ed8_18 - keyutils=1.6.1=h166bdaf_0 - - kiwisolver=1.4.7=py310h3788b33_0 + - kiwisolver=1.4.7=py312h68727a3_0 - krb5=1.21.3=h659f571_0 - lcalc=2.0.5=h5aac1b6_2 - lcms2=2.16=hb7c19ff_0 - ld_impl_linux-64=2.43=h712a8e2_2 - lerc=4.0.0=h27087fc_0 - - libblas=3.9.0=25_linux64_openblas + - libblas=3.9.0=26_linux64_openblas - libboost=1.85.0=h0ccab89_4 - libboost-devel=1.85.0=h00ab1b0_4 - libboost-headers=1.85.0=ha770c72_4 @@ -131,19 +131,19 @@ dependencies: - libbrotlicommon=1.1.0=hb9d3cd8_2 - libbrotlidec=1.1.0=hb9d3cd8_2 - libbrotlienc=1.1.0=hb9d3cd8_2 - - libcblas=3.9.0=25_linux64_openblas - - libclang-cpp19.1=19.1.4=default_hb5137d0_0 - - libclang13=19.1.4=default_h9c6a7e4_0 + - libcblas=3.9.0=26_linux64_openblas + - libclang-cpp19.1=19.1.6=default_hb5137d0_0 + - libclang13=19.1.6=default_h9c6a7e4_0 - libcups=2.3.3=h4637d8d_4 - - libcurl=8.10.1=hbbe4b11_0 - - libdeflate=1.22=hb9d3cd8_0 - - libdrm=2.4.123=hb9d3cd8_0 + - libcurl=8.11.1=h332b0f4_0 + - libdeflate=1.23=h4ddbbb0_0 + - libdrm=2.4.124=hb9d3cd8_0 - libedit=3.1.20191231=he28a2e2_2 - libegl=1.7.0=ha4b6fd6_2 - libev=4.33=hd590300_2 - libexpat=2.6.4=h5888daf_0 - libffi=3.4.2=h7f98852_5 - - libflint=3.0.1=h6fb9888_103 + - libflint=3.1.2=h6fb9888_101 - libgcc=14.2.0=h77fa898_1 - libgcc-devel_linux-64=13.3.0=h84ea5a7_101 - libgcc-ng=14.2.0=h69a702a_1 @@ -159,9 +159,11 @@ dependencies: - libhomfly=1.02r6=hd590300_1 - libiconv=1.17=hd590300_2 - libjpeg-turbo=3.0.0=hd590300_1 - - liblapack=3.9.0=25_linux64_openblas - - liblapacke=3.9.0=25_linux64_openblas - - libllvm19=19.1.4=ha7bfdaf_1 + - liblapack=3.9.0=26_linux64_openblas + - liblapacke=3.9.0=26_linux64_openblas + - libllvm19=19.1.6=ha7bfdaf_0 + - liblzma=5.6.3=hb9d3cd8_1 + - liblzma-devel=5.6.3=hb9d3cd8_1 - libnghttp2=1.64.0=h161d5f1_0 - libnsl=2.0.1=hd590300_0 - libntlm=1.4=h7f98852_1002 @@ -169,142 +171,142 @@ dependencies: - libopengl=1.7.0=ha4b6fd6_2 - libpciaccess=0.18=hd590300_0 - libpng=1.6.44=hadc24fc_0 - - libpq=17.2=h04577a9_0 + - libpq=17.2=h3b95a9b_1 - libsanitizer=13.3.0=heb74ff8_1 - libsodium=1.0.20=h4ab18f5_0 - - libsqlite=3.47.0=hadc24fc_1 + - libsqlite=3.47.2=hee588c1_0 - libssh2=1.11.1=hf672d98_0 - libstdcxx=14.2.0=hc0a3c3a_1 - libstdcxx-devel_linux-64=13.3.0=h84ea5a7_101 - libstdcxx-ng=14.2.0=h4852527_1 - - libtiff=4.7.0=he137b08_1 + - libtiff=4.7.0=hd9ff511_3 - libuuid=2.38.1=h0b41bf4_0 - libwebp-base=1.4.0=hd590300_0 - libxcb=1.17.0=h8a09558_0 - libxcrypt=4.4.36=hd590300_1 - libxkbcommon=1.7.0=h2c5496b_1 - - libxml2=2.13.5=hb346dea_0 + - libxml2=2.13.5=h8d12d68_1 - libxslt=1.1.39=h76b75d6_0 - libzlib=1.3.1=hb9d3cd8_2 - - linbox=1.7.0=ha329b40_0 - - llvm-openmp=19.1.4=h024ca30_0 + - linbox=1.7.0=h7298d08_1 + - llvm-openmp=19.1.6=h024ca30_0 - lrcalc=2.1=h5888daf_7 - m4=1.4.18=h516909a_1001 - m4ri=20140914=hae5d5c5_1006 - - m4rie=20150908=h267a509_1002 - - markupsafe=3.0.2=py310h89163eb_0 - - matplotlib=3.9.2=py310hff52083_2 - - matplotlib-base=3.9.2=py310h68603db_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 + - m4rie=20200125=h051dbe0_0 + - markupsafe=3.0.2=py312h178313f_1 + - matplotlib=3.10.0=py312h7900ff3_0 + - matplotlib-base=3.10.0=py312hd3ec401_0 + - matplotlib-inline=0.1.7=pyhd8ed1ab_1 - maxima=5.47.0=h75482ee_3 - - memory-allocator=0.1.3=py310ha75aee5_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 + - memory-allocator=0.1.3=py312h66e93f0_1 + - meson=1.6.1=pyhd8ed1ab_0 + - meson-python=0.17.1=pyh70fd9c4_1 - mpc=1.3.1=h24ddda3_1 - mpfi=1.5.4=h9f54685_1001 - mpfr=4.2.1=h90cbb55_3 - - mpmath=1.3.0=pyhd8ed1ab_0 + - mpmath=1.3.0=pyhd8ed1ab_1 - munkres=1.1.4=pyh9f0ad1d_0 - - mysql-common=9.0.1=h266115a_2 - - mysql-libs=9.0.1=he0572af_2 + - mysql-common=9.0.1=h266115a_3 + - mysql-libs=9.0.1=he0572af_3 - nauty=2.8.8=hd590300_1 - ncurses=6.5=he02047a_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_1 - networkx=3.4.2=pyh267e887_2 - ninja=1.12.1=h297d8ca_0 - ntl=11.4.3=hef3c4d3_1 - - numpy=1.26.4=py310hb13e2d6_0 + - numpy=1.26.4=py312heda63a1_0 - openblas=0.3.28=pthreads_h6ec200e_1 - - openjpeg=2.5.2=h488ebb8_0 + - openjpeg=2.5.3=h5fbd93e_0 - openldap=2.6.9=he970967_0 - openssl=3.4.0=hb9d3cd8_0 - - packaging=24.2=pyhff2d567_1 + - packaging=24.2=pyhd8ed1ab_2 - palp=2.20=h36c2ea0_0 - pari=2.15.5=h4d4ae9b_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 + - parso=0.8.4=pyhd8ed1ab_1 - pcre2=10.44=hba22ea6_2 - perl=5.32.1=7_hd590300_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=11.0.0=py310hfeaa1f3_0 - - pip=24.3.1=pyh8b19718_0 - - pixman=0.43.2=h59595ed_0 + - pexpect=4.9.0=pyhd8ed1ab_1 + - pickleshare=0.7.5=pyhd8ed1ab_1004 + - pillow=11.0.0=py312h7b63e92_0 + - pip=24.3.1=pyh8b19718_2 + - pixman=0.44.2=h29eaf8c_0 - pkg-config=0.29.2=h4bc722e_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgconfig=1.5.5=pyhd8ed1ab_5 - planarity=3.0.2.0=hd590300_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 + - platformdirs=4.3.6=pyhd8ed1ab_1 + - pluggy=1.5.0=pyhd8ed1ab_1 - ppl=1.2=h6ec01c2_1006 - - pplpy=0.8.9=py310h18554fa_1 + - pplpy=0.8.9=py312h12a6c6f_1 - primecount=7.9=hcb278e6_0 - - primecountpy=0.1.0=py310hd41b1e2_4 + - primecountpy=0.1.0=py312h8572e83_4 - primesieve=11.1=h59595ed_0 - - prompt-toolkit=3.0.48=pyha770c72_0 - - psutil=6.1.0=py310ha75aee5_0 + - prompt-toolkit=3.0.48=pyha770c72_1 + - psutil=6.1.0=py312h66e93f0_0 - pthread-stubs=0.4=hb9d3cd8_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pyside6=6.8.0.2=py310hfd10a26_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.10.15=h4a871b0_2_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 - - python-lrcalc=2.1=py310hf71b8c6_7 - - python_abi=3.10=5_cp310 - - pytz=2024.2=pyhd8ed1ab_0 - - pyzmq=26.2.0=py310h71f11fc_3 + - ptyprocess=0.7.0=pyhd8ed1ab_1 + - pure_eval=0.2.3=pyhd8ed1ab_1 + - pycparser=2.22=pyh29332c3_1 + - pygments=2.18.0=pyhd8ed1ab_1 + - pyparsing=3.2.0=pyhd8ed1ab_2 + - pyproject-metadata=0.9.0=pyhd8ed1ab_1 + - pyside6=6.8.1=py312h91f0f75_0 + - pysocks=1.7.1=pyha55dd90_7 + - pytest=8.3.4=pyhd8ed1ab_1 + - pytest-xdist=3.6.1=pyhd8ed1ab_1 + - python=3.12.8=h9e4cc4f_1_cpython + - python-dateutil=2.9.0.post0=pyhff2d567_1 + - python-lrcalc=2.1=py312h2ec8cdc_7 + - python_abi=3.12=5_cp312 + - pytz=2024.2=pyhd8ed1ab_1 + - pyzmq=26.2.0=py312hbf22597_3 - qd=2.3.22=h2cc385e_1004 - qhull=2020.2=h434a139_5 - - qt6-main=6.8.0=h6e8976b_0 + - qt6-main=6.8.1=h9d28a51_0 - readline=8.2=h8228510_1 - - requests=2.32.3=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_1 - rw=0.9=hd590300_2 - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - sagemath-db-graphs=20210214=hd8ed1ab_0 - sagemath-db-polytopes=20170220=1 - - scipy=1.14.1=py310hfcf56fc_1 + - scipy=1.14.1=py312h62794b6_2 - setuptools=75.6.0=pyhff2d567_1 - - singular=4.4.0=h8a38e62_0 - - six=1.16.0=pyh6c4a22f_0 + - singular=4.4.0=hc910cb2_1 + - six=1.17.0=pyhd8ed1ab_0 - snowballstemmer=2.2.0=pyhd8ed1ab_0 - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=8.1.3=pyhd8ed1ab_0 + - sphinx=8.1.3=pyhd8ed1ab_1 - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=h9eae976_1 - - stack_data=0.6.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_1 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_1 + - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_1 + - sqlite=3.47.2=h9eae976_0 + - stack_data=0.6.3=pyhd8ed1ab_1 - symmetrica=3.0.1=hcb278e6_0 - sympow=2.023.6=hc6ab17c_3 - sympy=1.13.3=pyh2585a3b_104 - sysroot_linux-64=2.17=h4a8ded7_18 - tachyon=0.99b6=hba7d16a_1002 - tk=8.6.13=noxft_h4845f30_101 - - tomli=2.1.0=pyhff2d567_0 - - tornado=6.4.2=py310ha75aee5_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 + - tomli=2.2.1=pyhd8ed1ab_1 + - tornado=6.4.2=py312h66e93f0_0 + - traitlets=5.14.3=pyhd8ed1ab_1 + - typing_extensions=4.12.2=pyha770c72_1 - tzdata=2024b=hc8b5060_0 - - unicodedata2=15.1.0=py310ha75aee5_1 - - urllib3=2.2.3=pyhd8ed1ab_0 + - unicodedata2=15.1.0=py312h66e93f0_1 + - urllib3=2.2.3=pyhd8ed1ab_1 - wayland=1.23.1=h3e06ad9_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_1 + - wheel=0.45.1=pyhd8ed1ab_1 + - widgetsnbextension=4.0.13=pyhd8ed1ab_1 - xcb-util=0.4.1=hb711507_2 - xcb-util-cursor=0.1.5=hb9d3cd8_0 - xcb-util-image=0.4.0=hb711507_2 @@ -312,10 +314,10 @@ dependencies: - xcb-util-renderutil=0.3.10=hb711507_0 - xcb-util-wm=0.4.2=hb711507_0 - xkeyboard-config=2.43=hb9d3cd8_0 - - xorg-libice=1.1.1=hb9d3cd8_1 - - xorg-libsm=1.2.4=he73a12e_1 - - xorg-libx11=1.8.10=h4f16b4b_0 - - xorg-libxau=1.0.11=hb9d3cd8_1 + - xorg-libice=1.1.2=hb9d3cd8_0 + - xorg-libsm=1.2.5=he73a12e_0 + - xorg-libx11=1.8.10=h4f16b4b_1 + - xorg-libxau=1.0.12=hb9d3cd8_0 - xorg-libxcomposite=0.4.6=hb9d3cd8_2 - xorg-libxcursor=1.2.3=hb9d3cd8_0 - xorg-libxdamage=1.1.6=hb9d3cd8_0 @@ -324,13 +326,14 @@ dependencies: - xorg-libxfixes=6.0.1=hb9d3cd8_0 - xorg-libxi=1.8.2=hb9d3cd8_0 - xorg-libxrandr=1.5.4=hb9d3cd8_0 - - xorg-libxrender=0.9.11=hb9d3cd8_1 + - xorg-libxrender=0.9.12=hb9d3cd8_0 - xorg-libxtst=1.2.5=hb9d3cd8_3 - - xorg-libxxf86vm=1.1.5=hb9d3cd8_4 - - xorg-xorgproto=2024.1=hb9d3cd8_1 - - xz=5.2.6=h166bdaf_0 + - xorg-libxxf86vm=1.1.6=hb9d3cd8_0 + - xz=5.6.3=hbcc6ac9_1 + - xz-gpl-tools=5.6.3=hbcc6ac9_1 + - xz-tools=5.6.3=hb9d3cd8_1 - zeromq=4.3.5=h3b0a872_7 - zipp=3.21.0=pyhd8ed1ab_1 - zlib=1.3.1=hb9d3cd8_2 - - zstandard=0.23.0=py310ha39cb0e_1 + - zstandard=0.23.0=py312hef9b889_1 - zstd=1.5.6=ha6fb4c9_0 diff --git a/environment-3.10-macos-x86_64.yml b/environment-3.12-macos-x86_64.yml similarity index 52% rename from environment-3.10-macos-x86_64.yml rename to environment-3.12-macos-x86_64.yml index 11b09eca6d1..4fccaefb570 100644 --- a/environment-3.10-macos-x86_64.yml +++ b/environment-3.12-macos-x86_64.yml @@ -1,37 +1,37 @@ name: sage-dev # Generated by conda-lock. # platform: osx-64 -# input_hash: 547d430073dcad6960849dd76e5cedcc0a4840137033d18ceaa468c8e61b5642 +# input_hash: 5888a68a5088012ad0dffd6db00812a4e3c24a060219dc73fd975f246c404337 channels: - conda-forge dependencies: - - alabaster=1.0.0=pyhd8ed1ab_0 - - appnope=0.1.4=pyhd8ed1ab_0 + - alabaster=1.0.0=pyhd8ed1ab_1 + - appnope=0.1.4=pyhd8ed1ab_1 - arpack=3.9.1=nompi_hf81eadf_101 - - asttokens=2.4.1=pyhd8ed1ab_0 + - asttokens=3.0.0=pyhd8ed1ab_1 - autoconf=2.71=pl5321hed12c24_1 - automake=1.17=pl5321h694c41f_0 - - babel=2.16.0=pyhd8ed1ab_0 + - babel=2.16.0=pyhd8ed1ab_1 - bdw-gc=8.0.6=h940c156_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - blas=2.125=openblas - - blas-devel=3.9.0=25_osx64_openblas + - beautifulsoup4=4.12.3=pyha770c72_1 + - blas=2.126=openblas + - blas-devel=3.9.0=26_osx64_openblas - boost-cpp=1.85.0=hfcd56d9_4 - brial=1.2.12=pyh694c41f_3 - brotli=1.1.0=h00291cd_2 - brotli-bin=1.1.0=h00291cd_2 - - brotli-python=1.1.0=py310h53e7c6a_2 + - brotli-python=1.1.0=py312h5861a67_2 - bzip2=1.0.8=hfdf4475_7 - - c-ares=1.34.3=hf13058a_1 + - c-ares=1.34.4=hf13058a_0 - c-compiler=1.8.0=hfc4bf79_1 - - ca-certificates=2024.8.30=h8857fd0_0 + - ca-certificates=2024.12.14=h8857fd0_0 - cctools=1010.6=h5b2de21_2 - cctools_osx-64=1010.6=hea4301f_2 - cddlib=1!0.94m=h0f52abe_0 - - certifi=2024.8.30=pyhd8ed1ab_0 - - cffi=1.17.1=py310hfce808e_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 + - certifi=2024.12.14=pyhd8ed1ab_0 + - cffi=1.17.1=py312hf857d28_0 + - charset-normalizer=3.4.0=pyhd8ed1ab_1 - clang=17.0.6=default_he371ed4_7 - clang-17=17.0.6=default_hb173f14_7 - clang_impl_osx-64=17.0.6=h1af8efd_23 @@ -40,28 +40,28 @@ dependencies: - clangxx_impl_osx-64=17.0.6=hc3430b7_23 - clangxx_osx-64=17.0.6=h7e5c614_23 - cliquer=1.22=h10d778d_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 + - colorama=0.4.6=pyhd8ed1ab_1 + - comm=0.2.2=pyhd8ed1ab_1 - compiler-rt=17.0.6=h1020d70_2 - compiler-rt_osx-64=17.0.6=hf2b8a54_2 - - contourpy=1.3.1=py310hf166250_0 + - contourpy=1.3.1=py312hc47a885_0 - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py310h8e2f543_0 - - cpython=3.10.15=py310hd8ed1ab_2 + - coverage=7.6.9=py312h3520af0_0 + - cpython=3.12.8=py312hd8ed1ab_1 - cxx-compiler=1.8.0=h385f146_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py310hc7df965_0 - - cysignals=1.11.2=py310h8c82e65_3 - - cython=3.0.11=py310h62447e2_3 - - debugpy=1.8.9=py310h6954a95_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 + - cycler=0.12.1=pyhd8ed1ab_1 + - cypari2=2.1.5=py312h88009e3_0 + - cysignals=1.11.2=py312h0c1623b_3 + - cython=3.0.11=py312h6891801_3 + - debugpy=1.8.11=py312haafddd8_0 + - decorator=5.1.1=pyhd8ed1ab_1 + - docutils=0.21.2=pyhd8ed1ab_1 - ecl=24.5.10=h56bac16_0 - - eclib=20231212=h02435c3_0 + - eclib=20231212=h960c116_1 - ecm=7.0.5=h4f6b447_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 + - exceptiongroup=1.2.2=pyhd8ed1ab_1 + - execnet=2.1.1=pyhd8ed1ab_1 + - executing=2.1.0=pyhd8ed1ab_1 - expat=2.6.4=h240833e_0 - fflas-ffpack=2.5.0=h5898d61_0 - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 @@ -71,17 +71,17 @@ dependencies: - fontconfig=2.15.0=h37eeddb_1 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 - - fonttools=4.55.0=py310h8e2f543_0 + - fonttools=4.55.3=py312h3520af0_0 - fortran-compiler=1.8.0=h33d1f46_1 - fplll=5.4.5=hb7981ad_0 - - fpylll=0.6.1=py310h65a3d7e_0 + - fpylll=0.6.1=py312ha9f3631_0 - freetype=2.12.1=h60636b9_2 - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h2299be9_0 - - gap-defaults=4.13.1=h694c41f_0 + - gap-core=4.14.0=hb9686a1_1 + - gap-defaults=4.14.0=h694c41f_1 - gettext=0.22.5=hdfe23c8_3 - gettext-tools=0.22.5=hdfe23c8_3 - - gf2x=1.3.0=hb2a7efb_2 + - gf2x=1.3.0=h35ac7d9_3 - gfan=0.6.2=hd793b56_1003 - gfortran=13.2.0=h2c809b3_1 - gfortran_impl_osx-64=13.2.0=h2bc304d_3 @@ -90,28 +90,28 @@ dependencies: - givaro=4.2.0=h1b3d6f7_0 - glpk=5.0=h3cb5acd_0 - gmp=6.3.0=hf036a51_2 - - gmpy2=2.1.5=py310hade44e5_2 + - gmpy2=2.1.5=py312h068713c_3 - gsl=2.7=h93259b0_0 - - h2=4.1.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_1 + - hpack=4.0.0=pyhd8ed1ab_1 + - hyperframe=6.0.1=pyhd8ed1ab_1 - icu=75.1=h120a0e1_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=h5479cbe_0 + - idna=3.10=pyhd8ed1ab_1 + - igraph=0.10.15=h5479cbe_1 - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h61918c1_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 + - importlib-metadata=8.5.0=pyha770c72_1 + - iniconfig=2.0.0=pyhd8ed1ab_1 - ipykernel=6.29.5=pyh57ce528_0 - - ipython=8.29.0=pyh707e725_0 - - ipywidgets=8.1.5=pyhd8ed1ab_0 + - ipython=8.30.0=pyh707e725_0 + - ipywidgets=8.1.5=pyhd8ed1ab_1 - isl=0.26=imath32_h2e86a7b_101 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 + - jedi=0.19.2=pyhd8ed1ab_1 + - jinja2=3.1.4=pyhd8ed1ab_1 + - jupyter_client=8.6.3=pyhd8ed1ab_1 - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 - - kiwisolver=1.4.7=py310hfa8da69_0 + - jupyterlab_widgets=3.0.13=pyhd8ed1ab_1 + - kiwisolver=1.4.7=py312hc5c4d5f_0 - krb5=1.21.3=h37d8d59_0 - lcalc=2.0.5=h547a6ed_2 - lcms2=2.16=ha2f27b4_0 @@ -120,7 +120,7 @@ dependencies: - lerc=4.0.0=hb486fe8_0 - libasprintf=0.22.5=hdfe23c8_3 - libasprintf-devel=0.22.5=hdfe23c8_3 - - libblas=3.9.0=25_osx64_openblas + - libblas=3.9.0=26_osx64_openblas - libboost=1.85.0=hcca3243_4 - libboost-devel=1.85.0=h2b186f8_4 - libboost-headers=1.85.0=h694c41f_4 @@ -129,17 +129,17 @@ dependencies: - libbrotlicommon=1.1.0=h00291cd_2 - libbrotlidec=1.1.0=h00291cd_2 - libbrotlienc=1.1.0=h00291cd_2 - - libcblas=3.9.0=25_osx64_openblas + - libcblas=3.9.0=26_osx64_openblas - libclang-cpp17=17.0.6=default_hb173f14_7 - - libcurl=8.10.1=h58e7537_0 - - libcxx=19.1.4=hf95d169_0 + - libcurl=8.11.1=h5dec5d8_0 + - libcxx=19.1.6=hf95d169_1 - libcxx-devel=17.0.6=h8f8a49f_6 - - libdeflate=1.22=h00291cd_0 + - libdeflate=1.23=he65b83e_0 - libedit=3.1.20191231=h0678c8f_2 - libev=4.33=h10d778d_2 - libexpat=2.6.4=h240833e_0 - libffi=3.4.2=h0d85af4_5 - - libflint=3.0.1=h1d27844_103 + - libflint=3.1.2=h1d27844_101 - libgd=2.3.3=h2e77e4f_10 - libgettextpo=0.22.5=hdfe23c8_3 - libgettextpo-devel=0.22.5=hdfe23c8_3 @@ -151,138 +151,142 @@ dependencies: - libintl=0.22.5=hdfe23c8_3 - libintl-devel=0.22.5=hdfe23c8_3 - libjpeg-turbo=3.0.0=h0dc2134_1 - - liblapack=3.9.0=25_osx64_openblas - - liblapacke=3.9.0=25_osx64_openblas + - liblapack=3.9.0=26_osx64_openblas + - liblapacke=3.9.0=26_osx64_openblas - libllvm17=17.0.6=hbedff68_1 + - liblzma=5.6.3=hd471939_1 + - liblzma-devel=5.6.3=hd471939_1 - libnghttp2=1.64.0=hc7306c3_0 - libopenblas=0.3.28=openmp_hbf64a52_1 - libpng=1.6.44=h4b8f8c9_0 - libsodium=1.0.20=hfdf4475_0 - - libsqlite=3.47.0=h2f8c449_1 + - libsqlite=3.47.2=hdb6dae5_0 - libssh2=1.11.1=h3dc7d44_0 - - libtiff=4.7.0=h583c2ba_1 + - libtiff=4.7.0=hb77a491_3 - libwebp-base=1.4.0=h10d778d_0 - libxcb=1.17.0=hf1f96e2_0 - - libxml2=2.13.5=h495214b_0 + - libxml2=2.13.5=hebb159f_1 - libzlib=1.3.1=hd23fc13_2 - - linbox=1.7.0=h7061c92_0 - - llvm-openmp=19.1.4=ha54dae1_0 + - linbox=1.7.0=h9325161_1 + - llvm-openmp=19.1.6=ha54dae1_0 - llvm-tools=17.0.6=hbedff68_1 - lrcalc=2.1=hac325c4_7 - m4=1.4.18=haf1e3a3_1001 - m4ri=20140914=hd82a5f3_1006 - - m4rie=20150908=hc616cfc_1002 - - markupsafe=3.0.2=py310h72eadd2_0 - - matplotlib=3.9.2=py310h2ec42d9_2 - - matplotlib-base=3.9.2=py310h449bdf7_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 + - m4rie=20200125=hd82a5f3_0 + - markupsafe=3.0.2=py312h3520af0_1 + - matplotlib=3.10.0=py312hb401068_0 + - matplotlib-base=3.10.0=py312h535dea3_0 + - matplotlib-inline=0.1.7=pyhd8ed1ab_1 - maxima=5.47.0=h3080a4d_3 - - memory-allocator=0.1.3=py310h837254d_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 + - memory-allocator=0.1.3=py312hb553811_1 + - meson=1.6.1=pyhd8ed1ab_0 + - meson-python=0.17.1=pyh70fd9c4_1 - mpc=1.3.1=h9d8efa1_1 - mpfi=1.5.4=h52b28e3_1001 - mpfr=4.2.1=haed47dc_3 - - mpmath=1.3.0=pyhd8ed1ab_0 + - mpmath=1.3.0=pyhd8ed1ab_1 - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h10d778d_1 - ncurses=6.5=hf036a51_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_1 - networkx=3.4.2=pyh267e887_2 - ninja=1.12.1=h3c5361c_0 - ntl=11.4.3=h0ab3c2f_1 - - numpy=1.26.4=py310h4bfa8fc_0 + - numpy=1.26.4=py312he3a82b2_0 - openblas=0.3.28=openmp_h30af337_1 - - openjpeg=2.5.2=h7310d3a_0 + - openjpeg=2.5.3=h7fd6d84_0 - openssl=3.4.0=hd471939_0 - - packaging=24.2=pyhff2d567_1 + - packaging=24.2=pyhd8ed1ab_2 - palp=2.20=hbcb3906_0 - pari=2.15.5=h7ba67ff_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 + - parso=0.8.4=pyhd8ed1ab_1 - perl=5.32.1=7_h10d778d_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=11.0.0=py310h32d1d24_0 - - pip=24.3.1=pyh8b19718_0 + - pexpect=4.9.0=pyhd8ed1ab_1 + - pickleshare=0.7.5=pyhd8ed1ab_1004 + - pillow=11.0.0=py312h66fe14f_0 + - pip=24.3.1=pyh8b19718_2 - pkg-config=0.29.2=hf7e621a_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgconfig=1.5.5=pyhd8ed1ab_5 - planarity=3.0.2.0=h10d778d_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 + - platformdirs=4.3.6=pyhd8ed1ab_1 + - pluggy=1.5.0=pyhd8ed1ab_1 - ppl=1.2=ha60d53e_1006 - - pplpy=0.8.9=py310hbe8aec3_1 + - pplpy=0.8.9=py312hb4417ad_1 - primecount=7.6=ha894c9a_0 - - primecountpy=0.1.0=py310h88cfcbd_4 + - primecountpy=0.1.0=py312h49ebfd2_4 - primesieve=11.0=hf0c8a7f_0 - - prompt-toolkit=3.0.48=pyha770c72_0 - - psutil=6.1.0=py310hb9d19b6_0 + - prompt-toolkit=3.0.48=pyha770c72_1 + - psutil=6.1.0=py312h3d0f464_0 - pthread-stubs=0.4=h00291cd_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.10.15=hd8744da_2_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 - - python-lrcalc=2.1=py310h53e7c6a_7 - - python_abi=3.10=5_cp310 - - pytz=2024.2=pyhd8ed1ab_0 - - pyzmq=26.2.0=py310h0c870a2_3 + - ptyprocess=0.7.0=pyhd8ed1ab_1 + - pure_eval=0.2.3=pyhd8ed1ab_1 + - pycparser=2.22=pyh29332c3_1 + - pygments=2.18.0=pyhd8ed1ab_1 + - pyparsing=3.2.0=pyhd8ed1ab_2 + - pyproject-metadata=0.9.0=pyhd8ed1ab_1 + - pysocks=1.7.1=pyha55dd90_7 + - pytest=8.3.4=pyhd8ed1ab_1 + - pytest-xdist=3.6.1=pyhd8ed1ab_1 + - python=3.12.8=h9ccd52b_1_cpython + - python-dateutil=2.9.0.post0=pyhff2d567_1 + - python-lrcalc=2.1=py312h5861a67_7 + - python_abi=3.12=5_cp312 + - pytz=2024.2=pyhd8ed1ab_1 + - pyzmq=26.2.0=py312h1060d5c_3 - qd=2.3.22=h2beb688_1004 - qhull=2020.2=h3c5361c_5 - readline=8.2=h9e318b2_1 - - requests=2.32.3=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_1 - rw=0.9=h10d778d_2 - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - sagemath-db-graphs=20210214=hd8ed1ab_0 - sagemath-db-polytopes=20170220=1 - - scipy=1.14.1=py310h9ad1863_1 + - scipy=1.14.1=py312h3b0f538_2 - setuptools=75.6.0=pyhff2d567_1 - sigtool=0.1.3=h88f4db0_0 - - singular=4.4.0=h0c52cc7_0 - - six=1.16.0=pyh6c4a22f_0 + - singular=4.4.0=h604985e_1 + - six=1.17.0=pyhd8ed1ab_0 - snowballstemmer=2.2.0=pyhd8ed1ab_0 - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=8.1.3=pyhd8ed1ab_0 + - sphinx=8.1.3=pyhd8ed1ab_1 - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=h6285a30_1 - - stack_data=0.6.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_1 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_1 + - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_1 + - sqlite=3.47.2=h2e4c9dc_0 + - stack_data=0.6.3=pyhd8ed1ab_1 - symmetrica=3.0.1=hf0c8a7f_0 - sympow=2.023.6=h115ba6a_3 - sympy=1.13.3=pyh2585a3b_104 - tachyon=0.99b6=h3a1d103_1002 - tapi=1300.6.5=h390ca13_0 - tk=8.6.13=h1abcd95_1 - - tomli=2.1.0=pyhff2d567_0 - - tornado=6.4.2=py310hbb8c376_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 + - tomli=2.2.1=pyhd8ed1ab_1 + - tornado=6.4.2=py312h01d7ebd_0 + - traitlets=5.14.3=pyhd8ed1ab_1 + - typing_extensions=4.12.2=pyha770c72_1 - tzdata=2024b=hc8b5060_0 - - unicodedata2=15.1.0=py310hb9d19b6_1 - - urllib3=2.2.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=h00291cd_1 + - unicodedata2=15.1.0=py312h3d0f464_1 + - urllib3=2.2.3=pyhd8ed1ab_1 + - wcwidth=0.2.13=pyhd8ed1ab_1 + - wheel=0.45.1=pyhd8ed1ab_1 + - widgetsnbextension=4.0.13=pyhd8ed1ab_1 + - xorg-libxau=1.0.12=h6e16a3a_0 - xorg-libxdmcp=1.1.5=h00291cd_0 - - xz=5.2.6=h775f41a_0 + - xz=5.6.3=h357f2ed_1 + - xz-gpl-tools=5.6.3=h357f2ed_1 + - xz-tools=5.6.3=hd471939_1 - zeromq=4.3.5=h7130eaa_7 - zipp=3.21.0=pyhd8ed1ab_1 - zlib=1.3.1=hd23fc13_2 - - zstandard=0.23.0=py310h41d873f_1 + - zstandard=0.23.0=py312h7122b0e_1 - zstd=1.5.6=h915ae27_0 diff --git a/environment-3.10-macos.yml b/environment-3.12-macos.yml similarity index 53% rename from environment-3.10-macos.yml rename to environment-3.12-macos.yml index d6cc0969531..957da365df9 100644 --- a/environment-3.10-macos.yml +++ b/environment-3.12-macos.yml @@ -1,37 +1,37 @@ name: sage-dev # Generated by conda-lock. # platform: osx-arm64 -# input_hash: a20846f94d8c398a77c7b0e2aabc5eb61c1c7fbabb5979b5da5d7b7b56c7b7be +# input_hash: 0c152106e1e870088723e57e0bd27be66ce0a8f2488067475849ebf869659bbe channels: - conda-forge dependencies: - - alabaster=1.0.0=pyhd8ed1ab_0 - - appnope=0.1.4=pyhd8ed1ab_0 + - alabaster=1.0.0=pyhd8ed1ab_1 + - appnope=0.1.4=pyhd8ed1ab_1 - arpack=3.9.1=nompi_h593882a_101 - - asttokens=2.4.1=pyhd8ed1ab_0 + - asttokens=3.0.0=pyhd8ed1ab_1 - autoconf=2.71=pl5321hcd07c0c_1 - automake=1.17=pl5321hce30654_0 - - babel=2.16.0=pyhd8ed1ab_0 + - babel=2.16.0=pyhd8ed1ab_1 - bdw-gc=8.0.6=hc021e02_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - blas=2.125=openblas - - blas-devel=3.9.0=25_osxarm64_openblas + - beautifulsoup4=4.12.3=pyha770c72_1 + - blas=2.126=openblas + - blas-devel=3.9.0=26_osxarm64_openblas - boost-cpp=1.85.0=h103c1d6_4 - brial=1.2.12=pyh694c41f_3 - brotli=1.1.0=hd74edd7_2 - brotli-bin=1.1.0=hd74edd7_2 - - brotli-python=1.1.0=py310hb4ad77e_2 + - brotli-python=1.1.0=py312hde4cb15_2 - bzip2=1.0.8=h99b78c6_7 - - c-ares=1.34.3=h5505292_1 + - c-ares=1.34.4=h5505292_0 - c-compiler=1.8.0=hf48404e_1 - - ca-certificates=2024.8.30=hf0a4a13_0 + - ca-certificates=2024.12.14=hf0a4a13_0 - cctools=1010.6=hf67d63f_2 - cctools_osx-arm64=1010.6=h623e0ac_2 - cddlib=1!0.94m=h6d7a090_0 - - certifi=2024.8.30=pyhd8ed1ab_0 - - cffi=1.17.1=py310h497396d_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 + - certifi=2024.12.14=pyhd8ed1ab_0 + - cffi=1.17.1=py312h0fad829_0 + - charset-normalizer=3.4.0=pyhd8ed1ab_1 - clang=17.0.6=default_h360f5da_7 - clang-17=17.0.6=default_h146c034_7 - clang_impl_osx-arm64=17.0.6=he47c785_23 @@ -40,28 +40,28 @@ dependencies: - clangxx_impl_osx-arm64=17.0.6=h50f59cd_23 - clangxx_osx-arm64=17.0.6=h07b0088_23 - cliquer=1.22=h93a5062_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 + - colorama=0.4.6=pyhd8ed1ab_1 + - comm=0.2.2=pyhd8ed1ab_1 - compiler-rt=17.0.6=h856b3c1_2 - compiler-rt_osx-arm64=17.0.6=h832e737_2 - - contourpy=1.3.1=py310h7f4e7e6_0 + - contourpy=1.3.1=py312hb23fbb9_0 - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py310hc74094e_0 - - cpython=3.10.15=py310hd8ed1ab_2 + - coverage=7.6.9=py312h998013c_0 + - cpython=3.12.8=py312hd8ed1ab_1 - cxx-compiler=1.8.0=h18dbf2f_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py310h5e3d6bc_0 - - cysignals=1.11.2=py310hfd3b3fe_3 - - cython=3.0.11=py310h1dbcdd0_3 - - debugpy=1.8.9=py310h853098b_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 + - cycler=0.12.1=pyhd8ed1ab_1 + - cypari2=2.1.5=py312h2da97d0_0 + - cysignals=1.11.2=py312heab4d4f_3 + - cython=3.0.11=py312hde4cb15_2 + - debugpy=1.8.11=py312hd8f9ff3_0 + - decorator=5.1.1=pyhd8ed1ab_1 + - docutils=0.21.2=pyhd8ed1ab_1 - ecl=23.9.9=h1d9728a_0 - - eclib=20231212=h7f07de4_0 + - eclib=20231212=h3d50bd9_1 - ecm=7.0.5=h41d338b_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 + - exceptiongroup=1.2.2=pyhd8ed1ab_1 + - execnet=2.1.1=pyhd8ed1ab_1 + - executing=2.1.0=pyhd8ed1ab_1 - expat=2.6.4=h286801f_0 - fflas-ffpack=2.5.0=h4bc3318_0 - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 @@ -71,17 +71,17 @@ dependencies: - fontconfig=2.15.0=h1383a14_1 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 - - fonttools=4.55.0=py310hc74094e_0 + - fonttools=4.55.3=py312h998013c_0 - fortran-compiler=1.8.0=hc3477c4_1 - fplll=5.4.5=hb7d509d_0 - - fpylll=0.6.1=py310hd9be144_0 + - fpylll=0.6.1=py312h381bdd1_0 - freetype=2.12.1=hadb7bae_2 - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h4cbeff9_0 - - gap-defaults=4.13.1=hce30654_0 + - gap-core=4.14.0=h25f1785_1 + - gap-defaults=4.14.0=hce30654_1 - gettext=0.22.5=h8414b35_3 - gettext-tools=0.22.5=h8414b35_3 - - gf2x=1.3.0=hdaa854c_2 + - gf2x=1.3.0=hf8f8af4_3 - gfan=0.6.2=hec08f5c_1003 - gfortran=13.2.0=h1ca8e4b_1 - gfortran_impl_osx-arm64=13.2.0=h252ada1_3 @@ -90,28 +90,28 @@ dependencies: - givaro=4.2.0=h018886a_0 - glpk=5.0=h6d7a090_0 - gmp=6.3.0=h7bae524_2 - - gmpy2=2.1.5=py310heb17c8b_2 + - gmpy2=2.1.5=py312h524cf62_3 - gsl=2.7=h6e638da_0 - - h2=4.1.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_1 + - hpack=4.0.0=pyhd8ed1ab_1 + - hyperframe=6.0.1=pyhd8ed1ab_1 - icu=75.1=hfee45f7_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=h3fe6531_0 + - idna=3.10=pyhd8ed1ab_1 + - igraph=0.10.15=h3fe6531_1 - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=hd73f12c_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 + - importlib-metadata=8.5.0=pyha770c72_1 + - iniconfig=2.0.0=pyhd8ed1ab_1 - ipykernel=6.29.5=pyh57ce528_0 - - ipython=8.29.0=pyh707e725_0 - - ipywidgets=8.1.5=pyhd8ed1ab_0 + - ipython=8.30.0=pyh707e725_0 + - ipywidgets=8.1.5=pyhd8ed1ab_1 - isl=0.26=imath32_h347afa1_101 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 + - jedi=0.19.2=pyhd8ed1ab_1 + - jinja2=3.1.4=pyhd8ed1ab_1 + - jupyter_client=8.6.3=pyhd8ed1ab_1 - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 - - kiwisolver=1.4.7=py310h7306fd8_0 + - jupyterlab_widgets=3.0.13=pyhd8ed1ab_1 + - kiwisolver=1.4.7=py312h6142ec9_0 - krb5=1.21.3=h237132a_0 - lcalc=2.0.5=h4a402bc_2 - lcms2=2.16=ha0e7c42_0 @@ -120,7 +120,7 @@ dependencies: - lerc=4.0.0=h9a09cb3_0 - libasprintf=0.22.5=h8414b35_3 - libasprintf-devel=0.22.5=h8414b35_3 - - libblas=3.9.0=25_osxarm64_openblas + - libblas=3.9.0=26_osxarm64_openblas - libboost=1.85.0=hf763ba5_4 - libboost-devel=1.85.0=hf450f58_4 - libboost-headers=1.85.0=hce30654_4 @@ -129,17 +129,17 @@ dependencies: - libbrotlicommon=1.1.0=hd74edd7_2 - libbrotlidec=1.1.0=hd74edd7_2 - libbrotlienc=1.1.0=hd74edd7_2 - - libcblas=3.9.0=25_osxarm64_openblas + - libcblas=3.9.0=26_osxarm64_openblas - libclang-cpp17=17.0.6=default_h146c034_7 - - libcurl=8.10.1=h13a7ad3_0 - - libcxx=19.1.4=ha82da77_0 + - libcurl=8.11.1=h73640d1_0 + - libcxx=19.1.6=ha82da77_1 - libcxx-devel=17.0.6=h86353a2_6 - - libdeflate=1.22=hd74edd7_0 + - libdeflate=1.23=hec38601_0 - libedit=3.1.20191231=hc8eb9b7_2 - libev=4.33=h93a5062_2 - libexpat=2.6.4=h286801f_0 - libffi=3.4.2=h3422bc3_5 - - libflint=3.0.1=he28cf6d_103 + - libflint=3.1.2=he28cf6d_101 - libgd=2.3.3=hac1b3a8_10 - libgettextpo=0.22.5=h8414b35_3 - libgettextpo-devel=0.22.5=h8414b35_3 @@ -152,139 +152,143 @@ dependencies: - libintl=0.22.5=h8414b35_3 - libintl-devel=0.22.5=h8414b35_3 - libjpeg-turbo=3.0.0=hb547adb_1 - - liblapack=3.9.0=25_osxarm64_openblas - - liblapacke=3.9.0=25_osxarm64_openblas + - liblapack=3.9.0=26_osxarm64_openblas + - liblapacke=3.9.0=26_osxarm64_openblas - libllvm17=17.0.6=h5090b49_2 + - liblzma=5.6.3=h39f12f2_1 + - liblzma-devel=5.6.3=h39f12f2_1 - libnghttp2=1.64.0=h6d7220d_0 - libopenblas=0.3.28=openmp_hf332438_1 - libpng=1.6.44=hc14010f_0 - libsodium=1.0.20=h99b78c6_0 - - libsqlite=3.47.0=hbaaea75_1 + - libsqlite=3.47.2=h3f77e49_0 - libssh2=1.11.1=h9cc3647_0 - - libtiff=4.7.0=hfce79cd_1 + - libtiff=4.7.0=h551f018_3 - libwebp-base=1.4.0=h93a5062_0 - libxcb=1.17.0=hdb1d25a_0 - - libxml2=2.13.5=hbbdcc80_0 + - libxml2=2.13.5=h178c5d8_1 - libzlib=1.3.1=h8359307_2 - - linbox=1.7.0=h3afee3a_0 - - llvm-openmp=19.1.4=hdb05f8b_0 + - linbox=1.7.0=h9da6ecd_1 + - llvm-openmp=19.1.6=hdb05f8b_0 - llvm-tools=17.0.6=h5090b49_2 - lrcalc=2.1=hf9b8971_7 - m4=1.4.18=h642e427_1001 - m4ri=20140914=hc97c1ff_1006 - - m4rie=20150908=h22b9e9d_1002 - - markupsafe=3.0.2=py310h5799be4_0 - - matplotlib=3.9.2=py310hb6292c7_2 - - matplotlib-base=3.9.2=py310h2a20ac7_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 + - m4rie=20200125=hc97c1ff_0 + - markupsafe=3.0.2=py312h998013c_1 + - matplotlib=3.10.0=py312h1f38498_0 + - matplotlib-base=3.10.0=py312hdbc7e53_0 + - matplotlib-inline=0.1.7=pyhd8ed1ab_1 - maxima=5.47.0=h2bbcd85_2 - - memory-allocator=0.1.3=py310h493c2e1_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 + - memory-allocator=0.1.3=py312h024a12e_1 + - meson=1.6.1=pyhd8ed1ab_0 + - meson-python=0.17.1=pyh70fd9c4_1 - mpc=1.3.1=h8f1351a_1 - mpfi=1.5.4=hbde5f5b_1001 - mpfr=4.2.1=hb693164_3 - - mpmath=1.3.0=pyhd8ed1ab_0 + - mpmath=1.3.0=pyhd8ed1ab_1 - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h93a5062_1 - ncurses=6.5=h7bae524_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_1 - networkx=3.4.2=pyh267e887_2 - ninja=1.12.1=h420ef59_0 - ntl=11.4.3=hbb3f309_1 - - numpy=1.26.4=py310hd45542a_0 + - numpy=1.26.4=py312h8442bc7_0 - openblas=0.3.28=openmp_hea878ba_1 - - openjpeg=2.5.2=h9f1df11_0 + - openjpeg=2.5.3=h8a3d83b_0 - openssl=3.4.0=h39f12f2_0 - - packaging=24.2=pyhff2d567_1 + - packaging=24.2=pyhd8ed1ab_2 - palp=2.20=h27ca646_0 - pari=2.15.5=h4f2304c_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 + - parso=0.8.4=pyhd8ed1ab_1 - pcre2=10.44=h297a79d_2 - perl=5.32.1=7_h4614cfb_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=11.0.0=py310h530beaf_0 - - pip=24.3.1=pyh8b19718_0 + - pexpect=4.9.0=pyhd8ed1ab_1 + - pickleshare=0.7.5=pyhd8ed1ab_1004 + - pillow=11.0.0=py312haf37ca6_0 + - pip=24.3.1=pyh8b19718_2 - pkg-config=0.29.2=hde07d2e_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgconfig=1.5.5=pyhd8ed1ab_5 - planarity=3.0.2.0=h93a5062_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 + - platformdirs=4.3.6=pyhd8ed1ab_1 + - pluggy=1.5.0=pyhd8ed1ab_1 - ppl=1.2=h8b147cf_1006 - - pplpy=0.8.9=py310hc3af9bb_1 + - pplpy=0.8.9=py312h35b16b8_1 - primecount=7.6=hb6e4faa_0 - - primecountpy=0.1.0=py310h38f39d4_4 + - primecountpy=0.1.0=py312h389731b_4 - primesieve=11.0=hb7217d7_0 - - prompt-toolkit=3.0.48=pyha770c72_0 - - psutil=6.1.0=py310hf9df320_0 + - prompt-toolkit=3.0.48=pyha770c72_1 + - psutil=6.1.0=py312h0bf5046_0 - pthread-stubs=0.4=hd74edd7_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.10.15=hdce6c4c_2_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 - - python-lrcalc=2.1=py310hb4ad77e_7 - - python_abi=3.10=5_cp310 - - pytz=2024.2=pyhd8ed1ab_0 - - pyzmq=26.2.0=py310h82ef58e_3 + - ptyprocess=0.7.0=pyhd8ed1ab_1 + - pure_eval=0.2.3=pyhd8ed1ab_1 + - pycparser=2.22=pyh29332c3_1 + - pygments=2.18.0=pyhd8ed1ab_1 + - pyparsing=3.2.0=pyhd8ed1ab_2 + - pyproject-metadata=0.9.0=pyhd8ed1ab_1 + - pysocks=1.7.1=pyha55dd90_7 + - pytest=8.3.4=pyhd8ed1ab_1 + - pytest-xdist=3.6.1=pyhd8ed1ab_1 + - python=3.12.8=hc22306f_1_cpython + - python-dateutil=2.9.0.post0=pyhff2d567_1 + - python-lrcalc=2.1=py312hde4cb15_7 + - python_abi=3.12=5_cp312 + - pytz=2024.2=pyhd8ed1ab_1 + - pyzmq=26.2.0=py312hf8a1cbd_3 - qd=2.3.22=hbec66e7_1004 - qhull=2020.2=h420ef59_5 - readline=8.2=h92ec313_1 - - requests=2.32.3=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_1 - rw=0.9=h93a5062_2 - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - sagemath-db-graphs=20210214=hd8ed1ab_0 - sagemath-db-polytopes=20170220=1 - - scipy=1.14.1=py310hc05a576_1 + - scipy=1.14.1=py312h6bb24ec_2 - setuptools=75.6.0=pyhff2d567_1 - sigtool=0.1.3=h44b9a77_0 - - singular=4.4.0=h8aafc33_0 - - six=1.16.0=pyh6c4a22f_0 + - singular=4.4.0=h5a8969a_1 + - six=1.17.0=pyhd8ed1ab_0 - snowballstemmer=2.2.0=pyhd8ed1ab_0 - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=8.1.3=pyhd8ed1ab_0 + - sphinx=8.1.3=pyhd8ed1ab_1 - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=hcd14bea_1 - - stack_data=0.6.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_1 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_1 + - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_1 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_1 + - sqlite=3.47.2=hd7222ec_0 + - stack_data=0.6.3=pyhd8ed1ab_1 - symmetrica=3.0.1=hb7217d7_0 - sympow=2.023.6=hb0babe8_3 - sympy=1.13.3=pyh2585a3b_104 - tachyon=0.99b6=hb8a568e_1002 - tapi=1300.6.5=h03f4b80_0 - tk=8.6.13=h5083fa2_1 - - tomli=2.1.0=pyhff2d567_0 - - tornado=6.4.2=py310h078409c_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 + - tomli=2.2.1=pyhd8ed1ab_1 + - tornado=6.4.2=py312hea69d52_0 + - traitlets=5.14.3=pyhd8ed1ab_1 + - typing_extensions=4.12.2=pyha770c72_1 - tzdata=2024b=hc8b5060_0 - - unicodedata2=15.1.0=py310hf9df320_1 - - urllib3=2.2.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=hd74edd7_1 + - unicodedata2=15.1.0=py312h0bf5046_1 + - urllib3=2.2.3=pyhd8ed1ab_1 + - wcwidth=0.2.13=pyhd8ed1ab_1 + - wheel=0.45.1=pyhd8ed1ab_1 + - widgetsnbextension=4.0.13=pyhd8ed1ab_1 + - xorg-libxau=1.0.12=h5505292_0 - xorg-libxdmcp=1.1.5=hd74edd7_0 - - xz=5.2.6=h57fd34a_0 + - xz=5.6.3=h9a6d368_1 + - xz-gpl-tools=5.6.3=h9a6d368_1 + - xz-tools=5.6.3=h39f12f2_1 - zeromq=4.3.5=hc1bb282_7 - zipp=3.21.0=pyhd8ed1ab_1 - zlib=1.3.1=h8359307_2 - - zstandard=0.23.0=py310h2665a74_1 + - zstandard=0.23.0=py312h15fbf35_1 - zstd=1.5.6=hb46c0d2_0 diff --git a/environment-3.9-linux-aarch64.yml b/environment-3.9-linux-aarch64.yml deleted file mode 100644 index e2445733524..00000000000 --- a/environment-3.9-linux-aarch64.yml +++ /dev/null @@ -1,337 +0,0 @@ -name: sage-dev -# Generated by conda-lock. -# platform: linux-aarch64 -# input_hash: 2baa194fde0ce285ceeba30a5c1ca2c6a9cc6e1193e7ae4eef4469a870d93e14 - -channels: - - conda-forge -dependencies: - - _openmp_mutex=4.5=2_kmp_llvm - - alabaster=0.7.16=pyhd8ed1ab_0 - - alsa-lib=1.2.13=h86ecc28_0 - - arpack=3.9.1=nompi_hd363cd0_101 - - asttokens=2.4.1=pyhd8ed1ab_0 - - autoconf=2.71=pl5321h2148fe1_1 - - automake=1.17=pl5321h8af1aa0_0 - - babel=2.16.0=pyhd8ed1ab_0 - - bdw-gc=8.0.6=hd62202e_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - binutils=2.43=hf1166c9_2 - - binutils_impl_linux-aarch64=2.43=h4c662bb_2 - - binutils_linux-aarch64=2.43=hf1166c9_2 - - blas=2.125=openblas - - blas-devel=3.9.0=25_linuxaarch64_openblas - - boost-cpp=1.85.0=hdad291f_4 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=h86ecc28_2 - - brotli-bin=1.1.0=h86ecc28_2 - - brotli-python=1.1.0=py39h7dbf29c_2 - - bzip2=1.0.8=h68df207_7 - - c-ares=1.34.3=h86ecc28_1 - - c-compiler=1.8.0=h6561dab_1 - - ca-certificates=2024.8.30=hcefe29a_0 - - cairo=1.18.0=hdb1a16f_3 - - cddlib=1!0.94m=h719063d_0 - - certifi=2024.8.30=pyhd8ed1ab_0 - - cffi=1.17.1=py39hecfc5ed_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 - - cliquer=1.22=h31becfc_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 - - contourpy=1.3.0=py39hbd2ca3f_2 - - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py39h36a3f59_0 - - cpython=3.9.20=py39hd8ed1ab_1 - - cxx-compiler=1.8.0=heb6c788_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py39h532d932_0 - - cyrus-sasl=2.1.27=hf6b2984_7 - - cysignals=1.11.2=py39hfa81392_3 - - cython=3.0.11=py39h3e5e1bb_3 - - dbus=1.13.6=h12b9eeb_3 - - debugpy=1.8.9=py39h7dbf29c_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - double-conversion=3.3.0=h2f0025b_0 - - ecl=24.5.10=h5567cc5_0 - - eclib=20231212=he26bab5_0 - - ecm=7.0.5=ha2d0fc4_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 - - expat=2.6.4=h5ad3122_0 - - fflas-ffpack=2.5.0=h503e619_0 - - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 - - font-ttf-inconsolata=3.000=h77eed37_0 - - font-ttf-source-code-pro=2.038=h77eed37_0 - - font-ttf-ubuntu=0.83=h77eed37_3 - - fontconfig=2.15.0=h8dda3cd_1 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.55.0=py39hbebea31_0 - - fortran-compiler=1.8.0=h25a59a9_1 - - fplll=5.4.5=hb3a790e_0 - - fpylll=0.6.1=py39h97065f7_0 - - freetype=2.12.1=hf0a5ef3_2 - - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h16511ff_0 - - gap-defaults=4.13.1=h8af1aa0_0 - - gcc=13.3.0=h8a56e6e_1 - - gcc_impl_linux-aarch64=13.3.0=hcdea9b6_1 - - gcc_linux-aarch64=13.3.0=h1cd514b_7 - - gf2x=1.3.0=h1b3b3a3_2 - - gfan=0.6.2=h5f589ec_1003 - - gfortran=13.3.0=h8a56e6e_1 - - gfortran_impl_linux-aarch64=13.3.0=h174a3c4_1 - - gfortran_linux-aarch64=13.3.0=h2809cf8_7 - - giac=1.9.0.21=h04922a4_1 - - givaro=4.2.0=h364d21b_0 - - glpk=5.0=h66325d0_0 - - gmp=6.3.0=h0a1ffab_2 - - gmpy2=2.1.5=py39h7dc50c5_2 - - graphite2=1.3.13=h2f0025b_1003 - - gsl=2.7=h294027d_0 - - gxx=13.3.0=h8a56e6e_1 - - gxx_impl_linux-aarch64=13.3.0=h1211b58_1 - - gxx_linux-aarch64=13.3.0=h2864abd_7 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=9.0.0=hbf49d6b_1 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=75.1=hf9b3779_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=h207f3e5_0 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h15043fe_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - importlib-resources=6.4.5=pyhd8ed1ab_0 - - importlib_resources=6.4.5=pyhd8ed1ab_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 - - ipykernel=6.29.5=pyh3099207_0 - - ipython=8.18.1=pyh707e725_3 - - ipywidgets=8.1.5=pyhd8ed1ab_0 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 - - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 - - kernel-headers_linux-aarch64=4.18.0=h05a177a_18 - - keyutils=1.6.1=h4e544f5_0 - - kiwisolver=1.4.7=py39h78c8b8d_0 - - krb5=1.21.3=h50a48e9_0 - - lcalc=2.0.5=he588f68_2 - - lcms2=2.16=h922389a_0 - - ld_impl_linux-aarch64=2.43=h80caac9_2 - - lerc=4.0.0=h4de3ea5_0 - - libblas=3.9.0=25_linuxaarch64_openblas - - libboost=1.85.0=h9fa81b4_4 - - libboost-devel=1.85.0=h37bb5a9_4 - - libboost-headers=1.85.0=h8af1aa0_4 - - libbraiding=1.3=h5ad3122_0 - - libbrial=1.2.12=h9429f74_3 - - libbrotlicommon=1.1.0=h86ecc28_2 - - libbrotlidec=1.1.0=h86ecc28_2 - - libbrotlienc=1.1.0=h86ecc28_2 - - libcblas=3.9.0=25_linuxaarch64_openblas - - libclang-cpp19.1=19.1.4=default_he324ac1_0 - - libclang13=19.1.4=default_h4390ef5_0 - - libcups=2.3.3=h405e4a8_4 - - libcurl=8.10.1=h3ec0cbf_0 - - libdeflate=1.22=h86ecc28_0 - - libdrm=2.4.123=h86ecc28_0 - - libedit=3.1.20191231=he28a2e2_2 - - libegl=1.7.0=hd24410f_2 - - libev=4.33=h31becfc_2 - - libexpat=2.6.4=h5ad3122_0 - - libffi=3.4.2=h3557bc0_5 - - libflint=3.0.1=h0433c20_103 - - libgcc=14.2.0=he277a41_1 - - libgcc-devel_linux-aarch64=13.3.0=h0c07274_101 - - libgcc-ng=14.2.0=he9431aa_1 - - libgd=2.3.3=h6818b27_10 - - libgfortran=14.2.0=he9431aa_1 - - libgfortran-ng=14.2.0=he9431aa_1 - - libgfortran5=14.2.0=hb6113d0_1 - - libgl=1.7.0=hd24410f_2 - - libglib=2.82.2=hc486b8e_0 - - libglvnd=1.7.0=hd24410f_2 - - libglx=1.7.0=hd24410f_2 - - libgomp=14.2.0=he277a41_1 - - libhomfly=1.02r6=h31becfc_1 - - libiconv=1.17=h31becfc_2 - - libjpeg-turbo=3.0.0=h31becfc_1 - - liblapack=3.9.0=25_linuxaarch64_openblas - - liblapacke=3.9.0=25_linuxaarch64_openblas - - libllvm19=19.1.4=h2edbd07_1 - - libnghttp2=1.64.0=hc8609a4_0 - - libnsl=2.0.1=h31becfc_0 - - libntlm=1.4=hf897c2e_1002 - - libopenblas=0.3.28=pthreads_h9d3fd7e_1 - - libopengl=1.7.0=hd24410f_2 - - libpciaccess=0.18=h31becfc_0 - - libpng=1.6.44=hc4a20ef_0 - - libpq=17.2=h081282e_0 - - libsanitizer=13.3.0=ha58e236_1 - - libsodium=1.0.20=h68df207_0 - - libsqlite=3.47.0=hc4a20ef_1 - - libssh2=1.11.1=ha41c0db_0 - - libstdcxx=14.2.0=h3f4de04_1 - - libstdcxx-devel_linux-aarch64=13.3.0=h0c07274_101 - - libstdcxx-ng=14.2.0=hf1166c9_1 - - libtiff=4.7.0=hec21d91_1 - - libuuid=2.38.1=hb4cce97_0 - - libwebp-base=1.4.0=h31becfc_0 - - libxcb=1.17.0=h262b8f6_0 - - libxcrypt=4.4.36=h31becfc_1 - - libxkbcommon=1.7.0=h46f2afe_1 - - libxml2=2.13.5=hf4efe5d_0 - - libxslt=1.1.39=h1cc9640_0 - - libzlib=1.3.1=h86ecc28_2 - - linbox=1.7.0=h681a5ee_0 - - llvm-openmp=19.1.4=h013ceaa_0 - - lrcalc=2.1=h5ad3122_7 - - m4=1.4.18=h516909a_1001 - - m4ri=20140914=hedfd65a_1006 - - m4rie=20150908=hf0a5ef3_1002 - - markupsafe=3.0.2=py39h36a3f59_0 - - matplotlib=3.9.2=py39ha65689a_2 - - matplotlib-base=3.9.2=py39hd333c8e_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h043f013_3 - - memory-allocator=0.1.3=py39h060674a_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 - - mpc=1.3.1=h783934e_1 - - mpfi=1.5.4=h846f343_1001 - - mpfr=4.2.1=h2305555_3 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - mysql-common=9.0.1=h3f5c77f_2 - - mysql-libs=9.0.1=h11569fd_2 - - nauty=2.8.8=h31becfc_1 - - ncurses=6.5=hcccb83c_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h70be974_0 - - ntl=11.4.3=h0d7519b_1 - - numpy=1.26.4=py39h91c28bb_0 - - openblas=0.3.28=pthreads_h3a8cbd8_1 - - openjpeg=2.5.2=h0d9d63b_0 - - openldap=2.6.9=h30c48ee_0 - - openssl=3.4.0=h86ecc28_0 - - packaging=24.2=pyhff2d567_1 - - palp=2.20=hb9de7d4_0 - - pari=2.15.5=h169c2a7_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - pcre2=10.44=h070dd5b_2 - - perl=5.32.1=7_h31becfc_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=11.0.0=py39hb20fde8_0 - - pip=24.3.1=pyh8b19718_0 - - pixman=0.43.4=h2f0025b_0 - - pkg-config=0.29.2=hce167ba_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - planarity=3.0.2.0=h31becfc_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ppl=1.2=h984aac9_1006 - - pplpy=0.8.9=py39hf652505_1 - - primecount=7.6=hd600fc2_0 - - primecountpy=0.1.0=py39hd16970a_3 - - primesieve=11.0=hd600fc2_0 - - prompt-toolkit=3.0.48=pyha770c72_0 - - psutil=6.1.0=py39h060674a_0 - - pthread-stubs=0.4=h86ecc28_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pyside6=6.8.0.2=py39h51c6ee1_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.9.20=h4a649e4_1_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 - - python-lrcalc=2.1=py39h7dbf29c_7 - - python_abi=3.9=5_cp39 - - pytz=2024.2=pyhd8ed1ab_0 - - pyzmq=26.2.0=py39he601760_3 - - qd=2.3.22=h05efe27_1004 - - qhull=2020.2=h70be974_5 - - qt6-main=6.8.0=h666f7c6_0 - - readline=8.2=h8fc344f_1 - - requests=2.32.3=pyhd8ed1ab_0 - - rw=0.9=h31becfc_2 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - scipy=1.13.1=py39hb921187_0 - - setuptools=75.6.0=pyhff2d567_1 - - singular=4.4.0=h9a92511_0 - - six=1.16.0=pyh6c4a22f_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.4.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=h578a6b9_1 - - stack_data=0.6.2=pyhd8ed1ab_0 - - symmetrica=3.0.1=hd600fc2_0 - - sympow=2.023.6=h157afb5_3 - - sympy=1.13.3=pyh2585a3b_104 - - sysroot_linux-aarch64=2.17=h5b4a56d_18 - - tachyon=0.99b6=ha0bfc61_1002 - - tk=8.6.13=h194ca79_0 - - tomli=2.1.0=pyhff2d567_0 - - tornado=6.4.2=py39h3e3acee_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - tzdata=2024b=hc8b5060_0 - - unicodedata2=15.1.0=py39h060674a_1 - - urllib3=2.2.3=pyhd8ed1ab_0 - - wayland=1.23.1=h698ed42_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 - - xcb-util=0.4.1=h5c728e9_2 - - xcb-util-cursor=0.1.5=h86ecc28_0 - - xcb-util-image=0.4.0=h5c728e9_2 - - xcb-util-keysyms=0.4.1=h5c728e9_0 - - xcb-util-renderutil=0.3.10=h5c728e9_0 - - xcb-util-wm=0.4.2=h5c728e9_0 - - xkeyboard-config=2.43=h86ecc28_0 - - xorg-libice=1.1.1=h57736b2_1 - - xorg-libsm=1.2.4=hbac51e1_1 - - xorg-libx11=1.8.9=he755bbd_2 - - xorg-libxau=1.0.11=h86ecc28_1 - - xorg-libxcomposite=0.4.6=h86ecc28_2 - - xorg-libxcursor=1.2.3=h86ecc28_0 - - xorg-libxdamage=1.1.6=h86ecc28_0 - - xorg-libxdmcp=1.1.5=h57736b2_0 - - xorg-libxext=1.3.6=h57736b2_0 - - xorg-libxfixes=6.0.1=h57736b2_0 - - xorg-libxi=1.8.2=h57736b2_0 - - xorg-libxrandr=1.5.4=h86ecc28_0 - - xorg-libxrender=0.9.11=h57736b2_1 - - xorg-libxtst=1.2.5=h57736b2_3 - - xorg-libxxf86vm=1.1.5=h57736b2_4 - - xorg-xorgproto=2024.1=h86ecc28_1 - - xz=5.2.6=h9cdd2b7_0 - - zeromq=4.3.5=h5efb499_7 - - zipp=3.21.0=pyhd8ed1ab_1 - - zlib=1.3.1=h86ecc28_2 - - zstandard=0.23.0=py39h5934b9c_1 - - zstd=1.5.6=h02f22dd_0 diff --git a/environment-3.9-linux.yml b/environment-3.9-linux.yml deleted file mode 100644 index 0a8d9500a8d..00000000000 --- a/environment-3.9-linux.yml +++ /dev/null @@ -1,338 +0,0 @@ -name: sage-dev -# Generated by conda-lock. -# platform: linux-64 -# input_hash: a52c15354bebd8c86b0f8a14c4514746d357f79f673cfa7998f53d9bcc42b5c1 - -channels: - - conda-forge -dependencies: - - _libgcc_mutex=0.1=conda_forge - - _openmp_mutex=4.5=2_kmp_llvm - - alabaster=0.7.16=pyhd8ed1ab_0 - - alsa-lib=1.2.13=hb9d3cd8_0 - - arpack=3.9.1=nompi_h77f6705_101 - - asttokens=2.4.1=pyhd8ed1ab_0 - - autoconf=2.71=pl5321h2b4cb7a_1 - - automake=1.17=pl5321ha770c72_0 - - babel=2.16.0=pyhd8ed1ab_0 - - bdw-gc=8.0.6=h4bd325d_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - binutils=2.43=h4852527_2 - - binutils_impl_linux-64=2.43=h4bf12b8_2 - - binutils_linux-64=2.43=h4852527_2 - - blas=2.125=openblas - - blas-devel=3.9.0=25_linux64_openblas - - boost-cpp=1.85.0=h3c6214e_4 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=hb9d3cd8_2 - - brotli-bin=1.1.0=hb9d3cd8_2 - - brotli-python=1.1.0=py39hf88036b_2 - - bzip2=1.0.8=h4bc722e_7 - - c-ares=1.34.3=hb9d3cd8_1 - - c-compiler=1.8.0=h2b85faf_1 - - ca-certificates=2024.8.30=hbcca054_0 - - cairo=1.18.0=hebfffa5_3 - - cddlib=1!0.94m=h9202a9a_0 - - certifi=2024.8.30=pyhd8ed1ab_0 - - cffi=1.17.1=py39h15c3d72_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 - - cliquer=1.22=hd590300_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 - - contourpy=1.3.0=py39h74842e3_2 - - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py39h9399b63_0 - - cpython=3.9.20=py39hd8ed1ab_1 - - cxx-compiler=1.8.0=h1a2810e_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py39h1698a45_0 - - cyrus-sasl=2.1.27=h54b06d7_7 - - cysignals=1.11.2=py39h1ce0973_3 - - cython=3.0.11=py39hde8bd2b_3 - - dbus=1.13.6=h5008d03_3 - - debugpy=1.8.9=py39hf88036b_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - double-conversion=3.3.0=h59595ed_0 - - ecl=24.5.10=h0f3afd4_0 - - eclib=20231212=h96f522a_0 - - ecm=7.0.5=h9458935_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 - - expat=2.6.4=h5888daf_0 - - fflas-ffpack=2.5.0=h4f9960b_0 - - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 - - font-ttf-inconsolata=3.000=h77eed37_0 - - font-ttf-source-code-pro=2.038=h77eed37_0 - - font-ttf-ubuntu=0.83=h77eed37_3 - - fontconfig=2.15.0=h7e30c49_1 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.55.0=py39h9399b63_0 - - fortran-compiler=1.8.0=h36df796_1 - - fplll=5.4.5=h384768b_0 - - fpylll=0.6.1=py39h2525e16_0 - - freetype=2.12.1=h267a509_2 - - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h94f18e1_0 - - gap-defaults=4.13.1=ha770c72_0 - - gcc=13.3.0=h9576a4e_1 - - gcc_impl_linux-64=13.3.0=hfea6d02_1 - - gcc_linux-64=13.3.0=hc28eda2_7 - - gf2x=1.3.0=ha476b99_2 - - gfan=0.6.2=hb86e20a_1003 - - gfortran=13.3.0=h9576a4e_1 - - gfortran_impl_linux-64=13.3.0=h10434e7_1 - - gfortran_linux-64=13.3.0=hb919d3a_7 - - giac=1.9.0.21=h673759e_1 - - givaro=4.2.0=hb789bce_0 - - glpk=5.0=h445213a_0 - - gmp=6.3.0=hac33072_2 - - gmpy2=2.1.5=py39h7196dd7_2 - - graphite2=1.3.13=h59595ed_1003 - - gsl=2.7=he838d99_0 - - gxx=13.3.0=h9576a4e_1 - - gxx_impl_linux-64=13.3.0=hdbfa832_1 - - gxx_linux-64=13.3.0=h6834431_7 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=9.0.0=hda332d3_1 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=75.1=he02047a_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=he44f51b_0 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h623f65a_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - importlib-resources=6.4.5=pyhd8ed1ab_0 - - importlib_resources=6.4.5=pyhd8ed1ab_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 - - ipykernel=6.29.5=pyh3099207_0 - - ipython=8.18.1=pyh707e725_3 - - ipywidgets=8.1.5=pyhd8ed1ab_0 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 - - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 - - kernel-headers_linux-64=3.10.0=he073ed8_18 - - keyutils=1.6.1=h166bdaf_0 - - kiwisolver=1.4.7=py39h74842e3_0 - - krb5=1.21.3=h659f571_0 - - lcalc=2.0.5=h5aac1b6_2 - - lcms2=2.16=hb7c19ff_0 - - ld_impl_linux-64=2.43=h712a8e2_2 - - lerc=4.0.0=h27087fc_0 - - libblas=3.9.0=25_linux64_openblas - - libboost=1.85.0=h0ccab89_4 - - libboost-devel=1.85.0=h00ab1b0_4 - - libboost-headers=1.85.0=ha770c72_4 - - libbraiding=1.3=h5888daf_0 - - libbrial=1.2.12=h76af697_3 - - libbrotlicommon=1.1.0=hb9d3cd8_2 - - libbrotlidec=1.1.0=hb9d3cd8_2 - - libbrotlienc=1.1.0=hb9d3cd8_2 - - libcblas=3.9.0=25_linux64_openblas - - libclang-cpp19.1=19.1.4=default_hb5137d0_0 - - libclang13=19.1.4=default_h9c6a7e4_0 - - libcups=2.3.3=h4637d8d_4 - - libcurl=8.10.1=hbbe4b11_0 - - libdeflate=1.22=hb9d3cd8_0 - - libdrm=2.4.123=hb9d3cd8_0 - - libedit=3.1.20191231=he28a2e2_2 - - libegl=1.7.0=ha4b6fd6_2 - - libev=4.33=hd590300_2 - - libexpat=2.6.4=h5888daf_0 - - libffi=3.4.2=h7f98852_5 - - libflint=3.0.1=h6fb9888_103 - - libgcc=14.2.0=h77fa898_1 - - libgcc-devel_linux-64=13.3.0=h84ea5a7_101 - - libgcc-ng=14.2.0=h69a702a_1 - - libgd=2.3.3=hd3e95f3_10 - - libgfortran=14.2.0=h69a702a_1 - - libgfortran-ng=14.2.0=h69a702a_1 - - libgfortran5=14.2.0=hd5240d6_1 - - libgl=1.7.0=ha4b6fd6_2 - - libglib=2.82.2=h2ff4ddf_0 - - libglvnd=1.7.0=ha4b6fd6_2 - - libglx=1.7.0=ha4b6fd6_2 - - libgomp=14.2.0=h77fa898_1 - - libhomfly=1.02r6=hd590300_1 - - libiconv=1.17=hd590300_2 - - libjpeg-turbo=3.0.0=hd590300_1 - - liblapack=3.9.0=25_linux64_openblas - - liblapacke=3.9.0=25_linux64_openblas - - libllvm19=19.1.4=ha7bfdaf_1 - - libnghttp2=1.64.0=h161d5f1_0 - - libnsl=2.0.1=hd590300_0 - - libntlm=1.4=h7f98852_1002 - - libopenblas=0.3.28=pthreads_h94d23a6_1 - - libopengl=1.7.0=ha4b6fd6_2 - - libpciaccess=0.18=hd590300_0 - - libpng=1.6.44=hadc24fc_0 - - libpq=17.2=h04577a9_0 - - libsanitizer=13.3.0=heb74ff8_1 - - libsodium=1.0.20=h4ab18f5_0 - - libsqlite=3.47.0=hadc24fc_1 - - libssh2=1.11.1=hf672d98_0 - - libstdcxx=14.2.0=hc0a3c3a_1 - - libstdcxx-devel_linux-64=13.3.0=h84ea5a7_101 - - libstdcxx-ng=14.2.0=h4852527_1 - - libtiff=4.7.0=he137b08_1 - - libuuid=2.38.1=h0b41bf4_0 - - libwebp-base=1.4.0=hd590300_0 - - libxcb=1.17.0=h8a09558_0 - - libxcrypt=4.4.36=hd590300_1 - - libxkbcommon=1.7.0=h2c5496b_1 - - libxml2=2.13.5=hb346dea_0 - - libxslt=1.1.39=h76b75d6_0 - - libzlib=1.3.1=hb9d3cd8_2 - - linbox=1.7.0=ha329b40_0 - - llvm-openmp=19.1.4=h024ca30_0 - - lrcalc=2.1=h5888daf_7 - - m4=1.4.18=h516909a_1001 - - m4ri=20140914=hae5d5c5_1006 - - m4rie=20150908=h267a509_1002 - - markupsafe=3.0.2=py39h9399b63_0 - - matplotlib=3.9.2=py39hf3d152e_2 - - matplotlib-base=3.9.2=py39h16632d1_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h75482ee_3 - - memory-allocator=0.1.3=py39h8cd3c5a_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 - - mpc=1.3.1=h24ddda3_1 - - mpfi=1.5.4=h9f54685_1001 - - mpfr=4.2.1=h90cbb55_3 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - mysql-common=9.0.1=h266115a_2 - - mysql-libs=9.0.1=he0572af_2 - - nauty=2.8.8=hd590300_1 - - ncurses=6.5=he02047a_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h297d8ca_0 - - ntl=11.4.3=hef3c4d3_1 - - numpy=1.26.4=py39h474f0d3_0 - - openblas=0.3.28=pthreads_h6ec200e_1 - - openjpeg=2.5.2=h488ebb8_0 - - openldap=2.6.9=he970967_0 - - openssl=3.4.0=hb9d3cd8_0 - - packaging=24.2=pyhff2d567_1 - - palp=2.20=h36c2ea0_0 - - pari=2.15.5=h4d4ae9b_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - pcre2=10.44=hba22ea6_2 - - perl=5.32.1=7_hd590300_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=11.0.0=py39h538c539_0 - - pip=24.3.1=pyh8b19718_0 - - pixman=0.43.2=h59595ed_0 - - pkg-config=0.29.2=h4bc722e_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - planarity=3.0.2.0=hd590300_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ppl=1.2=h6ec01c2_1006 - - pplpy=0.8.9=py39h9e9cb73_1 - - primecount=7.9=hcb278e6_0 - - primecountpy=0.1.0=py39h7633fee_4 - - primesieve=11.1=h59595ed_0 - - prompt-toolkit=3.0.48=pyha770c72_0 - - psutil=6.1.0=py39h8cd3c5a_0 - - pthread-stubs=0.4=hb9d3cd8_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pyside6=6.8.0.2=py39h0383914_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.9.20=h13acc7a_1_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 - - python-lrcalc=2.1=py39hf88036b_7 - - python_abi=3.9=5_cp39 - - pytz=2024.2=pyhd8ed1ab_0 - - pyzmq=26.2.0=py39h4e4fb57_3 - - qd=2.3.22=h2cc385e_1004 - - qhull=2020.2=h434a139_5 - - qt6-main=6.8.0=h6e8976b_0 - - readline=8.2=h8228510_1 - - requests=2.32.3=pyhd8ed1ab_0 - - rw=0.9=hd590300_2 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - scipy=1.13.1=py39haf93ffa_0 - - setuptools=75.6.0=pyhff2d567_1 - - singular=4.4.0=h8a38e62_0 - - six=1.16.0=pyh6c4a22f_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.4.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=h9eae976_1 - - stack_data=0.6.2=pyhd8ed1ab_0 - - symmetrica=3.0.1=hcb278e6_0 - - sympow=2.023.6=hc6ab17c_3 - - sympy=1.13.3=pyh2585a3b_104 - - sysroot_linux-64=2.17=h4a8ded7_18 - - tachyon=0.99b6=hba7d16a_1002 - - tk=8.6.13=noxft_h4845f30_101 - - tomli=2.1.0=pyhff2d567_0 - - tornado=6.4.2=py39h8cd3c5a_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - tzdata=2024b=hc8b5060_0 - - unicodedata2=15.1.0=py39h8cd3c5a_1 - - urllib3=2.2.3=pyhd8ed1ab_0 - - wayland=1.23.1=h3e06ad9_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 - - xcb-util=0.4.1=hb711507_2 - - xcb-util-cursor=0.1.5=hb9d3cd8_0 - - xcb-util-image=0.4.0=hb711507_2 - - xcb-util-keysyms=0.4.1=hb711507_0 - - xcb-util-renderutil=0.3.10=hb711507_0 - - xcb-util-wm=0.4.2=hb711507_0 - - xkeyboard-config=2.43=hb9d3cd8_0 - - xorg-libice=1.1.1=hb9d3cd8_1 - - xorg-libsm=1.2.4=he73a12e_1 - - xorg-libx11=1.8.10=h4f16b4b_0 - - xorg-libxau=1.0.11=hb9d3cd8_1 - - xorg-libxcomposite=0.4.6=hb9d3cd8_2 - - xorg-libxcursor=1.2.3=hb9d3cd8_0 - - xorg-libxdamage=1.1.6=hb9d3cd8_0 - - xorg-libxdmcp=1.1.5=hb9d3cd8_0 - - xorg-libxext=1.3.6=hb9d3cd8_0 - - xorg-libxfixes=6.0.1=hb9d3cd8_0 - - xorg-libxi=1.8.2=hb9d3cd8_0 - - xorg-libxrandr=1.5.4=hb9d3cd8_0 - - xorg-libxrender=0.9.11=hb9d3cd8_1 - - xorg-libxtst=1.2.5=hb9d3cd8_3 - - xorg-libxxf86vm=1.1.5=hb9d3cd8_4 - - xorg-xorgproto=2024.1=hb9d3cd8_1 - - xz=5.2.6=h166bdaf_0 - - zeromq=4.3.5=h3b0a872_7 - - zipp=3.21.0=pyhd8ed1ab_1 - - zlib=1.3.1=hb9d3cd8_2 - - zstandard=0.23.0=py39h08a7858_1 - - zstd=1.5.6=ha6fb4c9_0 diff --git a/environment-3.9-macos-x86_64.yml b/environment-3.9-macos-x86_64.yml deleted file mode 100644 index c755abe0e4a..00000000000 --- a/environment-3.9-macos-x86_64.yml +++ /dev/null @@ -1,290 +0,0 @@ -name: sage-dev -# Generated by conda-lock. -# platform: osx-64 -# input_hash: cdad1bd56606756079e5b1e9a07e3c7deb49c120a33b156a2567eaf2121dfae0 - -channels: - - conda-forge -dependencies: - - alabaster=0.7.16=pyhd8ed1ab_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - arpack=3.9.1=nompi_hf81eadf_101 - - asttokens=2.4.1=pyhd8ed1ab_0 - - autoconf=2.71=pl5321hed12c24_1 - - automake=1.17=pl5321h694c41f_0 - - babel=2.16.0=pyhd8ed1ab_0 - - bdw-gc=8.0.6=h940c156_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - blas=2.125=openblas - - blas-devel=3.9.0=25_osx64_openblas - - boost-cpp=1.85.0=hfcd56d9_4 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=h00291cd_2 - - brotli-bin=1.1.0=h00291cd_2 - - brotli-python=1.1.0=py39h7c0e7c0_2 - - bzip2=1.0.8=hfdf4475_7 - - c-ares=1.34.3=hf13058a_1 - - c-compiler=1.8.0=hfc4bf79_1 - - ca-certificates=2024.8.30=h8857fd0_0 - - cctools=1010.6=h5b2de21_2 - - cctools_osx-64=1010.6=hea4301f_2 - - cddlib=1!0.94m=h0f52abe_0 - - certifi=2024.8.30=pyhd8ed1ab_0 - - cffi=1.17.1=py39h8ddeee6_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 - - clang=17.0.6=default_he371ed4_7 - - clang-17=17.0.6=default_hb173f14_7 - - clang_impl_osx-64=17.0.6=h1af8efd_23 - - clang_osx-64=17.0.6=h7e5c614_23 - - clangxx=17.0.6=default_he371ed4_7 - - clangxx_impl_osx-64=17.0.6=hc3430b7_23 - - clangxx_osx-64=17.0.6=h7e5c614_23 - - cliquer=1.22=h10d778d_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compiler-rt=17.0.6=h1020d70_2 - - compiler-rt_osx-64=17.0.6=hf2b8a54_2 - - contourpy=1.3.0=py39h0d3c867_2 - - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py39hd18e689_0 - - cpython=3.9.20=py39hd8ed1ab_1 - - cxx-compiler=1.8.0=h385f146_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py39hc0d7317_0 - - cysignals=1.11.2=py39hf6ae30e_3 - - cython=3.0.11=py39h84f6f9c_3 - - debugpy=1.8.9=py39hdf37715_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - ecl=24.5.10=h56bac16_0 - - eclib=20231212=h02435c3_0 - - ecm=7.0.5=h4f6b447_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 - - expat=2.6.4=h240833e_0 - - fflas-ffpack=2.5.0=h5898d61_0 - - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 - - font-ttf-inconsolata=3.000=h77eed37_0 - - font-ttf-source-code-pro=2.038=h77eed37_0 - - font-ttf-ubuntu=0.83=h77eed37_3 - - fontconfig=2.15.0=h37eeddb_1 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.55.0=py39hd18e689_0 - - fortran-compiler=1.8.0=h33d1f46_1 - - fplll=5.4.5=hb7981ad_0 - - fpylll=0.6.1=py39h3b3ffec_0 - - freetype=2.12.1=h60636b9_2 - - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h2299be9_0 - - gap-defaults=4.13.1=h694c41f_0 - - gettext=0.22.5=hdfe23c8_3 - - gettext-tools=0.22.5=hdfe23c8_3 - - gf2x=1.3.0=hb2a7efb_2 - - gfan=0.6.2=hd793b56_1003 - - gfortran=13.2.0=h2c809b3_1 - - gfortran_impl_osx-64=13.2.0=h2bc304d_3 - - gfortran_osx-64=13.2.0=h18f7dce_1 - - giac=1.9.0.21=h92f3f65_1 - - givaro=4.2.0=h1b3d6f7_0 - - glpk=5.0=h3cb5acd_0 - - gmp=6.3.0=hf036a51_2 - - gmpy2=2.1.5=py39h8ddd0cc_2 - - gsl=2.7=h93259b0_0 - - h2=4.1.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=75.1=h120a0e1_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=h5479cbe_0 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h61918c1_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - importlib-resources=6.4.5=pyhd8ed1ab_0 - - importlib_resources=6.4.5=pyhd8ed1ab_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 - - ipykernel=6.29.5=pyh57ce528_0 - - ipython=8.18.1=pyh707e725_3 - - ipywidgets=8.1.5=pyhd8ed1ab_0 - - isl=0.26=imath32_h2e86a7b_101 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 - - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 - - kiwisolver=1.4.7=py39h0d8d0ca_0 - - krb5=1.21.3=h37d8d59_0 - - lcalc=2.0.5=h547a6ed_2 - - lcms2=2.16=ha2f27b4_0 - - ld64=951.9=h0a3eb4e_2 - - ld64_osx-64=951.9=h5ffbe8e_2 - - lerc=4.0.0=hb486fe8_0 - - libasprintf=0.22.5=hdfe23c8_3 - - libasprintf-devel=0.22.5=hdfe23c8_3 - - libblas=3.9.0=25_osx64_openblas - - libboost=1.85.0=hcca3243_4 - - libboost-devel=1.85.0=h2b186f8_4 - - libboost-headers=1.85.0=h694c41f_4 - - libbraiding=1.3=h240833e_0 - - libbrial=1.2.12=h81e9653_3 - - libbrotlicommon=1.1.0=h00291cd_2 - - libbrotlidec=1.1.0=h00291cd_2 - - libbrotlienc=1.1.0=h00291cd_2 - - libcblas=3.9.0=25_osx64_openblas - - libclang-cpp17=17.0.6=default_hb173f14_7 - - libcurl=8.10.1=h58e7537_0 - - libcxx=19.1.4=hf95d169_0 - - libcxx-devel=17.0.6=h8f8a49f_6 - - libdeflate=1.22=h00291cd_0 - - libedit=3.1.20191231=h0678c8f_2 - - libev=4.33=h10d778d_2 - - libexpat=2.6.4=h240833e_0 - - libffi=3.4.2=h0d85af4_5 - - libflint=3.0.1=h1d27844_103 - - libgd=2.3.3=h2e77e4f_10 - - libgettextpo=0.22.5=hdfe23c8_3 - - libgettextpo-devel=0.22.5=hdfe23c8_3 - - libgfortran=5.0.0=13_2_0_h97931a8_3 - - libgfortran-devel_osx-64=13.2.0=h80d4556_3 - - libgfortran5=13.2.0=h2873a65_3 - - libhomfly=1.02r6=h10d778d_1 - - libiconv=1.17=hd75f5a5_2 - - libintl=0.22.5=hdfe23c8_3 - - libintl-devel=0.22.5=hdfe23c8_3 - - libjpeg-turbo=3.0.0=h0dc2134_1 - - liblapack=3.9.0=25_osx64_openblas - - liblapacke=3.9.0=25_osx64_openblas - - libllvm17=17.0.6=hbedff68_1 - - libnghttp2=1.64.0=hc7306c3_0 - - libopenblas=0.3.28=openmp_hbf64a52_1 - - libpng=1.6.44=h4b8f8c9_0 - - libsodium=1.0.20=hfdf4475_0 - - libsqlite=3.47.0=h2f8c449_1 - - libssh2=1.11.1=h3dc7d44_0 - - libtiff=4.7.0=h583c2ba_1 - - libwebp-base=1.4.0=h10d778d_0 - - libxcb=1.17.0=hf1f96e2_0 - - libxml2=2.13.5=h495214b_0 - - libzlib=1.3.1=hd23fc13_2 - - linbox=1.7.0=h7061c92_0 - - llvm-openmp=19.1.4=ha54dae1_0 - - llvm-tools=17.0.6=hbedff68_1 - - lrcalc=2.1=hac325c4_7 - - m4=1.4.18=haf1e3a3_1001 - - m4ri=20140914=hd82a5f3_1006 - - m4rie=20150908=hc616cfc_1002 - - markupsafe=3.0.2=py39h20cc651_0 - - matplotlib=3.9.2=py39h6e9494a_2 - - matplotlib-base=3.9.2=py39ha1b726c_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h3080a4d_3 - - memory-allocator=0.1.3=py39h06d86d0_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 - - mpc=1.3.1=h9d8efa1_1 - - mpfi=1.5.4=h52b28e3_1001 - - mpfr=4.2.1=haed47dc_3 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - nauty=2.8.8=h10d778d_1 - - ncurses=6.5=hf036a51_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h3c5361c_0 - - ntl=11.4.3=h0ab3c2f_1 - - numpy=1.26.4=py39h28c39a1_0 - - openblas=0.3.28=openmp_h30af337_1 - - openjpeg=2.5.2=h7310d3a_0 - - openssl=3.4.0=hd471939_0 - - packaging=24.2=pyhff2d567_1 - - palp=2.20=hbcb3906_0 - - pari=2.15.5=h7ba67ff_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - perl=5.32.1=7_h10d778d_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=11.0.0=py39h6cf2171_0 - - pip=24.3.1=pyh8b19718_0 - - pkg-config=0.29.2=hf7e621a_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - planarity=3.0.2.0=h10d778d_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ppl=1.2=ha60d53e_1006 - - pplpy=0.8.9=py39hc385998_1 - - primecount=7.6=ha894c9a_0 - - primecountpy=0.1.0=py39h8ee36c8_4 - - primesieve=11.0=hf0c8a7f_0 - - prompt-toolkit=3.0.48=pyha770c72_0 - - psutil=6.1.0=py39h296a897_0 - - pthread-stubs=0.4=h00291cd_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.9.20=hf24efe3_1_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 - - python-lrcalc=2.1=py39h7c0e7c0_7 - - python_abi=3.9=5_cp39 - - pytz=2024.2=pyhd8ed1ab_0 - - pyzmq=26.2.0=py39h7644d4c_3 - - qd=2.3.22=h2beb688_1004 - - qhull=2020.2=h3c5361c_5 - - readline=8.2=h9e318b2_1 - - requests=2.32.3=pyhd8ed1ab_0 - - rw=0.9=h10d778d_2 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - scipy=1.13.1=py39h038d4f4_0 - - setuptools=75.6.0=pyhff2d567_1 - - sigtool=0.1.3=h88f4db0_0 - - singular=4.4.0=h0c52cc7_0 - - six=1.16.0=pyh6c4a22f_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.4.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=h6285a30_1 - - stack_data=0.6.2=pyhd8ed1ab_0 - - symmetrica=3.0.1=hf0c8a7f_0 - - sympow=2.023.6=h115ba6a_3 - - sympy=1.13.3=pyh2585a3b_104 - - tachyon=0.99b6=h3a1d103_1002 - - tapi=1300.6.5=h390ca13_0 - - tk=8.6.13=h1abcd95_1 - - tomli=2.1.0=pyhff2d567_0 - - tornado=6.4.2=py39h80efdc8_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - tzdata=2024b=hc8b5060_0 - - unicodedata2=15.1.0=py39h296a897_1 - - urllib3=2.2.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=h00291cd_1 - - xorg-libxdmcp=1.1.5=h00291cd_0 - - xz=5.2.6=h775f41a_0 - - zeromq=4.3.5=h7130eaa_7 - - zipp=3.21.0=pyhd8ed1ab_1 - - zlib=1.3.1=hd23fc13_2 - - zstandard=0.23.0=py39hc23f734_1 - - zstd=1.5.6=h915ae27_0 diff --git a/environment-3.9-macos.yml b/environment-3.9-macos.yml deleted file mode 100644 index ac783c7e02f..00000000000 --- a/environment-3.9-macos.yml +++ /dev/null @@ -1,292 +0,0 @@ -name: sage-dev -# Generated by conda-lock. -# platform: osx-arm64 -# input_hash: 001c7b49d78852907ca5b2bef0b258fde0a46a8187c66ff7edbc8b3c0e988b51 - -channels: - - conda-forge -dependencies: - - alabaster=0.7.16=pyhd8ed1ab_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - arpack=3.9.1=nompi_h593882a_101 - - asttokens=2.4.1=pyhd8ed1ab_0 - - autoconf=2.71=pl5321hcd07c0c_1 - - automake=1.17=pl5321hce30654_0 - - babel=2.16.0=pyhd8ed1ab_0 - - bdw-gc=8.0.6=hc021e02_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - blas=2.125=openblas - - blas-devel=3.9.0=25_osxarm64_openblas - - boost-cpp=1.85.0=h103c1d6_4 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=hd74edd7_2 - - brotli-bin=1.1.0=hd74edd7_2 - - brotli-python=1.1.0=py39hfa9831e_2 - - bzip2=1.0.8=h99b78c6_7 - - c-ares=1.34.3=h5505292_1 - - c-compiler=1.8.0=hf48404e_1 - - ca-certificates=2024.8.30=hf0a4a13_0 - - cctools=1010.6=hf67d63f_2 - - cctools_osx-arm64=1010.6=h623e0ac_2 - - cddlib=1!0.94m=h6d7a090_0 - - certifi=2024.8.30=pyhd8ed1ab_0 - - cffi=1.17.1=py39h7f933ea_0 - - charset-normalizer=3.4.0=pyhd8ed1ab_0 - - clang=17.0.6=default_h360f5da_7 - - clang-17=17.0.6=default_h146c034_7 - - clang_impl_osx-arm64=17.0.6=he47c785_23 - - clang_osx-arm64=17.0.6=h07b0088_23 - - clangxx=17.0.6=default_h360f5da_7 - - clangxx_impl_osx-arm64=17.0.6=h50f59cd_23 - - clangxx_osx-arm64=17.0.6=h07b0088_23 - - cliquer=1.22=h93a5062_1 - - colorama=0.4.6=pyhd8ed1ab_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compiler-rt=17.0.6=h856b3c1_2 - - compiler-rt_osx-arm64=17.0.6=h832e737_2 - - contourpy=1.3.0=py39h85b62ae_2 - - conway-polynomials=0.10=pyhd8ed1ab_0 - - coverage=7.6.8=py39hefdd603_0 - - cpython=3.9.20=py39hd8ed1ab_1 - - cxx-compiler=1.8.0=h18dbf2f_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py39h070b2a8_0 - - cysignals=1.11.2=py39h65fc70a_3 - - cython=3.0.11=py39h20637d4_3 - - debugpy=1.8.9=py39h941272d_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - ecl=23.9.9=h1d9728a_0 - - eclib=20231212=h7f07de4_0 - - ecm=7.0.5=h41d338b_0 - - exceptiongroup=1.2.2=pyhd8ed1ab_0 - - execnet=2.1.1=pyhd8ed1ab_0 - - executing=2.1.0=pyhd8ed1ab_0 - - expat=2.6.4=h286801f_0 - - fflas-ffpack=2.5.0=h4bc3318_0 - - font-ttf-dejavu-sans-mono=2.37=hab24e00_0 - - font-ttf-inconsolata=3.000=h77eed37_0 - - font-ttf-source-code-pro=2.038=h77eed37_0 - - font-ttf-ubuntu=0.83=h77eed37_3 - - fontconfig=2.15.0=h1383a14_1 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.55.0=py39hefdd603_0 - - fortran-compiler=1.8.0=hc3477c4_1 - - fplll=5.4.5=hb7d509d_0 - - fpylll=0.6.1=py39h2eadeda_0 - - freetype=2.12.1=hadb7bae_2 - - furo=2024.8.6=pyhd8ed1ab_1 - - gap-core=4.13.1=h4cbeff9_0 - - gap-defaults=4.13.1=hce30654_0 - - gettext=0.22.5=h8414b35_3 - - gettext-tools=0.22.5=h8414b35_3 - - gf2x=1.3.0=hdaa854c_2 - - gfan=0.6.2=hec08f5c_1003 - - gfortran=13.2.0=h1ca8e4b_1 - - gfortran_impl_osx-arm64=13.2.0=h252ada1_3 - - gfortran_osx-arm64=13.2.0=h57527a5_1 - - giac=1.9.0.21=h1c96721_1 - - givaro=4.2.0=h018886a_0 - - glpk=5.0=h6d7a090_0 - - gmp=6.3.0=h7bae524_2 - - gmpy2=2.1.5=py39h0bbb021_2 - - gsl=2.7=h6e638da_0 - - h2=4.1.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=75.1=hfee45f7_0 - - idna=3.10=pyhd8ed1ab_0 - - igraph=0.10.15=h3fe6531_0 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=hd73f12c_1004 - - importlib-metadata=8.5.0=pyha770c72_0 - - importlib-resources=6.4.5=pyhd8ed1ab_0 - - importlib_resources=6.4.5=pyhd8ed1ab_0 - - iniconfig=2.0.0=pyhd8ed1ab_0 - - ipykernel=6.29.5=pyh57ce528_0 - - ipython=8.18.1=pyh707e725_3 - - ipywidgets=8.1.5=pyhd8ed1ab_0 - - isl=0.26=imath32_h347afa1_101 - - jedi=0.19.2=pyhff2d567_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jupyter_client=8.6.3=pyhd8ed1ab_0 - - jupyter_core=5.7.2=pyh31011fe_1 - - jupyterlab_widgets=3.0.13=pyhd8ed1ab_0 - - kiwisolver=1.4.7=py39h157d57c_0 - - krb5=1.21.3=h237132a_0 - - lcalc=2.0.5=h4a402bc_2 - - lcms2=2.16=ha0e7c42_0 - - ld64=951.9=h39a299f_2 - - ld64_osx-arm64=951.9=h3f9b568_2 - - lerc=4.0.0=h9a09cb3_0 - - libasprintf=0.22.5=h8414b35_3 - - libasprintf-devel=0.22.5=h8414b35_3 - - libblas=3.9.0=25_osxarm64_openblas - - libboost=1.85.0=hf763ba5_4 - - libboost-devel=1.85.0=hf450f58_4 - - libboost-headers=1.85.0=hce30654_4 - - libbraiding=1.3=h286801f_0 - - libbrial=1.2.12=h56a29cd_3 - - libbrotlicommon=1.1.0=hd74edd7_2 - - libbrotlidec=1.1.0=hd74edd7_2 - - libbrotlienc=1.1.0=hd74edd7_2 - - libcblas=3.9.0=25_osxarm64_openblas - - libclang-cpp17=17.0.6=default_h146c034_7 - - libcurl=8.10.1=h13a7ad3_0 - - libcxx=19.1.4=ha82da77_0 - - libcxx-devel=17.0.6=h86353a2_6 - - libdeflate=1.22=hd74edd7_0 - - libedit=3.1.20191231=hc8eb9b7_2 - - libev=4.33=h93a5062_2 - - libexpat=2.6.4=h286801f_0 - - libffi=3.4.2=h3422bc3_5 - - libflint=3.0.1=he28cf6d_103 - - libgd=2.3.3=hac1b3a8_10 - - libgettextpo=0.22.5=h8414b35_3 - - libgettextpo-devel=0.22.5=h8414b35_3 - - libgfortran=5.0.0=13_2_0_hd922786_3 - - libgfortran-devel_osx-arm64=13.2.0=h5d7a38c_3 - - libgfortran5=13.2.0=hf226fd6_3 - - libglib=2.82.2=h07bd6cf_0 - - libhomfly=1.02r6=h93a5062_1 - - libiconv=1.17=h0d3ecfb_2 - - libintl=0.22.5=h8414b35_3 - - libintl-devel=0.22.5=h8414b35_3 - - libjpeg-turbo=3.0.0=hb547adb_1 - - liblapack=3.9.0=25_osxarm64_openblas - - liblapacke=3.9.0=25_osxarm64_openblas - - libllvm17=17.0.6=h5090b49_2 - - libnghttp2=1.64.0=h6d7220d_0 - - libopenblas=0.3.28=openmp_hf332438_1 - - libpng=1.6.44=hc14010f_0 - - libsodium=1.0.20=h99b78c6_0 - - libsqlite=3.47.0=hbaaea75_1 - - libssh2=1.11.1=h9cc3647_0 - - libtiff=4.7.0=hfce79cd_1 - - libwebp-base=1.4.0=h93a5062_0 - - libxcb=1.17.0=hdb1d25a_0 - - libxml2=2.13.5=hbbdcc80_0 - - libzlib=1.3.1=h8359307_2 - - linbox=1.7.0=h3afee3a_0 - - llvm-openmp=19.1.4=hdb05f8b_0 - - llvm-tools=17.0.6=h5090b49_2 - - lrcalc=2.1=hf9b8971_7 - - m4=1.4.18=h642e427_1001 - - m4ri=20140914=hc97c1ff_1006 - - m4rie=20150908=h22b9e9d_1002 - - markupsafe=3.0.2=py39h66d85bf_0 - - matplotlib=3.9.2=py39hdf13c20_2 - - matplotlib-base=3.9.2=py39hc57f556_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h2bbcd85_2 - - memory-allocator=0.1.3=py39h06df861_1 - - meson=1.6.0=pyhd8ed1ab_0 - - meson-python=0.17.1=pyh70fd9c4_0 - - mpc=1.3.1=h8f1351a_1 - - mpfi=1.5.4=hbde5f5b_1001 - - mpfr=4.2.1=hb693164_3 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - nauty=2.8.8=h93a5062_1 - - ncurses=6.5=h7bae524_1 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h420ef59_0 - - ntl=11.4.3=hbb3f309_1 - - numpy=1.26.4=py39h7aa2656_0 - - openblas=0.3.28=openmp_hea878ba_1 - - openjpeg=2.5.2=h9f1df11_0 - - openssl=3.4.0=h39f12f2_0 - - packaging=24.2=pyhff2d567_1 - - palp=2.20=h27ca646_0 - - pari=2.15.5=h4f2304c_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - pcre2=10.44=h297a79d_2 - - perl=5.32.1=7_h4614cfb_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=11.0.0=py39h4ac03e3_0 - - pip=24.3.1=pyh8b19718_0 - - pkg-config=0.29.2=hde07d2e_1009 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - planarity=3.0.2.0=h93a5062_0 - - platformdirs=4.3.6=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ppl=1.2=h8b147cf_1006 - - pplpy=0.8.9=py39ha497ee3_1 - - primecount=7.6=hb6e4faa_0 - - primecountpy=0.1.0=py39hbd775c9_4 - - primesieve=11.0=hb7217d7_0 - - prompt-toolkit=3.0.48=pyha770c72_0 - - psutil=6.1.0=py39h57695bc_0 - - pthread-stubs=0.4=hd74edd7_1002 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.3=pyhd8ed1ab_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.2.0=pyhd8ed1ab_1 - - pyproject-metadata=0.9.0=pyh2cfa8aa_0 - - pysocks=1.7.1=pyha2e5f31_6 - - pytest=8.3.3=pyhd8ed1ab_0 - - pytest-xdist=3.6.1=pyhd8ed1ab_0 - - python=3.9.20=h9e33284_1_cpython - - python-dateutil=2.9.0.post0=pyhff2d567_0 - - python-lrcalc=2.1=py39hfa9831e_7 - - python_abi=3.9=5_cp39 - - pytz=2024.2=pyhd8ed1ab_0 - - pyzmq=26.2.0=py39h6e893d0_3 - - qd=2.3.22=hbec66e7_1004 - - qhull=2020.2=h420ef59_5 - - readline=8.2=h92ec313_1 - - requests=2.32.3=pyhd8ed1ab_0 - - rw=0.9=h93a5062_2 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - scipy=1.13.1=py39h3d5391c_0 - - setuptools=75.6.0=pyhff2d567_1 - - sigtool=0.1.3=h44b9a77_0 - - singular=4.4.0=h8aafc33_0 - - six=1.16.0=pyh6c4a22f_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.4.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_2 - - sphinx-inline-tabs=2023.4.21=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.1.0=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=2.0.0=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sqlite=3.47.0=hcd14bea_1 - - stack_data=0.6.2=pyhd8ed1ab_0 - - symmetrica=3.0.1=hb7217d7_0 - - sympow=2.023.6=hb0babe8_3 - - sympy=1.13.3=pyh2585a3b_104 - - tachyon=0.99b6=hb8a568e_1002 - - tapi=1300.6.5=h03f4b80_0 - - tk=8.6.13=h5083fa2_1 - - tomli=2.1.0=pyhff2d567_0 - - tornado=6.4.2=py39hf3bc14e_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - tzdata=2024b=hc8b5060_0 - - unicodedata2=15.1.0=py39h57695bc_1 - - urllib3=2.2.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - wheel=0.45.1=pyhd8ed1ab_0 - - widgetsnbextension=4.0.13=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=hd74edd7_1 - - xorg-libxdmcp=1.1.5=hd74edd7_0 - - xz=5.2.6=h57fd34a_0 - - zeromq=4.3.5=hc1bb282_7 - - zipp=3.21.0=pyhd8ed1ab_1 - - zlib=1.3.1=h8359307_2 - - zstandard=0.23.0=py39hcf1bb16_1 - - zstd=1.5.6=hb46c0d2_0 diff --git a/pyproject.toml b/pyproject.toml index e2b17964399..fc18fe0520f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,9 +4,8 @@ build-backend = 'mesonpy' requires = [ 'meson-python', 'cypari2 >=2.1.1', - # cysignals 1.11.2 is the newest version that is available on conda: - # https://github.com/conda-forge/cysignals-feedstock/pull/49 - 'cysignals >=1.11.2', + # Exclude 1.12.0 because of https://github.com/sagemath/cysignals/issues/212 + 'cysignals >=1.11.2, != 1.12.0', # Exclude 3.0.3 because of https://github.com/cython/cython/issues/5748 'cython >=3.0, != 3.0.3', 'gmpy2 ~=2.1.b999', @@ -21,7 +20,8 @@ dependencies = [ 'six >=1.15.0', 'conway-polynomials >=0.8', 'cypari2 >=2.1.1', - 'cysignals >=1.10.2', + # Exclude 1.12.0 because of https://github.com/sagemath/cysignals/issues/212 + 'cysignals >=1.11.2, != 1.12.0', 'cython >=3.0, != 3.0.3', 'gmpy2 ~=2.1.b999', 'lrcalc ~=2.1', diff --git a/tools/update-conda.py b/tools/update-conda.py index 7372a3e2379..3ed5a083785 100644 --- a/tools/update-conda.py +++ b/tools/update-conda.py @@ -27,7 +27,7 @@ "osx-arm64": "macos", # "win-64": "win", } -pythons = ["3.9", "3.10", "3.11"] +pythons = ["3.11", "3.12"] tags = [""] From 29a486275b0cb1407700ce125bb5bc7a30e8e936 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sun, 5 Jan 2025 22:33:53 -0600 Subject: [PATCH 120/175] don't tar old nonexistent files, call "find" correctly --- Makefile | 2 +- bootstrap | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9990af924c2..6bc60acdca3 100644 --- a/Makefile +++ b/Makefile @@ -173,7 +173,7 @@ distclean: build-clean bootstrap-clean: rm -rf config/install-sh config/compile config/config.guess config/config.sub config/missing configure build/make/Makefile-auto.in rm -f src/doc/en/installation/*.txt - find src/doc/en/reference/spkg -name index.rst -prune -o -maxdepth 1 -name "*.rst" -exec rm -f {} \+ + find src/doc/en/reference/spkg -maxdepth 1 -name index.rst -prune -o -name "*.rst" -exec rm -f {} \+ for a in environment environment-optional src/environment src/environment-optional; do rm -f $$a.yml $$a-3.[89].yml $$a-3.1[0-9].yml; done rm -f src/requirements.txt rm -f src/setup.cfg diff --git a/bootstrap b/bootstrap index 57dd5652d0b..00c2a1f7d54 100755 --- a/bootstrap +++ b/bootstrap @@ -224,8 +224,8 @@ save () { config/install-sh config/compile config/config.guess config/config.sub config/missing \ build/make/Makefile-auto.in \ src/doc/en/installation/*.txt \ - $(find src/doc/en/reference/spkg -name index.rst -prune -o -maxdepth 1 -name "*.rst" -print) \ - environment-3.[89]-*.yml environment-3.1[0-9]-*.yml \ + $(find src/doc/en/reference/spkg -maxdepth 1 -name index.rst -prune -o -name "*.rst" -print) \ + environment-3.1[0-9]-*.yml \ src/pyproject.toml \ src/requirements.txt \ src/setup.cfg \ From e88cac0d1f1c97b93fda31fd83e8f526c67cc2a7 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:38:57 +0700 Subject: [PATCH 121/175] Workaround to allow flint to be compiled with numpy 2 --- src/sage/libs/flint/flint_wrap.h | 5 +++++ src/sage_setup/autogen/flint/templates/flint_wrap.h.template | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/sage/libs/flint/flint_wrap.h b/src/sage/libs/flint/flint_wrap.h index 1302973779e..2cd39eb1441 100644 --- a/src/sage/libs/flint/flint_wrap.h +++ b/src/sage/libs/flint/flint_wrap.h @@ -26,6 +26,10 @@ #pragma push_macro("ulong") #undef ulong +/* Reserved in C99, needed for FLINT without https://github.com/flintlib/flint/pull/2027 */ +#pragma push_macro("I") +#define I Iv + #include /* If flint was already previously included via another header (e.g. @@ -169,6 +173,7 @@ #undef mp_bitcnt_t #pragma pop_macro("ulong") +#pragma pop_macro("I") /* CPU_SIZE_1 and SIZE_RED_FAILURE_THRESH are defined as macros in flint/fmpz_lll.h * and as variables in fplll/defs.h, which breaks build if linbox is compiled with fplll */ diff --git a/src/sage_setup/autogen/flint/templates/flint_wrap.h.template b/src/sage_setup/autogen/flint/templates/flint_wrap.h.template index 97323ede6ce..ec58aa2f602 100644 --- a/src/sage_setup/autogen/flint/templates/flint_wrap.h.template +++ b/src/sage_setup/autogen/flint/templates/flint_wrap.h.template @@ -26,6 +26,10 @@ #pragma push_macro("ulong") #undef ulong +/* Reserved in C99, needed for FLINT without https://github.com/flintlib/flint/pull/2027 */ +#pragma push_macro("I") +#define I Iv + #include /* If flint was already previously included via another header (e.g. @@ -43,6 +47,7 @@ #undef mp_bitcnt_t #pragma pop_macro("ulong") +#pragma pop_macro("I") /* CPU_SIZE_1 and SIZE_RED_FAILURE_THRESH are defined as macros in flint/fmpz_lll.h * and as variables in fplll/defs.h, which breaks build if linbox is compiled with fplll */ From 78bd23b71548d63de7ea502305cd10c48b46e849 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 6 Jan 2025 22:06:43 +0700 Subject: [PATCH 122/175] Fix segmentation fault in singular interface code --- src/sage/libs/singular/singular.pyx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index dd1c5a35239..198b3b53f4c 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -1403,13 +1403,6 @@ cdef number *sa2si_NF(object elem, ring *_ring) noexcept: cdef number *apow1 cdef number *apow2 - cdef nMapFunc nMapFuncPtr = NULL - - nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function - - if nMapFuncPtr is NULL: - raise RuntimeError("Failed to determine nMapFuncPtr") - elem = list(elem) if _ring != currRing: @@ -1432,7 +1425,10 @@ 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 + assert _ring.cf.type == n_algExt # if false naSetMap will segmentation fault (should never happen) + cdef nMapFunc nMapFuncPtr = naSetMap(qqr.cf, _ring.cf) # choose correct mapping function + if nMapFuncPtr is NULL: + raise RuntimeError("Failed to determine nMapFuncPtr") cdef poly *_p for i from 0 <= i < len(elem): nlCoeff = nlInit2gmp( mpq_numref((elem[i]).value), mpq_denref((elem[i]).value), qqr.cf ) From 0448df5aa25f22ea60535751a9e47cac1b1ca218 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 6 Jan 2025 22:59:10 +0530 Subject: [PATCH 123/175] Added doctest for lefschetz_element() --- src/sage/categories/kahler_algebras.py | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 02a679c4c4c..8186191f2ad 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -101,6 +101,34 @@ def poincare_pairing(a,b): @abstract_method def lefschetz_element(): + r""" + Return one Lefschetz element of the given Kähler algebra. + + EXAMPLES:: + + sage: U46 = matroids.Uniform(4,6) + sage: C = U46.chow_ring(QQ, False) + sage: w = C.lefschetz_element(); w + -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A05 - 2*A12 - 2*A13 - 2*A14 + - 2*A15 - 2*A23 - 2*A24 - 2*A25 - 2*A34 - 2*A35 - 2*A45 - 6*A012 + - 6*A013 - 6*A014 - 6*A015 - 6*A023 - 6*A024 - 6*A025 - 6*A034 + - 6*A035 - 6*A045 - 6*A123 - 6*A124 - 6*A125 - 6*A134 - 6*A135 + - 6*A145 - 6*A234 - 6*A235 - 6*A245 - 6*A345 - 30*A012345 + sage: basis_deg = {} + sage: for b in C.basis(): + ....: deg = b.homogeneous_degree() + ....: if deg not in basis_deg: + ....: basis_deg[deg] = [] + ....: basis_deg[deg].append(b) + sage: m = max(basis_deg); m + 3 + sage: len(basis_deg[1]) == len(basis_deg[2]) + True + sage: matrix([(w*b).to_vector() for b in basis_deg[1]]).rank() + 36 + sage: len(basis_deg[2]) + 36 + """ pass def hodge_riemann_relations(self, k): From 298de9bfa9ba62f0d10913dd56ad71d9e416c976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 7 Jan 2025 20:55:32 +0100 Subject: [PATCH 124/175] small cleanup in tropical files --- .../rings/semirings/tropical_mpolynomial.py | 23 +++--- .../rings/semirings/tropical_polynomial.py | 6 +- src/sage/rings/semirings/tropical_variety.py | 82 +++++++++---------- 3 files changed, 52 insertions(+), 59 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index d8011d2b033..8c7282770b0 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -33,9 +33,9 @@ # **************************************************************************** from sage.misc.cachefunc import cached_method +from sage.rings.polynomial.multi_polynomial_element import MPolynomial_polydict from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation -from sage.rings.polynomial.multi_polynomial_element import MPolynomial_polydict class TropicalMPolynomial(MPolynomial_polydict): @@ -286,8 +286,9 @@ def plot3d(self, color='random'): multivariate polynomial in two variables """ from random import random - from sage.plot.graphics import Graphics + from sage.geometry.polyhedron.constructor import Polyhedron + from sage.plot.graphics import Graphics from sage.sets.real_set import RealSet from sage.symbolic.relation import solve @@ -399,7 +400,11 @@ def tropical_variety(self): sage: p1.tropical_variety() Tropical surface of 1*x*y + (-1/2)*x*z + 4*z^2 """ - from sage.rings.semirings.tropical_variety import TropicalCurve, TropicalSurface, TropicalVariety + from sage.rings.semirings.tropical_variety import ( + TropicalCurve, + TropicalSurface, + TropicalVariety, + ) if self.parent().ngens() == 2: return TropicalCurve(self) @@ -617,8 +622,8 @@ def dual_subdivision(self): A vertex at (1, 0, 1, 0), A vertex at (1, 1, 0, 0))] """ - from sage.geometry.polyhedron.constructor import Polyhedron from sage.geometry.polyhedral_complex import PolyhedralComplex + from sage.geometry.polyhedron.constructor import Polyhedron TV = self.tropical_variety() cycles = [] @@ -627,18 +632,14 @@ def dual_subdivision(self): for indices in TV._vertices_components().values(): cycle = [] for index in indices: - vertices = TV._keys[index[0]] - for v in vertices: - cycle.append(v) + cycle.extend(TV._keys[index[0]]) cycles.append(cycle) else: line_comps = TV.weight_vectors()[1] for indices in line_comps.values(): cycle = [] for index in indices: - vertices = TV._keys[index] - for v in vertices: - cycle.append(v) + cycle.extend(TV._keys[index]) cycles.append(cycle) polyhedron_lst = [] @@ -729,8 +730,8 @@ def __init__(self, base_semiring, n, names, order): sage: R = PolynomialRing(T, 5, 'x') sage: TestSuite(R).run() """ - from sage.rings.semirings.tropical_semiring import TropicalSemiring from sage.categories.semirings import Semirings + from sage.rings.semirings.tropical_semiring import TropicalSemiring if not isinstance(base_semiring, TropicalSemiring): raise ValueError(f"{base_semiring} is not a tropical semiring") Parent.__init__(self, base=base_semiring, names=names, category=Semirings()) diff --git a/src/sage/rings/semirings/tropical_polynomial.py b/src/sage/rings/semirings/tropical_polynomial.py index ef00b53e4ca..0b59960923e 100644 --- a/src/sage/rings/semirings/tropical_polynomial.py +++ b/src/sage/rings/semirings/tropical_polynomial.py @@ -35,9 +35,9 @@ # **************************************************************************** from sage.misc.cachefunc import cached_method -from sage.structure.unique_representation import UniqueRepresentation -from sage.structure.parent import Parent from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_sparse +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation class TropicalPolynomial(Polynomial_generic_sparse): @@ -371,9 +371,9 @@ def piecewise_function(self): sage: p3.piecewise_function() 3*x + 1 """ - from sage.symbolic.ring import SR from sage.functions.piecewise import piecewise from sage.sets.real_set import RealSet + from sage.symbolic.ring import SR x = SR.var('x') data = self.monomial_coefficients() diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 63d92e6509f..3393a4416be 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -26,12 +26,11 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +from sage.rings.infinity import infinity +from sage.rings.rational_field import QQ from sage.structure.sage_object import SageObject from sage.structure.unique_representation import UniqueRepresentation -from sage.rings.rational_field import QQ -from sage.rings.infinity import infinity - class TropicalVariety(UniqueRepresentation, SageObject): r""" @@ -188,10 +187,11 @@ def __init__(self, poly): """ import operator from itertools import combinations - from sage.symbolic.ring import SR - from sage.symbolic.relation import solve + from sage.arith.misc import gcd from sage.rings.semirings.tropical_mpolynomial import TropicalMPolynomial + from sage.symbolic.relation import solve + from sage.symbolic.ring import SR if not isinstance(poly, TropicalMPolynomial): raise ValueError(f"{poly} is not a multivariate tropical polynomial") @@ -448,9 +448,10 @@ def _components_intersection(self): 5: [((0, t2, 0), {0 <= t2}), ((1/2*t2, t2, t2), {t2 <= 0})]} """ import operator + from sage.functions.min_max import max_symbolic, min_symbolic - from sage.symbolic.relation import solve from sage.sets.set import Set + from sage.symbolic.relation import solve def update_result(result): sol_param = solve(new_expr, vars) @@ -592,19 +593,20 @@ def weight_vectors(self): sage: all(a == vector([0,0,0,0]) for a in [sum(lst) for lst in vec]) True """ - from sage.symbolic.ring import SR - from sage.symbolic.relation import solve - from sage.calculus.functional import diff + from itertools import combinations + from sage.arith.misc import gcd + from sage.calculus.functional import diff from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector, zero_vector - from itertools import combinations + from sage.symbolic.relation import solve + from sage.symbolic.ring import SR dim = self.dimension() t = SR.var('t') - t_vars = [SR.var('t{}'.format(i)) for i in range(dim)] - u_vars = [SR.var('u{}'.format(i)) for i in range(dim)] - convert_tu = {ti: ui for ti, ui in zip(t_vars, u_vars)} + t_vars = [SR.var(f't{i}') for i in range(dim)] + u_vars = [SR.var(f'u{i}') for i in range(dim)] + convert_tu = dict(zip(t_vars, u_vars)) CI = self._components_intersection() unique_line = set() index_line = {} @@ -657,9 +659,9 @@ def weight_vectors(self): if is_unique: new_eqn = tuple([eq.subs(convert_tu) for eq in eqn]) cdns = line[1] - new_cdn = set([cdn.subs(convert_tu) for cdn in cdns]) + new_cdn = {cdn.subs(convert_tu) for cdn in cdns} unique_line.add(new_eqn) - index_line[index] = tuple([new_eqn, new_cdn]) + index_line[index] = (new_eqn, new_cdn) line_comps[index] = [i] index += 1 else: @@ -676,9 +678,7 @@ def weight_vectors(self): for v in l.variables(): all_var.add(v) for vpar in all_var: - par_drv = [] - for l in line: - par_drv.append(QQ(diff(l, vpar))) + par_drv = [QQ(diff(l, vpar)) for l in line] par_drv = vector(par_drv) dir_vecs.append(par_drv) @@ -688,32 +688,24 @@ def weight_vectors(self): surface = self._hypersurface[i][0] drv_vectors = [] for vpar in self._vars: - temp_vec = [] - for s in surface: - temp_vec.append(QQ(diff(s, vpar))) + temp_vec = [QQ(diff(s, vpar)) for s in surface] temp_vec = vector(temp_vec) drv_vectors.append(temp_vec) temp = [t_vars] - for vec in drv_vectors: - temp.append(vec) + temp.extend(drv_vectors) vec_matrix = matrix(SR, temp) normal_vec = vec_matrix.det() - temp_nor = [] - for tvar in t_vars: - temp_nor.append(QQ(diff(normal_vec, tvar))) + temp_nor = [QQ(diff(normal_vec, tvar)) for tvar in t_vars] normal_vec = vector(temp_nor) normal_vec *= 1/gcd(normal_vec) # Calculate the weight vector temp_final = [t_vars] - for v in dir_vecs: - temp_final.append(v) + temp_final.extend(dir_vecs) temp_final.append(normal_vec) vec_matrix = matrix(SR, temp_final) weight_vec = vec_matrix.det() - temp_weight = [] - for tvar in t_vars: - temp_weight.append(QQ(diff(weight_vec, tvar))) + temp_weight = [QQ(diff(weight_vec, tvar)) for tvar in t_vars] weight_vec = vector(temp_weight) order = self._hypersurface[i][2] weight_vec *= order @@ -722,7 +714,7 @@ def weight_vectors(self): balance = False for i in range(1, len(WV[k])+1): for j in combinations(range(len(WV[k])), i): - test_vectors = [v for v in WV[k]] + test_vectors = list(WV[k]) for idx in j: test_vectors[idx] = -test_vectors[idx] if sum(test_vectors) == zero_vector(QQ, dim): @@ -791,8 +783,8 @@ def _axes(self): sage: p2.tropical_variety()._axes() [[-1, 2], [-1, 2], [-1, 2]] """ - from sage.symbolic.relation import solve from sage.arith.srange import srange + from sage.symbolic.relation import solve if not self._hypersurface: return [[-1, 1], [-1, 1], [-1, 1]] @@ -911,8 +903,8 @@ def _polygon_vertices(self): 7: {(-1/2, -1, -1), (-1/2, 2, -1), (0, 0, 0), (0, 2, 0)}, 8: {(1, 1, 1), (1, 2, 1), (2, 1, 1), (2, 2, 1)}} """ - from sage.symbolic.relation import solve from sage.sets.real_set import RealSet + from sage.symbolic.relation import solve poly_verts = {i: set() for i in range(self.number_of_components())} axes = self._axes() @@ -1057,8 +1049,9 @@ def plot(self, color='random'): sphinx_plot(p2.tropical_variety().plot()) """ from random import random - from sage.plot.graphics import Graphics + from sage.geometry.polyhedron.constructor import Polyhedron + from sage.plot.graphics import Graphics if color == 'random': colors = [] @@ -1283,17 +1276,17 @@ def _vertices_components(self): if lower != -infinity: x = parametric_function[0].subs(**{str(v): lower}) y = parametric_function[1].subs(**{str(v): lower}) - if (x,y) not in comp_vert: - comp_vert[(x,y)] = [(i, 1)] + if (x, y) not in comp_vert: + comp_vert[(x, y)] = [(i, 1)] else: - comp_vert[(x,y)].append((i, 1)) + comp_vert[(x, y)].append((i, 1)) if upper != infinity: x = parametric_function[0].subs(**{str(v): upper}) y = parametric_function[1].subs(**{str(v): upper}) - if (x,y) not in comp_vert: - comp_vert[(x,y)] = [(i, -1)] + if (x, y) not in comp_vert: + comp_vert[(x, y)] = [(i, -1)] else: - comp_vert[(x,y)].append((i, -1)) + comp_vert[(x, y)].append((i, -1)) return comp_vert def weight_vectors(self): @@ -1334,9 +1327,9 @@ def weight_vectors(self): (-1, 0): [(-1, 0), (0, -1), (1, 1)], (3, 4): [(-1, -1), (0, 1), (1, 0)]} """ + from sage.arith.misc import gcd from sage.calculus.functional import diff from sage.modules.free_module_element import vector - from sage.arith.misc import gcd if not self._vertices_components(): return {} @@ -1636,10 +1629,9 @@ def plot(self): + R(4)*x**3*y + x**2*y**2 + R(2)*x*y**3 + y**4) sphinx_plot(p3.tropical_variety().plot()) """ - from sage.plot.plot import plot - from sage.plot.text import text from sage.plot.graphics import Graphics - from sage.plot.plot import parametric_plot + from sage.plot.plot import parametric_plot, plot + from sage.plot.text import text if not self._hypersurface: return plot(lambda x: float('nan'), {-1, 1}) From b9cf5a95c7544acef3afdb73903edbeb2a13dc69 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 8 Jan 2025 08:52:29 +0700 Subject: [PATCH 125/175] Add a test --- src/sage/libs/singular/singular.pyx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 198b3b53f4c..d4ed0e3b064 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -1393,6 +1393,13 @@ cdef number *sa2si_NF(object elem, ring *_ring) noexcept: (a + 1) sage: R(F.gen()^5) + 1 (-a^2 + a + 2) + + Ensures :issue:`36101` is fixed:: + + sage: RR. = AA[] + sage: f = -4*r^2+(((1+2*AA(cos(pi/6)))*c0*r+2*c1*r+(1+2*AA(cos(pi/6)))*s0*r+2*s1*r)/2-1/2)^2+((1-(1+2*AA(cos(pi/6)))*c0*r-2*c1*r+(1+2*AA(cos(pi/6)))*s0*r+2*s1*r)/2-1/2)^2 + sage: f.change_ring( QuadraticField(3) ) + ... """ cdef int i cdef number *n1 From b4819173711e4ab0cb17ca8e14eb911c9a312f82 Mon Sep 17 00:00:00 2001 From: Enrique Artal Date: Wed, 8 Jan 2025 17:10:51 +0100 Subject: [PATCH 126/175] using new libbrading --- src/sage/schemes/curves/zariski_vankampen.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/sage/schemes/curves/zariski_vankampen.py b/src/sage/schemes/curves/zariski_vankampen.py index 1a6591d6f9b..f7a7cb28921 100644 --- a/src/sage/schemes/curves/zariski_vankampen.py +++ b/src/sage/schemes/curves/zariski_vankampen.py @@ -1426,17 +1426,15 @@ def conjugate_positive_form(braid): sage: from sage.schemes.curves.zariski_vankampen import conjugate_positive_form sage: B = BraidGroup(4) sage: t = B((1, 3, 2, -3, 1, 1)) - sage: conjugate_positive_form(t) + sage: cpf = conjugate_positive_form(t); cpf [[(s0*s1)^2, [s0*s2*s1*s0]]] + sage: t == prod(prod(b) * a / prod(b) for a, b in cpf) + True sage: B = BraidGroup(5) sage: t = B((1, 2, 3, 4, -1, -2, 3, 3, 2, -4)) sage: L = conjugate_positive_form(t); L [[s0^2, [s0*s1*s2*s1*s3*s2*s1*s0]], [s3*s2, [s0*s1*s2*s1*s3*s2*s1*s0]]] - sage: s = B.one() - sage: for a, l in L: - ....: b = prod(l) - ....: s *= b * a / b - sage: s == t + sage: t == prod(prod(b) * a / prod(b) for a, b in L) True sage: s1 = B.gen(1)^3 sage: conjugate_positive_form(s1) @@ -1470,14 +1468,13 @@ def conjugate_positive_form(braid): else: bra = sg0 * B(a) / sg0 br1, sg = bra.super_summit_set_element() - res = None A1 = rightnormalform(sg) par = A1[-1][0] % 2 A1 = [B(a0) for a0 in A1[:-1]] res = [br1, A1, par] if res[2]: r0 = res[0].Tietze() - res[0] = B([i.sign() * (d - abs(i)) for i in r0]) + res[0] = B([d - i for i in r0]) res0 = res[:2] shorts.append(res0) return shorts From 7a2ae3f9209c6bd583b606985100254ac71ca652 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 9 Jan 2025 09:36:14 +0530 Subject: [PATCH 127/175] Edited documentation --- src/sage/categories/kahler_algebras.py | 41 +++++++++++++------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index 8186191f2ad..a08ab008b92 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -30,39 +30,48 @@ class KahlerAlgebras(Category_over_base_ring): A finite-dimensional graded algebra `\bigoplus_{k=1}^{r}A^k` satisfies the *Kähler package* if the following properties hold: - - Poincaré duality: There exists a perfect `\mathbb{Z}`-bilinear pairing + - Poincaré duality: There exists a perfect `\ZZ`-bilinear pairing given by .. MATH:: - A^k \times A^{r-k} \longrightarrow \mathbb{Z} \\ - (a,b) \mapsto \text{deg}(a \cdot b). + A^k \times A^{r-k} \longrightarrow \ZZ \\ + (a,b) \mapsto \deg(a \cdot b). - Hard-Lefschetz Theorem: The graded algebra contains *Lefschetz elements* - `\omega \in A^{1}_{\mathbb{R}}` such that multiplication by `\omega` is - an injection from `A^k_{\mathbb{R}} \longrightarrow A^{k+1}_{\mathbb{R}}` + `\omega \in A^{1}_{\RR}` such that multiplication by `\omega` is + an injection from `A^k_{\RR} \longrightarrow A^{k+1}_{\RR}` for all `k < \frac{r}{2}`. - Hodge-Riemann-Minikowski Relations: Every Lefchetz element `\omega`, - define quadratic forms on `A^{k}_{\mathbb{R}}` given by + define quadratic forms on `A^{k}_{\RR}` given by .. MATH:: - a \mapsto (-1)^k \text{deg}(a \cdot \omega^{r-2k} \cdot a) + a \mapsto (-1)^k \deg(a \cdot \omega^{r-2k} \cdot a) This quadratic form becomes positive definite upon restriction to the kernel of the following map .. MATH:: - A^k_\mathbb{R} \longrightarrow A^{r-k+1}_\mathbb{R} \\ + A^k_\RR \longrightarrow A^{r-k+1}_\RR \\ a \mapsto a \cdot \omega^{r-2k+1}. REFERENCES: - [ANR2023]_ - EXAMPLES:: + TESTS:: + + sage: C = KahlerAlgebras(QQ) + sage: TestSuite(C).run() + """ + def super_categories(self): + r""" + Return the super categories of ``self``. + + EXAMPLES:: sage: from sage.categories.kahler_algebras import KahlerAlgebras @@ -71,18 +80,12 @@ class KahlerAlgebras(Category_over_base_ring): sage: sorted(C.super_categories(), key=str) [Category of finite dimensional graded algebras with basis over Rational Field] - - TESTS:: - - sage: C = KahlerAlgebras(QQ) - sage: TestSuite(C).run() - """ - def super_categories(self): + """ return [GradedAlgebrasWithBasis(self.base_ring()).FiniteDimensional()] class ParentMethods: @abstract_method - def poincare_pairing(a,b): + def poincare_pairing(self, a,b): r""" Return the Poincaré pairing of two elements of the Kähler algebra. @@ -97,10 +100,9 @@ def poincare_pairing(a,b): sage: ch.poincare_pairing(v, u) 3 """ - pass @abstract_method - def lefschetz_element(): + def lefschetz_element(self): r""" Return one Lefschetz element of the given Kähler algebra. @@ -129,7 +131,6 @@ def lefschetz_element(): sage: len(basis_deg[2]) 36 """ - pass def hodge_riemann_relations(self, k): r""" From cccf43304e4b02eeb40500311ba9d29d00731483 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 9 Jan 2025 09:46:05 +0530 Subject: [PATCH 128/175] Edited documentation --- src/sage/categories/kahler_algebras.py | 44 +++++++++++++------------- src/sage/matroids/chow_ring.py | 14 ++++---- src/sage/matroids/chow_ring_ideal.py | 13 ++++---- 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index a08ab008b92..d43b6267d72 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -73,32 +73,32 @@ def super_categories(self): EXAMPLES:: - sage: from sage.categories.kahler_algebras import KahlerAlgebras + sage: from sage.categories.kahler_algebras import KahlerAlgebras - sage: C = KahlerAlgebras(QQ); C - Category of kahler algebras over Rational Field - sage: sorted(C.super_categories(), key=str) - [Category of finite dimensional graded algebras with basis over - Rational Field] + sage: C = KahlerAlgebras(QQ); C + Category of kahler algebras over Rational Field + sage: sorted(C.super_categories(), key=str) + [Category of finite dimensional graded algebras with basis over + Rational Field] """ return [GradedAlgebrasWithBasis(self.base_ring()).FiniteDimensional()] class ParentMethods: @abstract_method - def poincare_pairing(self, a,b): + def poincare_pairing(self, a, b): r""" Return the Poincaré pairing of two elements of the Kähler algebra. - EXAMPLES:: + EXAMPLES:: - sage: ch = matroids.catalog.Fano().chow_ring(QQ, True, 'fy') - sage: Ba, Bb, Bc, Bd, Be, Bf, Bg, Babf, Bace, Badg, Bbcd, Bbeg, Bcfg, Bdef, Babcdefg = ch.gens()[8:] - sage: u = ch(-Babf^2 + Bcfg^2 - 8/7*Bc*Babcdefg + 1/2*Bd*Babcdefg - Bf*Babcdefg - Bg*Babcdefg); u - -Babf^2 + Bcfg^2 - 8/7*Bc*Babcdefg + 1/2*Bd*Babcdefg - Bf*Babcdefg - Bg*Babcdefg - sage: v = ch(Bg - 2/37*Babf + Badg + Bbeg + Bcfg + Babcdefg); v - Bg - 2/37*Babf + Badg + Bbeg + Bcfg + Babcdefg - sage: ch.poincare_pairing(v, u) - 3 + sage: ch = matroids.catalog.Fano().chow_ring(QQ, True, 'fy') + sage: Ba, Bb, Bc, Bd, Be, Bf, Bg, Babf, Bace, Badg, Bbcd, Bbeg, Bcfg, Bdef, Babcdefg = ch.gens()[8:] + sage: u = ch(-Babf^2 + Bcfg^2 - 8/7*Bc*Babcdefg + 1/2*Bd*Babcdefg - Bf*Babcdefg - Bg*Babcdefg); u + -Babf^2 + Bcfg^2 - 8/7*Bc*Babcdefg + 1/2*Bd*Babcdefg - Bf*Babcdefg - Bg*Babcdefg + sage: v = ch(Bg - 2/37*Babf + Badg + Bbeg + Bcfg + Babcdefg); v + Bg - 2/37*Babf + Badg + Bbeg + Bcfg + Babcdefg + sage: ch.poincare_pairing(v, u) + 3 """ @abstract_method @@ -108,7 +108,7 @@ def lefschetz_element(self): EXAMPLES:: - sage: U46 = matroids.Uniform(4,6) + sage: U46 = matroids.Uniform(4, 6) sage: C = U46.chow_ring(QQ, False) sage: w = C.lefschetz_element(); w -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A05 - 2*A12 - 2*A13 - 2*A14 @@ -134,12 +134,12 @@ def lefschetz_element(self): def hodge_riemann_relations(self, k): r""" - Return the quadratic form for the corresponding k (< r/2) for the - Kähler algebra. + Return the quadratic form for the corresponding ``k`` + (`< \frac{r}{2}`) for the Kähler algebra, where `r` is the top degree. EXAMPLES:: - sage: ch = matroids.Uniform(4,6).chow_ring(QQ, False) + sage: ch = matroids.Uniform(4, 6).chow_ring(QQ, False) sage: ch.hodge_riemann_relations(1) Quadratic form in 36 variables over Rational Field with coefficients: [ 3 -1 -1 3 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 3 ] @@ -181,11 +181,11 @@ def hodge_riemann_relations(self, k): sage: ch.hodge_riemann_relations(3) Traceback (most recent call last): ... - ValueError: k must be less than r < 2 + ValueError: k must be less than r/2 < 2 """ r = self.top_degree() if k > (r/2): - raise ValueError("k must be less than r < 2") + raise ValueError("k must be less than r/2 < 2") basis_k = [] lefschetz_el = self.lefschetz_element() for b in self.basis(): diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 7dca223bb40..e642e1bb475 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -53,8 +53,10 @@ class ChowRing(QuotientRing_generic): :mod:`sage.matroids.chow_ring_ideal` - An important note to be taken is that different presentations of Chow rings - of non-simple matroids may not be isomorphic to one another. + .. WARNING:: + + Different presentations of Chow rings of non-simple matroids may not be + isomorphic to one another. INPUT: @@ -131,7 +133,7 @@ def _latex_(self): EXAMPLES:: - sage: M1 = matroids.Uniform(2,5) + sage: M1 = matroids.Uniform(2, 5) sage: ch = M1.chow_ring(QQ, False) sage: ch._latex_() 'A(\\begin{array}{l}\n\\text{\\texttt{U(2,{ }5):{ }Matroid{ }of{ }rank{ }2{ }on{ }5{ }elements{ }with{ }circuit{-}closures}}\\\\\n\\text{\\texttt{{\\char`\\{}2:{ }{\\char`\\{}{\\char`\\{}0,{ }1,{ }2,{ }3,{ }4{\\char`\\}}{\\char`\\}}{\\char`\\}}}}\n\\end{array})_{\\Bold{Q}}' @@ -148,7 +150,7 @@ def matroid(self): EXAMPLES:: - sage: ch = matroids.Uniform(3,6).chow_ring(QQ, True, 'fy') + sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, True, 'fy') sage: ch.matroid() U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} @@ -225,7 +227,7 @@ def lefschetz_element(self): It is then multiplied with the elements of FY-monomial bases of different degrees:: - sage: ch = matroids.Uniform(4,5).chow_ring(QQ, False) + sage: ch = matroids.Uniform(4, 5).chow_ring(QQ, False) sage: basis_deg = {} sage: for b in ch.basis(): ....: deg = b.homogeneous_degree() @@ -285,7 +287,7 @@ def lefschetz_element(self): TESTS:: - sage: U46 = matroids.Uniform(4,6) + sage: U46 = matroids.Uniform(4, 6) sage: C = U46.chow_ring(QQ, False) sage: w = C.lefschetz_element(); w -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A05 - 2*A12 - 2*A13 - 2*A14 diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index db830ab0fc2..625bec8d7b9 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -21,7 +21,7 @@ def matroid(self): EXAMPLES:: - sage: ch = matroids.Uniform(3,6).chow_ring(QQ, False) + sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False) sage: ch.defining_ideal().matroid() U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} @@ -63,7 +63,7 @@ def flats_to_generator_dict(self): EXAMPLES:: - sage: ch = matroids.Uniform(4,6).chow_ring(QQ, True, 'atom-free') + sage: ch = matroids.Uniform(4, 6).chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal().flats_to_generator_dict() {frozenset({0}): A0, frozenset({1}): A1, frozenset({2}): A2, frozenset({3}): A3, frozenset({4}): A4, frozenset({5}): A5, @@ -87,8 +87,7 @@ def flats_to_generator_dict(self): frozenset({3, 4, 5}): A345, frozenset({0, 1, 2, 3, 4, 5}): A012345} """ - flats_gen = self._flats_generator - return flats_gen + return dict(self._flats_generator) class ChowRingIdeal_nonaug(ChowRingIdeal): @@ -129,7 +128,7 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): Chow ring ideal of uniform matroid of rank 3 on 6 elements:: - sage: ch = matroids.Uniform(3,6).chow_ring(QQ, False) + sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False) sage: ch.defining_ideal() Chow ring ideal of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} - non augmented @@ -576,7 +575,7 @@ def normal_basis(self, algorithm='', *args, **kwargs): EXAMPLES:: - sage: ch = matroids.Uniform(2,5).chow_ring(QQ, True, 'fy') + sage: ch = matroids.Uniform(2, 5).chow_ring(QQ, True, 'fy') sage: I = ch.defining_ideal() sage: I.normal_basis() [1, B0, B1, B2, B3, B4, B01234, B01234^2] @@ -753,7 +752,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): EXAMPLES:: - sage: M1 = matroids.Uniform(3,6) + sage: M1 = matroids.Uniform(3, 6) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal().groebner_basis(algorithm='') Polynomial Sequence with 253 Polynomials in 22 Variables From 693792597cf3a3e74cfa57192468340fedc8e14d Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 9 Jan 2025 09:46:25 +0530 Subject: [PATCH 129/175] Edited top_degree() methd --- src/sage/categories/graded_algebras_with_basis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/graded_algebras_with_basis.py b/src/sage/categories/graded_algebras_with_basis.py index 180760d1f32..254020f09ff 100644 --- a/src/sage/categories/graded_algebras_with_basis.py +++ b/src/sage/categories/graded_algebras_with_basis.py @@ -171,7 +171,7 @@ def top_degree(self): sage: ch.top_degree() 3 """ - return max([b.degree() for b in self.basis()]) + return max(b.degree() for b in self.basis()) class SignedTensorProducts(SignedTensorProductsCategory): """ From 7a2352586b9f723fb2fe7ae60489a4320aa42f86 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 9 Jan 2025 09:52:58 +0530 Subject: [PATCH 130/175] Formatted documentation --- src/sage/categories/kahler_algebras.py | 20 +++++++-------- src/sage/matroids/chow_ring.py | 34 +++++++------------------- src/sage/matroids/chow_ring_ideal.py | 9 +++++++ 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index d43b6267d72..cda0ce871a9 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -5,6 +5,15 @@ - Shriya M """ +# **************************************************************************** +# Copyright (C) 2024 Shriya M <25shriya at gmail.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.categories.category_types import Category_over_base_ring from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis @@ -15,15 +24,6 @@ from sage.misc.cachefunc import cached_method -# **************************************************************************** -# Copyright (C) 2024 Shriya M <25shriya at gmail.com> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# https://www.gnu.org/licenses/ -# **************************************************************************** class KahlerAlgebras(Category_over_base_ring): r""" The category of graded algebras satisfying the Kähler package. @@ -134,7 +134,7 @@ def lefschetz_element(self): def hodge_riemann_relations(self, k): r""" - Return the quadratic form for the corresponding ``k`` + Return the quadratic form for the corresponding ``k`` (`< \frac{r}{2}`) for the Kähler algebra, where `r` is the top degree. EXAMPLES:: diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index e642e1bb475..5fea543aeb3 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -5,6 +5,15 @@ - Shriya M """ +# **************************************************************************** +# Copyright (C) 2024 Shriya M <25shriya at gmail.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug, AugmentedChowRingIdeal_fy, AugmentedChowRingIdeal_atom_free from sage.rings.quotient_ring import QuotientRing_generic @@ -284,31 +293,6 @@ def lefschetz_element(self): 6*A01234^3, 6*A01234^3, 2*A01234^3, 2*A01234^3, 6*A01234^3, 2*A01234^3, 6*A01234^3, 6*A01234^3, 2*A01234^3, 6*A01234^3, 6*A01234^3, 6*A01234^3, -20*A01234^3], 3: [0]} - - TESTS:: - - sage: U46 = matroids.Uniform(4, 6) - sage: C = U46.chow_ring(QQ, False) - sage: w = C.lefschetz_element(); w - -2*A01 - 2*A02 - 2*A03 - 2*A04 - 2*A05 - 2*A12 - 2*A13 - 2*A14 - - 2*A15 - 2*A23 - 2*A24 - 2*A25 - 2*A34 - 2*A35 - 2*A45 - 6*A012 - - 6*A013 - 6*A014 - 6*A015 - 6*A023 - 6*A024 - 6*A025 - 6*A034 - - 6*A035 - 6*A045 - 6*A123 - 6*A124 - 6*A125 - 6*A134 - 6*A135 - - 6*A145 - 6*A234 - 6*A235 - 6*A245 - 6*A345 - 30*A012345 - sage: basis_deg = {} - sage: for b in C.basis(): - ....: deg = b.homogeneous_degree() - ....: if deg not in basis_deg: - ....: basis_deg[deg] = [] - ....: basis_deg[deg].append(b) - sage: m = max(basis_deg); m - 3 - sage: len(basis_deg[1]) == len(basis_deg[2]) - True - sage: matrix([(w*b).to_vector() for b in basis_deg[1]]).rank() - 36 - sage: len(basis_deg[2]) - 36 """ w = sum(len(F) * (len(self.matroid().groundset()) - len(F)) * gen for F, gen in self.defining_ideal().flats_to_generator_dict().items()) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 625bec8d7b9..00b5592ee42 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -5,6 +5,15 @@ - Shriya M """ +# **************************************************************************** +# Copyright (C) 2024 Shriya M <25shriya at gmail.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal from sage.matroids.utilities import cmp_elements_key From cac23787c0300f82383c472b3dfb9b5f904d25cf Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 9 Jan 2025 11:21:58 +0530 Subject: [PATCH 131/175] Edited doctest --- src/sage/categories/kahler_algebras.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/categories/kahler_algebras.py b/src/sage/categories/kahler_algebras.py index cda0ce871a9..d8791ae78fb 100644 --- a/src/sage/categories/kahler_algebras.py +++ b/src/sage/categories/kahler_algebras.py @@ -64,6 +64,8 @@ class KahlerAlgebras(Category_over_base_ring): TESTS:: + sage: from sage.categories.kahler_algebras import KahlerAlgebras + sage: C = KahlerAlgebras(QQ) sage: TestSuite(C).run() """ From a0695685b3fca00b04775421d53902e24c0abf5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 9 Jan 2025 16:39:13 +0100 Subject: [PATCH 132/175] adding the category keyword to padic rings and fields classes --- src/sage/rings/padics/factory.py | 31 ++++++++---- src/sage/rings/padics/generic_nodes.py | 4 +- src/sage/rings/padics/padic_base_generic.py | 4 +- src/sage/rings/padics/padic_base_leaves.py | 52 ++++++++++----------- 4 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/sage/rings/padics/factory.py b/src/sage/rings/padics/factory.py index a0990ad1720..de5e112343f 100644 --- a/src/sage/rings/padics/factory.py +++ b/src/sage/rings/padics/factory.py @@ -17,7 +17,7 @@ sage: R = QpLF(2) """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007-2013 David Roe # William Stein # @@ -26,10 +26,11 @@ # the License, or (at your option) any later version. # # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from sage.misc.superseded import experimental +from sage.categories.fields import Fields from sage.structure.factory import UniqueFactory from sage.rings.integer import Integer from sage.rings.infinity import Infinity @@ -783,35 +784,45 @@ def create_object(self, version, key): pass p, prec, type, print_mode, name, print_pos, print_sep, print_alphabet, print_max_terms, show_prec, label = key + _Fields = Fields() + if type == 'capped-rel': if print_mode == 'terse': return pAdicFieldCappedRelative(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet, - 'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name) + 'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name, + category=_Fields) else: return pAdicFieldCappedRelative(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet, - 'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name) + 'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name, + category=_Fields) elif type == 'floating-point': if print_mode == 'terse': return pAdicFieldFloatingPoint(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet, - 'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name) + 'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name, + category=_Fields) else: return pAdicFieldFloatingPoint(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet, - 'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name) + 'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name, + category=_Fields) elif type == 'relaxed': if print_mode == 'terse': return pAdicFieldRelaxed(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet, - 'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name) + 'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name, + category=_Fields) else: return pAdicFieldRelaxed(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet, - 'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name) + 'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name, + category=_Fields) elif type[:8] == 'lattice-': subtype = type[8:] if print_mode == 'terse': return pAdicFieldLattice(p, prec, subtype, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet, - 'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name, label) + 'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name, label, + category=_Fields) else: return pAdicFieldLattice(p, prec, subtype, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet, - 'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name, label) + 'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name, label, + category=_Fields) else: raise ValueError("unexpected type") diff --git a/src/sage/rings/padics/generic_nodes.py b/src/sage/rings/padics/generic_nodes.py index 5b8c7468c75..c1459a3a204 100644 --- a/src/sage/rings/padics/generic_nodes.py +++ b/src/sage/rings/padics/generic_nodes.py @@ -314,7 +314,7 @@ class pAdicLatticeGeneric(pAdicGeneric): sage: R._prec_type() 'lattice-float' """ - def __init__(self, p, prec, print_mode, names, label=None): + def __init__(self, p, prec, print_mode, names, label=None, category=None): """ Initialization. @@ -357,7 +357,7 @@ def __init__(self, p, prec, print_mode, names, label=None): else: raise ValueError("subtype must be either 'cap' or 'float'") self._element_class = self.__make_element_class__(element_class) - pAdicGeneric.__init__(self, self, p, prec, print_mode, names, None) + pAdicGeneric.__init__(self, self, p, prec, print_mode, names, None, category=category) def _prec_type(self): """ diff --git a/src/sage/rings/padics/padic_base_generic.py b/src/sage/rings/padics/padic_base_generic.py index 8001d366b23..003d34c8315 100644 --- a/src/sage/rings/padics/padic_base_generic.py +++ b/src/sage/rings/padics/padic_base_generic.py @@ -34,7 +34,7 @@ class pAdicBaseGeneric(pAdicGeneric): _implementation = 'GMP' - def __init__(self, p, prec, print_mode, names, element_class): + def __init__(self, p, prec, print_mode, names, element_class, category=None): """ Initialization. @@ -47,7 +47,7 @@ def __init__(self, p, prec, print_mode, names, element_class): self.prime_pow = PowComputer_flint(p, 1, 1, 1, self.is_field()) else: self.prime_pow = PowComputer(p, max(min(prec - 1, 30), 1), prec, self.is_field(), self._prec_type()) - pAdicGeneric.__init__(self, self, p, prec, print_mode, names, element_class) + pAdicGeneric.__init__(self, self, p, prec, print_mode, names, element_class, category=category) if self.is_field(): if self.is_capped_relative(): coerce_list = [pAdicCoercion_ZZ_CR(self), pAdicCoercion_QQ_CR(self)] diff --git a/src/sage/rings/padics/padic_base_leaves.py b/src/sage/rings/padics/padic_base_leaves.py index 64be9291c49..4eb9e584de1 100644 --- a/src/sage/rings/padics/padic_base_leaves.py +++ b/src/sage/rings/padics/padic_base_leaves.py @@ -211,7 +211,7 @@ class pAdicRingCappedRelative(pAdicRingBaseGeneric, pAdicCappedRelativeRingGener An implementation of the `p`-adic integers with capped relative precision. """ - def __init__(self, p, prec, print_mode, names): + def __init__(self, p, prec, print_mode, names, category=None): """ Initialization. @@ -247,7 +247,7 @@ def __init__(self, p, prec, print_mode, names): ....: max_runs=2^5, skip='_test_log') sage: R._test_log(max_runs=2, elements=[R.random_element() for i in range(4)]) # long time """ - pAdicRingBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicCappedRelativeElement) + pAdicRingBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicCappedRelativeElement, category=category) def _coerce_map_from_(self, R): """ @@ -309,7 +309,7 @@ class pAdicRingCappedAbsolute(pAdicRingBaseGeneric, pAdicCappedAbsoluteRingGener r""" An implementation of the `p`-adic integers with capped absolute precision. """ - def __init__(self, p, prec, print_mode, names): + def __init__(self, p, prec, print_mode, names, category=None): """ Initialization. @@ -345,7 +345,7 @@ def __init__(self, p, prec, print_mode, names): ....: max_runs=2^5, skip='_test_log') sage: R._test_log(max_runs=2, elements=[R.random_element() for i in range(4)]) """ - pAdicRingBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicCappedAbsoluteElement) + pAdicRingBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicCappedAbsoluteElement, category=category) def _coerce_map_from_(self, R): """ @@ -410,7 +410,7 @@ class pAdicRingFloatingPoint(pAdicRingBaseGeneric, pAdicFloatingPointRingGeneric An implementation of the `p`-adic integers with floating point precision. """ - def __init__(self, p, prec, print_mode, names): + def __init__(self, p, prec, print_mode, names, category=None): """ Initialization. @@ -446,7 +446,7 @@ def __init__(self, p, prec, print_mode, names): ....: max_runs=2^5, skip='_test_log') sage: R._test_log(max_runs=2, elements=[R.random_element() for i in range(4)]) """ - pAdicRingBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicFloatingPointElement) + pAdicRingBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicFloatingPointElement, category=category) def _coerce_map_from_(self, R): """ @@ -505,7 +505,7 @@ class pAdicRingFixedMod(pAdicRingBaseGeneric, pAdicFixedModRingGeneric): r""" An implementation of the `p`-adic integers using fixed modulus. """ - def __init__(self, p, prec, print_mode, names): + def __init__(self, p, prec, print_mode, names, category=None): """ Initialization. @@ -550,7 +550,7 @@ def __init__(self, p, prec, print_mode, names): sage: K(R(90)) 3*5 + 3*5^2 """ - pAdicRingBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicFixedModElement) + pAdicRingBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicFixedModElement, category=category) def _coerce_map_from_(self, R): """ @@ -618,7 +618,7 @@ class pAdicFieldCappedRelative(pAdicFieldBaseGeneric, pAdicCappedRelativeFieldGe sage: K = Qp(101) # indirect doctest """ - def __init__(self, p, prec, print_mode, names): + def __init__(self, p, prec, print_mode, names, category=None): """ Initialization. @@ -660,7 +660,7 @@ def __init__(self, p, prec, print_mode, names): ....: max_runs=2^5, skip='_test_log') sage: R._test_log(max_runs=2, elements=[R.random_element() for i in range(4)]) """ - pAdicFieldBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicCappedRelativeElement) + pAdicFieldBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicCappedRelativeElement, category=category) def _coerce_map_from_(self, R): """ @@ -749,7 +749,7 @@ class pAdicFieldFloatingPoint(pAdicFieldBaseGeneric, pAdicFloatingPointFieldGene An implementation of the `p`-adic rationals with floating point precision. """ - def __init__(self, p, prec, print_mode, names): + def __init__(self, p, prec, print_mode, names, category=None): """ Initialization. @@ -786,7 +786,7 @@ def __init__(self, p, prec, print_mode, names): ....: max_runs=2^5, skip='_test_log') sage: R._test_log(max_runs=2, elements=[R.random_element() for i in range(4)]) """ - pAdicFieldBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicFloatingPointElement) + pAdicFieldBaseGeneric.__init__(self, p, prec, print_mode, names, pAdicFloatingPointElement, category=category) def _coerce_map_from_(self, R): """ @@ -881,7 +881,7 @@ class pAdicRingLattice(pAdicLatticeGeneric, pAdicRingBaseGeneric): sage: R 2-adic Ring with lattice-cap precision (label: init) """ - def __init__(self, p, prec, subtype, print_mode, names, label=None): + def __init__(self, p, prec, subtype, print_mode, names, label=None, category=None): """ Initialization. @@ -893,11 +893,11 @@ def __init__(self, p, prec, subtype, print_mode, names, label=None): # We need to set the subtype first, so that # pAdicRingBaseGeneric.__init__ can work self._subtype = subtype - if isinstance(prec,tuple): - pAdicRingBaseGeneric.__init__(self, p, prec[1], print_mode, names, None) + if isinstance(prec, tuple): + pAdicRingBaseGeneric.__init__(self, p, prec[1], print_mode, names, None, category=category) else: - pAdicRingBaseGeneric.__init__(self, p, prec, print_mode, names, None) - pAdicLatticeGeneric.__init__(self, p, prec, print_mode, names, label) + pAdicRingBaseGeneric.__init__(self, p, prec, print_mode, names, None, category=category) + pAdicLatticeGeneric.__init__(self, p, prec, print_mode, names, label, category=category) def _coerce_map_from_(self, R): """ @@ -1012,7 +1012,7 @@ class pAdicFieldLattice(pAdicLatticeGeneric, pAdicFieldBaseGeneric): sage: R 2-adic Field with lattice-cap precision (label: init) """ - def __init__(self, p, prec, subtype, print_mode, names, label=None): + def __init__(self, p, prec, subtype, print_mode, names, label=None, category=None): """ Initialization. @@ -1024,11 +1024,11 @@ def __init__(self, p, prec, subtype, print_mode, names, label=None): # We need to set the subtype first, so that # pAdicFieldBaseGeneric.__init__ can work self._subtype = subtype - if isinstance(prec,tuple): - pAdicFieldBaseGeneric.__init__(self, p, prec[1], print_mode, names, None) + if isinstance(prec, tuple): + pAdicFieldBaseGeneric.__init__(self, p, prec[1], print_mode, names, None, category=category) else: - pAdicFieldBaseGeneric.__init__(self, p, prec, print_mode, names, None) - pAdicLatticeGeneric.__init__(self, p, prec, print_mode, names, label) + pAdicFieldBaseGeneric.__init__(self, p, prec, print_mode, names, None, category=category) + pAdicLatticeGeneric.__init__(self, p, prec, print_mode, names, label, category=category) def _coerce_map_from_(self, R): """ @@ -1137,7 +1137,7 @@ class pAdicRingRelaxed(pAdicRelaxedGeneric, pAdicRingBaseGeneric): sage: type(R) # needs sage.libs.flint """ - def __init__(self, p, prec, print_mode, names): + def __init__(self, p, prec, print_mode, names, category=None): """ Initialization. @@ -1151,7 +1151,7 @@ def __init__(self, p, prec, print_mode, names): """ from sage.rings.padics import padic_relaxed_element self._default_prec, self._halting_prec, self._secure = prec - pAdicRingBaseGeneric.__init__(self, p, self._default_prec, print_mode, names, padic_relaxed_element.pAdicRelaxedElement) + pAdicRingBaseGeneric.__init__(self, p, self._default_prec, print_mode, names, padic_relaxed_element.pAdicRelaxedElement, category=category) self._element_class_module = padic_relaxed_element self._element_class_prefix = "pAdicRelaxedElement_" @@ -1176,7 +1176,7 @@ class pAdicFieldRelaxed(pAdicRelaxedGeneric, pAdicFieldBaseGeneric): sage: type(R) # needs sage.libs.flint """ - def __init__(self, p, prec, print_mode, names): + def __init__(self, p, prec, print_mode, names, category=None): """ Initialization. @@ -1190,6 +1190,6 @@ def __init__(self, p, prec, print_mode, names): """ from sage.rings.padics import padic_relaxed_element self._default_prec, self._halting_prec, self._secure = prec - pAdicFieldBaseGeneric.__init__(self, p, self._default_prec, print_mode, names, padic_relaxed_element.pAdicRelaxedElement) + pAdicFieldBaseGeneric.__init__(self, p, self._default_prec, print_mode, names, padic_relaxed_element.pAdicRelaxedElement, category=category) self._element_class_module = padic_relaxed_element self._element_class_prefix = "pAdicRelaxedElement_" From f6d8ca8af106c36fb332f144d5929711bffb946d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 9 Jan 2025 19:01:06 +0100 Subject: [PATCH 133/175] let the categories handle "is_commutative" for rings --- src/sage/algebras/clifford_algebra.py | 2 +- .../finite_dimensional_algebra.py | 2 +- src/sage/algebras/iwahori_hecke_algebra.py | 2 +- .../algebras/steenrod/steenrod_algebra.py | 6 +++-- src/sage/categories/commutative_rings.py | 11 +++++++++ .../finite_dimensional_algebras_with_basis.py | 4 ++-- src/sage/categories/lie_algebras.py | 7 +++--- src/sage/categories/magmas.py | 2 +- src/sage/rings/quotient_ring.py | 2 +- src/sage/rings/real_double.pyx | 3 ++- src/sage/rings/ring.pyx | 23 ++----------------- 11 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/sage/algebras/clifford_algebra.py b/src/sage/algebras/clifford_algebra.py index 92ad6c34d64..091f5e0d559 100644 --- a/src/sage/algebras/clifford_algebra.py +++ b/src/sage/algebras/clifford_algebra.py @@ -844,7 +844,7 @@ def one_basis(self): """ return FrozenBitset() - def is_commutative(self): + def is_commutative(self) -> bool: """ Check if ``self`` is a commutative algebra. diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py index 3ba4bc658cb..66b3943b7d0 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py @@ -497,7 +497,7 @@ def is_associative(self): return True @cached_method - def is_commutative(self): + def is_commutative(self) -> bool: """ Return ``True`` if ``self`` is commutative. diff --git a/src/sage/algebras/iwahori_hecke_algebra.py b/src/sage/algebras/iwahori_hecke_algebra.py index 01390f1a5a4..ecc6788979b 100644 --- a/src/sage/algebras/iwahori_hecke_algebra.py +++ b/src/sage/algebras/iwahori_hecke_algebra.py @@ -766,7 +766,7 @@ def is_field(self, proof=True): """ return False - def is_commutative(self): + def is_commutative(self) -> bool: """ Return whether this Iwahori-Hecke algebra is commutative. diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index 540cb6ee92d..337e50f700c 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -2827,10 +2827,12 @@ def gen(self, i=0): tot += 1 return test - def is_commutative(self): + def is_commutative(self) -> bool: r""" Return ``True`` if ``self`` is graded commutative, as determined by the - profile function. In particular, a sub-Hopf algebra of the + profile function. + + In particular, a sub-Hopf algebra of the mod 2 Steenrod algebra is commutative if and only if there is an integer `n>0` so that its profile function `e` satisfies diff --git a/src/sage/categories/commutative_rings.py b/src/sage/categories/commutative_rings.py index 6c47efacfe0..f67990df978 100644 --- a/src/sage/categories/commutative_rings.py +++ b/src/sage/categories/commutative_rings.py @@ -46,6 +46,17 @@ class CommutativeRings(CategoryWithAxiom): sage: GroupAlgebra(CyclicPermutationGroup(3), QQ) in CommutativeRings() # not implemented, needs sage.groups sage.modules True + + Some tests for the method ``is_commutative``:: + + sage: QQ.is_commutative() + True + sage: ZpCA(7).is_commutative() # needs sage.rings.padics + True + sage: A = QuaternionAlgebra(QQ, -1, -3, names=('i','j','k')); A # needs sage.combinat sage.modules + Quaternion Algebra (-1, -3) with base ring Rational Field + sage: A.is_commutative() # needs sage.combinat sage.modules + False """ class ParentMethods: def is_commutative(self) -> bool: diff --git a/src/sage/categories/finite_dimensional_algebras_with_basis.py b/src/sage/categories/finite_dimensional_algebras_with_basis.py index 187fe3d675a..20ec2f2747a 100644 --- a/src/sage/categories/finite_dimensional_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_algebras_with_basis.py @@ -1143,7 +1143,7 @@ def is_identity_decomposition_into_orthogonal_idempotents(self, l): for f in l[:i])) @cached_method - def is_commutative(self): + def is_commutative(self) -> bool: """ Return whether ``self`` is a commutative algebra. @@ -1158,7 +1158,7 @@ def is_commutative(self): True """ B = list(self.basis()) - try: # See if 1 is a basis element, if so, remove it + try: # See if 1 is a basis element, if so, remove it B.remove(self.one()) except ValueError: pass diff --git a/src/sage/categories/lie_algebras.py b/src/sage/categories/lie_algebras.py index f134cfded5b..3a3e1a7cd5b 100644 --- a/src/sage/categories/lie_algebras.py +++ b/src/sage/categories/lie_algebras.py @@ -589,10 +589,11 @@ def is_abelian(self): zero = self.zero() return all(x._bracket_(y) == zero for x in G for y in G) - def is_commutative(self): + def is_commutative(self) -> bool: """ - Return if ``self`` is commutative. This is equivalent to ``self`` - being abelian. + Return if ``self`` is commutative. + + This is equivalent to ``self`` being abelian. EXAMPLES:: diff --git a/src/sage/categories/magmas.py b/src/sage/categories/magmas.py index ea491b2caf7..5bad4ffb775 100644 --- a/src/sage/categories/magmas.py +++ b/src/sage/categories/magmas.py @@ -398,7 +398,7 @@ def is_field(self, proof=True): class Commutative(CategoryWithAxiom): class ParentMethods: - def is_commutative(self): + def is_commutative(self) -> bool: """ Return ``True``, since commutative magmas are commutative. diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index 7e3dd8c6d53..ad36ef60eb1 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -589,7 +589,7 @@ def _latex_(self): """ return "%s/%s" % (latex.latex(self.cover_ring()), latex.latex(self.defining_ideal())) - def is_commutative(self): + def is_commutative(self) -> bool: """ Tell whether this quotient ring is commutative. diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 129603749d3..5efa0c87b65 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -132,7 +132,8 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): sage: TestSuite(R).run() """ from sage.categories.fields import Fields - Field.__init__(self, self, category=Fields().Infinite().Metric().Complete()) + Field.__init__(self, self, + category=Fields().Infinite().Metric().Complete()) self._populate_coercion_lists_(init_no_parent=True, convert_method_name='_real_double_') diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index 0891853efba..2cf3f40b99f 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -761,11 +761,9 @@ cdef class CommutativeRing(Ring): sage: Integers(389)['x,y'] Multivariate Polynomial Ring in x, y over Ring of integers modulo 389 """ - try: - if not base_ring.is_commutative(): - raise TypeError("base ring %s is no commutative ring" % base_ring) - except AttributeError: + if base_ring is not self and base_ring not in _CommutativeRings: raise TypeError("base ring %s is no commutative ring" % base_ring) + # This is a low-level class. For performance, we trust that # the category is fine, if it is provided. If it isn't, we use # the category of commutative rings. @@ -830,23 +828,6 @@ cdef class CommutativeRing(Ring): except (NotImplementedError,TypeError): return coercion_model.division_parent(self) - def is_commutative(self): - """ - Return ``True``, since this ring is commutative. - - EXAMPLES:: - - sage: QQ.is_commutative() - True - sage: ZpCA(7).is_commutative() # needs sage.rings.padics - True - sage: A = QuaternionAlgebra(QQ, -1, -3, names=('i','j','k')); A # needs sage.combinat sage.modules - Quaternion Algebra (-1, -3) with base ring Rational Field - sage: A.is_commutative() # needs sage.combinat sage.modules - False - """ - return True - def krull_dimension(self): """ Return the Krull dimension of this commutative ring. From d373f693aa69328f388e2b8b14c467e1ef832d01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 9 Jan 2025 20:11:08 +0100 Subject: [PATCH 134/175] fix doctest in doc --- src/doc/en/thematic_tutorials/coercion_and_categories.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index 2339cc57f26..9494f8c43ee 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -130,7 +130,6 @@ This base class provides a lot more methods than a general parent:: 'gen', 'gens', 'integral_closure', - 'is_commutative', 'is_field', 'krull_dimension', 'ngens', From 47a5173b27b0c57bc8ace32e21dab84c1ea0674e Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 5 Jan 2025 01:32:42 +0800 Subject: [PATCH 135/175] Meson: build groups even without gap `group.pyx` compiles fine also without gap installed. --- src/sage/groups/meson.build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sage/groups/meson.build b/src/sage/groups/meson.build index 3c5f20a1214..37ba1028d5e 100644 --- a/src/sage/groups/meson.build +++ b/src/sage/groups/meson.build @@ -38,13 +38,17 @@ extension_data = { } foreach name, pyx : extension_data + deps = [py_dep, gmp] + if name == 'libgap_wrapper' + deps += [gap] + endif py.extension_module( name, sources: pyx, subdir: 'sage/groups', install: true, include_directories: [inc_cpython], - dependencies: [py_dep, gmp, gap], + dependencies: deps, ) endforeach From 5d22e8953a97420ea0daeb47cd2dc4126c1de086 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 5 Jan 2025 01:29:01 +0800 Subject: [PATCH 136/175] Fix import duplication in `sage.rings.all` The import of the `all_sagemath_categories` module triggered exactly the same imports that were already in the `rings.all` file. We thus delete this obsolete file. --- src/sage/rings/all.py | 2 -- src/sage/rings/all__sagemath_categories.py | 7 ------- src/sage/rings/meson.build | 1 - 3 files changed, 10 deletions(-) delete mode 100644 src/sage/rings/all__sagemath_categories.py diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index e3c7167fe12..ca7946fa78f 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -12,8 +12,6 @@ # **************************************************************************** from sage.misc.lazy_import import lazy_import -from sage.rings.all__sagemath_categories import * - # Ring base classes from sage.rings.ring import (Ring, Field, CommutativeRing, IntegralDomain, PrincipalIdealDomain) diff --git a/src/sage/rings/all__sagemath_categories.py b/src/sage/rings/all__sagemath_categories.py deleted file mode 100644 index 4c0efe7b507..00000000000 --- a/src/sage/rings/all__sagemath_categories.py +++ /dev/null @@ -1,7 +0,0 @@ -# sage_setup: distribution = sagemath-categories -# Ring base classes -from sage.rings.ring import Ring -# Ideals -from sage.rings.ideal import Ideal - -ideal = Ideal diff --git a/src/sage/rings/meson.build b/src/sage/rings/meson.build index a3be9efe30b..5f4dafdf7c2 100644 --- a/src/sage/rings/meson.build +++ b/src/sage/rings/meson.build @@ -3,7 +3,6 @@ py.install_sources( 'abc.pxd', 'algebraic_closure_finite_field.py', 'all.py', - 'all__sagemath_categories.py', 'all__sagemath_objects.py', 'big_oh.py', 'cc.py', From a6a85a62ab69fbc7ae9e19297bcc786325add25b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 9 Jan 2025 21:11:17 +0100 Subject: [PATCH 137/175] fixing some ruff PLR warnings --- src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py | 1 - .../algebras/hecke_algebras/cubic_hecke_base_ring.py | 7 ++----- src/sage/categories/affine_weyl_groups.py | 2 +- src/sage/combinat/diagram_algebras.py | 2 +- src/sage/combinat/necklace.py | 7 +++---- src/sage/combinat/non_decreasing_parking_function.py | 1 - src/sage/combinat/tableau.py | 1 - src/sage/combinat/tableau_tuple.py | 1 - src/sage/combinat/words/suffix_trees.py | 4 ---- src/sage/databases/cubic_hecke_db.py | 1 - src/sage/graphs/bipartite_graph.py | 1 - src/sage/graphs/matching_covered_graph.py | 1 - src/sage/groups/cubic_braid.py | 9 --------- src/sage/interfaces/octave.py | 1 - src/sage/lfunctions/dokchitser.py | 1 - src/sage/matrix/operation_table.py | 2 -- src/sage/matroids/utilities.py | 1 - src/sage/plot/hyperbolic_arc.py | 1 - src/sage/quadratic_forms/quadratic_form__neighbors.py | 2 +- src/sage/rings/lazy_series.py | 1 - src/sage/rings/tests.py | 1 - 21 files changed, 8 insertions(+), 40 deletions(-) diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py index 9aa6fa63ff2..faa4e90baf1 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py @@ -1116,7 +1116,6 @@ def check_base_ring_embedding(base_ring_embedding): # initializing the basis extension (in case of more than 4 strands) # ---------------------------------------------------------------------- self._init_basis_extension() - return ############################################################################ # -------------------------------------------------------------------------- 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 10381f64f35..1b011c68c61 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_base_ring.py @@ -105,8 +105,6 @@ def register_ring_hom(ring_hom): except ValueError: verbose('\nthe map:\n%s\ncannot be registered as conversion\n' % ring_hom) - return - # ----------------------------------------------------------------------------- # class for the Galois Group action on the generic extension ring corresponding @@ -1005,11 +1003,10 @@ def __init__(self, names=('u', 'v', 'w', 's'), order='degrevlex', markov_trace_v # Init of data used on demand # ---------------------------------------------------------------------- self._mirror = None - return - ############################################################################ + # ######################################################################## # overloaded inherited methods - ############################################################################ + # ######################################################################## def _defining_names(self): r""" Return the generators of ``self`` as the defining names. diff --git a/src/sage/categories/affine_weyl_groups.py b/src/sage/categories/affine_weyl_groups.py index 71dfcd2350a..b904c96319e 100644 --- a/src/sage/categories/affine_weyl_groups.py +++ b/src/sage/categories/affine_weyl_groups.py @@ -130,7 +130,7 @@ def succ(pair): if (length < k and i == u1.first_descent(side='left') and u1.is_affine_grassmannian()): yield (u1, length + 1) - return + return RecursivelyEnumeratedSet_forest(((self.one(), 0),), succ, algorithm='breadth', category=FiniteEnumeratedSets(), post_process=select_length) diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index b929327a28e..841c9efe9d3 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -4795,7 +4795,7 @@ def insert_pairing(cur, intervals): # Singleton intervals are vertical lines, # so we don't need to worry about them if len(I) > 1 and I[0] < cur[0]: - cur, level[j] = level[j], cur + cur, level[j] = I, cur level.append([cur[0]]) level.append([cur[1]]) break diff --git a/src/sage/combinat/necklace.py b/src/sage/combinat/necklace.py index 3ac4bccf5e2..f3e8ccfd32d 100644 --- a/src/sage/combinat/necklace.py +++ b/src/sage/combinat/necklace.py @@ -360,12 +360,11 @@ def _fast_fixed_content(a, content, t, p, k, r, s, dll, equality=False): content[j] += 1 j = dll.next(j) a[t - 1] = k - 1 - return -################################ -# List Fixed Content Algorithm # -################################ +# ############################### +# List Fixed Content Algorithm # +# ############################### def _lfc(content, equality=False): """ EXAMPLES:: diff --git a/src/sage/combinat/non_decreasing_parking_function.py b/src/sage/combinat/non_decreasing_parking_function.py index dc6bf59e3e2..b8f9c9b825f 100644 --- a/src/sage/combinat/non_decreasing_parking_function.py +++ b/src/sage/combinat/non_decreasing_parking_function.py @@ -629,6 +629,5 @@ def iterator_rec(n): return for res in iterator_rec(self.n): yield NonDecreasingParkingFunction(res) - return Element = NonDecreasingParkingFunction diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index cb912e67409..4d8f738d001 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -8133,7 +8133,6 @@ def __iter__(self): yield self.element_class(self, tableau) - return def list(self): r""" diff --git a/src/sage/combinat/tableau_tuple.py b/src/sage/combinat/tableau_tuple.py index fd847c4ad1e..6c75106154b 100644 --- a/src/sage/combinat/tableau_tuple.py +++ b/src/sage/combinat/tableau_tuple.py @@ -4926,7 +4926,6 @@ def max_row_in_component(tab, r): yield tableau_from_list(tab) # all done! - return def last(self): r""" diff --git a/src/sage/combinat/words/suffix_trees.py b/src/sage/combinat/words/suffix_trees.py index 3249ce23235..86e2391c616 100644 --- a/src/sage/combinat/words/suffix_trees.py +++ b/src/sage/combinat/words/suffix_trees.py @@ -501,7 +501,6 @@ def show(self, *args, **kwds): sage: t.show() # needs sage.plot """ self.plot(*args, **kwds).show() - return ################################################################################ # Suffix Trees @@ -656,7 +655,6 @@ def _process_letter(self, letter): # set the active state s, k = self._canonize(s, (k, i)) self._active_state = (s, (k, i+1)) - return def _test_and_split(self, s, k_p, letter): r""" @@ -918,7 +916,6 @@ def show(self, word_labels=None, *args, **kwds): sage: t.show(word_labels=False) # needs sage.plot """ self.plot(word_labels=word_labels, *args, **kwds).show() - return ##### # Various methods @@ -1115,7 +1112,6 @@ def to_explicit_suffix_tree(self): end_state, r = self._test_and_split(s, (k, i-1), end_of_string) # remove the end of string symbol from the word self._letters.pop() - return def edge_iterator(self): r""" diff --git a/src/sage/databases/cubic_hecke_db.py b/src/sage/databases/cubic_hecke_db.py index bc5b9ba9bdd..3c75faf88ca 100644 --- a/src/sage/databases/cubic_hecke_db.py +++ b/src/sage/databases/cubic_hecke_db.py @@ -1153,7 +1153,6 @@ def update_basis_extensions(self, new_basis_extensions): """ self._data_library.update({self.section.basis_extensions: new_basis_extensions}) self.write(self.section.basis_extensions) - return # ----------------------------------------------------------------------------- diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index e21ec47e9cf..8d766556d24 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -1070,7 +1070,6 @@ def add_edge(self, u, v=None, label=None): # add the edge Graph.add_edge(self, u, v, label) - return def add_edges(self, edges, loops=True): """ diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 9544c2e58f9..32432509a3f 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2661,7 +2661,6 @@ def remove_loops(self, vertices=None): raise TypeError(f'\'{vertices.__class__.__name__}\' ' 'object is not iterable') - return @doc_index('Miscellaneous methods') def update_matching(self, matching): diff --git a/src/sage/groups/cubic_braid.py b/src/sage/groups/cubic_braid.py index 94bdf4c12e5..3ca62e9f5e9 100644 --- a/src/sage/groups/cubic_braid.py +++ b/src/sage/groups/cubic_braid.py @@ -801,7 +801,6 @@ def __init__(self, names, cbg_type=None): self._classical_embedding = None # if self._classical_group different from self._classical_base_group self._centralizing_matrix = None # for Assion groups: element in classical base group commuting with self self._centralizing_element = None # image under nat. map of the former one in the proj. classical group - return def _repr_(self): r""" @@ -913,7 +912,6 @@ def _internal_test_attached_group(self, attached_group, tester): if self.is_finite() and self.strands() <= 7: # not realistic for larger number of strands att_grp_elem_back = self(att_grp_elem) tester.assertEqual(att_grp_elem_back, elem) - return def _test_classical_group(self, **options): r""" @@ -934,7 +932,6 @@ def _test_classical_group(self, **options): classic_grp = self.as_classical_group() if self.is_finite(): self._internal_test_attached_group(classic_grp, tester) - return def _test_permutation_group(self, **options): r""" @@ -955,7 +952,6 @@ def _test_permutation_group(self, **options): tester = self._tester(**options) permgrp = self.as_permutation_group() self._internal_test_attached_group(permgrp, tester) - return def _test_matrix_group(self, **options): r""" @@ -1024,7 +1020,6 @@ def _test_reflection_group(self, **options): tester = self._tester(**options) reflgrp = self.as_reflection_group() self._internal_test_attached_group(reflgrp, tester) - return # ------------------------------------------------------------------------------- # ------------------------------------------------------------------------------- @@ -1135,7 +1130,6 @@ def set_classical_realization(self, base_group, proj_group, centralizing_matrix, self._centralizing_matrix = centralizing_matrix self._centralizing_element = centralizing_element self._classical_embedding = embedding - return # ------------------------------------------------------------------------------- # local methods to set up the classical group (specific part) @@ -1210,7 +1204,6 @@ def transvec2mat(v, bas=bas, bform=bform, fact=1): transvec_matrices = [transvec2mat(v) for v in transvections] set_classical_realization(self, base_group, proj_group, centralizing_matrix, transvec_matrices) - return # ------------------------------------------------------------------------------- # Case for unitary groups @@ -1295,7 +1288,6 @@ def transvec2mat(v, bas=bas, bform=bform, fact=a): transvec_matrices = [transvec2mat(v) for v in transvections] set_classical_realization(self, base_group, proj_group, centralizing_matrix, transvec_matrices) - return # ---------------------------------------------------------------- # local functions declaration section finishes here @@ -1346,7 +1338,6 @@ def transvec2mat(v, bas=bas, bform=bform, fact=a): self._classical_embedding = classical_group if self._classical_invariant_form is None: self._classical_invariant_form = classical_group.ambient().invariant_form() - return def _element_constructor_(self, x, **kwds): r""" diff --git a/src/sage/interfaces/octave.py b/src/sage/interfaces/octave.py index 5241989836b..da26ea800b5 100644 --- a/src/sage/interfaces/octave.py +++ b/src/sage/interfaces/octave.py @@ -351,7 +351,6 @@ def quit(self, verbose=False): if self._expect is not None: if verbose: print("Exiting spawned %s process." % self) - return def _start(self): """ diff --git a/src/sage/lfunctions/dokchitser.py b/src/sage/lfunctions/dokchitser.py index b6524bce984..9e4154a6c07 100644 --- a/src/sage/lfunctions/dokchitser.py +++ b/src/sage/lfunctions/dokchitser.py @@ -287,7 +287,6 @@ def _instantiate_gp(cls): cls.__globals_re = re.compile( '([^a-zA-Z0-9_]|^)(%s)([^a-zA-Z0-9_]|$)' % '|'.join(cls.__globals)) - return @classmethod def _teardown_gp(cls, instance=None): diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py index 89943f90b3b..58c53cfa1c7 100644 --- a/src/sage/matrix/operation_table.py +++ b/src/sage/matrix/operation_table.py @@ -777,7 +777,6 @@ def set_print_symbols(self, ascii, latex): raise ValueError('LaTeX symbol must be a string, not %s' % latex) self._ascii_symbol = ascii self._latex_symbol = latex - return None def column_keys(self): r""" @@ -931,7 +930,6 @@ def change_names(self, names): (1,2) """ self._width, self._names, self._name_dict = self._name_maker(names) - return None def matrix_of_variables(self): r""" diff --git a/src/sage/matroids/utilities.py b/src/sage/matroids/utilities.py index c9b903594c5..eb8b493c2e0 100644 --- a/src/sage/matroids/utilities.py +++ b/src/sage/matroids/utilities.py @@ -792,7 +792,6 @@ def split_vertex(G, u, v=None, edges=None): G.delete_edge(e) # This modifies the graph without needing to return anything - return def cmp_elements_key(x): diff --git a/src/sage/plot/hyperbolic_arc.py b/src/sage/plot/hyperbolic_arc.py index 904576f79b2..4aa87d4ad22 100644 --- a/src/sage/plot/hyperbolic_arc.py +++ b/src/sage/plot/hyperbolic_arc.py @@ -167,7 +167,6 @@ def _bezier_path(self, z0, z1, model, first=False): self.path.append(points[N: N + 3]) N += 3 self.last_plotted = "arc" - return class HyperbolicArc(HyperbolicArcCore): diff --git a/src/sage/quadratic_forms/quadratic_form__neighbors.py b/src/sage/quadratic_forms/quadratic_form__neighbors.py index d4d579409d3..b63fbda3b60 100644 --- a/src/sage/quadratic_forms/quadratic_form__neighbors.py +++ b/src/sage/quadratic_forms/quadratic_form__neighbors.py @@ -327,7 +327,7 @@ def neighbor_iteration(seeds, p, mass=None, max_classes=None, def p_divisible_vectors(Q, max_neighbors): yield from iter(v.lift() for v in Q.orbits_lines_mod_p(p) if v != 0 and Q(v.lift()).valuation(p) > 0) - return + elif algorithm == 'exhaustion': def p_divisible_vectors(Q, max_neighbors): k = 0 diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index b670cce965c..6a4fea857a4 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -4948,7 +4948,6 @@ def compute_coefficients(self, i): """ from sage.misc.superseded import deprecation deprecation(32367, "the method compute_coefficients obsolete and has no effect.") - return def _im_gens_(self, codomain, im_gens, base_map=None): """ diff --git a/src/sage/rings/tests.py b/src/sage/rings/tests.py index 3796ef7b276..09e0d585078 100644 --- a/src/sage/rings/tests.py +++ b/src/sage/rings/tests.py @@ -501,4 +501,3 @@ def test_karatsuba_multiplication(base_ring, maxdeg1, maxdeg2, msg += "and\n" msg += f"{sage_input(g)}" raise ValueError(msg) - return From b1687553c2bfa27b36e6279025c69a6523e01a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 9 Jan 2025 21:32:34 +0100 Subject: [PATCH 138/175] simplify many range(0,n) to range(n) --- src/sage/calculus/desolvers.py | 2 +- src/sage/coding/grs_code.py | 7 +++---- src/sage/coding/guruswami_sudan/gs_decoder.py | 8 ++++---- src/sage/coding/guruswami_sudan/interpolation.py | 7 ++++--- src/sage/crypto/mq/sr.py | 16 ++++++++-------- src/sage/data_structures/stream.py | 8 ++++---- .../dynamics/arithmetic_dynamics/affine_ds.py | 2 +- .../arithmetic_dynamics/endPN_minimal_model.py | 5 +++-- .../dynamics/arithmetic_dynamics/wehlerK3.py | 7 ++++--- .../geometry/hyperplane_arrangement/library.py | 3 ++- src/sage/geometry/polyhedral_complex.py | 2 +- .../parametrized_surface3d.py | 4 ++-- src/sage/geometry/triangulation/base.pyx | 4 ++-- src/sage/interfaces/phc.py | 2 +- src/sage/interfaces/r.py | 2 +- src/sage/knots/knot.py | 2 +- src/sage/libs/mpmath/ext_impl.pyx | 4 ++-- src/sage/schemes/elliptic_curves/ell_point.py | 4 ++-- src/sage/structure/global_options.py | 8 ++++---- src/sage/tensor/modules/free_module_tensor.py | 4 ++-- src/sage/topology/delta_complex.py | 8 ++++---- src/sage/topology/simplicial_complex.py | 2 +- src/sage/topology/simplicial_complex_examples.py | 10 +++------- 23 files changed, 60 insertions(+), 61 deletions(-) diff --git a/src/sage/calculus/desolvers.py b/src/sage/calculus/desolvers.py index d17f5a14e90..6a8d8fbe2bb 100644 --- a/src/sage/calculus/desolvers.py +++ b/src/sage/calculus/desolvers.py @@ -741,7 +741,7 @@ def desolve_laplace(de, dvar, ics=None, ivar=None): # maxima("de:"+de._repr_()+"=0;") # if ics is not None: # d = len(ics) - # for i in range(0,d-1): + # for i in range(d-1): # ic = "atvalue(diff("+vars[1]+"("+vars[0]+"),"+str(vars[0])+","+str(i)+"),"+str(vars[0])+"="+str(ics[0])+","+str(ics[1+i])+")" # maxima(ic) # diff --git a/src/sage/coding/grs_code.py b/src/sage/coding/grs_code.py index a37a5b15a7b..aead68b0bb3 100644 --- a/src/sage/coding/grs_code.py +++ b/src/sage/coding/grs_code.py @@ -1525,7 +1525,7 @@ def _polynomial_vanishing_at_alphas(self, PolRing): """ G = PolRing.one() x = PolRing.gen() - for i in range(0, self.code().length()): + for i in range(self.code().length()): G = G*(x-self.code().evaluation_points()[i]) return G @@ -1612,11 +1612,10 @@ def _decode_to_code_and_message(self, r): if n == C.dimension() or r in C: return r, self.connected_encoder().unencode_nocheck(r) - points = [(alphas[i], r[i]/col_mults[i]) for i in - range(0, n)] + points = [(alphas[i], r[i]/col_mults[i]) for i in range(n)] R = PolRing.lagrange_polynomial(points) - (Q1, Q0) = self._partial_xgcd(G, R, PolRing) + Q1, Q0 = self._partial_xgcd(G, R, PolRing) h, rem = Q1.quo_rem(Q0) if not rem.is_zero(): diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index e909c3a0bf3..f3e194491d2 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -849,15 +849,15 @@ def decode_to_code(self, r): s = self.multiplicity() l = self.list_size() tau = self.decoding_radius() - ## SETUP INTERPOLATION PROBLEM + # SETUP INTERPOLATION PROBLEM wy = k-1 - points = [(alphas[i], r[i]/colmults[i]) for i in range(0,len(alphas))] - ## SOLVE INTERPOLATION + points = [(alphas[i], r[i]/colmults[i]) for i in range(len(alphas))] + # SOLVE INTERPOLATION try: Q = self.interpolation_algorithm()(points, tau, (s,l), wy) except TypeError: raise ValueError("The provided interpolation algorithm has a wrong signature. See the documentation of `codes.decoders.GRSGuruswamiSudanDecoder.interpolation_algorithm()` for details") - ## EXAMINE THE FACTORS AND CONVERT TO CODEWORDS + # EXAMINE THE FACTORS AND CONVERT TO CODEWORDS try: polynomials = self.rootfinding_algorithm()(Q, maxd=wy) except TypeError: diff --git a/src/sage/coding/guruswami_sudan/interpolation.py b/src/sage/coding/guruswami_sudan/interpolation.py index 3adc0ef1130..bfeb0efd2a9 100644 --- a/src/sage/coding/guruswami_sudan/interpolation.py +++ b/src/sage/coding/guruswami_sudan/interpolation.py @@ -342,14 +342,15 @@ def lee_osullivan_module(points, parameters, wy): PF = F['x'] x = PF.gens()[0] R = PF.lagrange_polynomial(points) - G = prod(x - points[i][0] for i in range(0, len(points))) + G = prod(x - points[i][0] for i in range(len(points))) PFy = PF['y'] y = PFy.gens()[0] - ybasis = [(y-R)**i * G**(s-i) for i in range(0, s+1)] \ - + [y**(i-s) * (y-R)**s for i in range(s+1, l+1)] + ybasis = [(y-R)**i * G**(s-i) for i in range(s + 1)] \ + + [y**(i-s) * (y-R)**s for i in range(s + 1, l + 1)] def pad(lst): return lst + [0]*(l+1-len(lst)) + modbasis = [pad(yb.coefficients(sparse=False)) for yb in ybasis] return matrix(PF, modbasis) diff --git a/src/sage/crypto/mq/sr.py b/src/sage/crypto/mq/sr.py index 610a97b05fb..c60202c6f23 100644 --- a/src/sage/crypto/mq/sr.py +++ b/src/sage/crypto/mq/sr.py @@ -2248,8 +2248,8 @@ def shift_rows_matrix(self): bs = r*c*e shift_rows = matrix(k, bs, bs) I = MatrixSpace(k, e, e)(1) - for x in range(0, c): - for y in range(0, r): + for x in range(c): + for y in range(r): _r = ((x*r)+y) * e _c = (((x*r)+((r+1)*y)) * e) % bs self._insert_matrix_into_matrix(shift_rows, I, _r, _c) @@ -2290,14 +2290,14 @@ def lin_matrix(self, length=None): if e == 4: l = [k.from_integer(x) for x in (5, 1, 12, 5)] for k in range( 0, length ): - for i in range(0, 4): - for j in range(0, 4): + for i in range(4): + for j in range(4): lin[k*4+j, k*4+i] = l[(i-j) % 4] ** (2**j) elif e == 8: l = [k.from_integer(x) for x in (5, 9, 249, 37, 244, 1, 181, 143)] for k in range( 0, length ): - for i in range(0, 8): - for j in range(0, 8): + for i in range(8): + for j in range(8): lin[k*8+j, k*8+i] = l[(i-j) % 8] ** (2**j) return lin @@ -2651,8 +2651,8 @@ def shift_rows_matrix(self): k = self.k bs = r*c shift_rows = matrix(k, r*c, r*c) - for x in range(0, c): - for y in range(0, r): + for x in range(c): + for y in range(r): _r = ((x*r)+y) _c = ((x*r)+((r+1)*y)) % bs shift_rows[_r, _c] = 1 diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index ddca8fb26b2..eade622907f 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -3247,7 +3247,7 @@ def __init__(self, series, shift, minimal_valuation): true order at initialization:: sage: f = Stream_function(fun, True, 0) - sage: [f[i] for i in range(0, 10)] + sage: [f[i] for i in range(10)] [0, 1, 1, 0, 1, 0, 0, 0, 1, 0] sage: f._cache {1: 1, 2: 1, 3: 0, 4: 1, 5: 0, 6: 0, 7: 0, 8: 1, 9: 0} @@ -3257,7 +3257,7 @@ def __init__(self, series, shift, minimal_valuation): sage: s._approximate_order 3 sage: f = Stream_function(fun, False, 0) - sage: [f[i] for i in range(0, 10)] + sage: [f[i] for i in range(10)] [0, 1, 1, 0, 1, 0, 0, 0, 1, 0] sage: f._cache [1, 1, 0, 1, 0, 0, 0, 1, 0] @@ -3432,7 +3432,7 @@ def is_nonzero(self): sage: from sage.data_structures.stream import Stream_function, Stream_truncated sage: def fun(n): return 1 if ZZ(n).is_power_of(2) else 0 sage: f = Stream_function(fun, False, 0) - sage: [f[i] for i in range(0, 4)] + sage: [f[i] for i in range(4)] [0, 1, 1, 0] sage: f._cache [1, 1, 0] @@ -3445,7 +3445,7 @@ def is_nonzero(self): True sage: f = Stream_function(fun, True, 0) - sage: [f[i] for i in range(0, 4)] + sage: [f[i] for i in range(4)] [0, 1, 1, 0] sage: f._cache {1: 1, 2: 1, 3: 0} diff --git a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py index ecf61822ba9..c9d9a0e5403 100644 --- a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py @@ -800,7 +800,7 @@ def multiplier(self, P, n, check=True): l = identity_matrix(FractionField(self.codomain().base_ring()), N, N) Q = P J = self.jacobian() - for i in range(0, n): + for i in range(n): R = self(Q) l = J(tuple(Q)) * l # chain rule matrix multiplication Q = R diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py b/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py index 902f83b55ae..ccd2041d1ca 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py @@ -66,12 +66,13 @@ def bCheck(c, v, p, b): sage: bCheck(11664*b^2 + 70227*b + 76059, 15/2, 3, b) -1 """ - val = (v+1).floor() + val = (v + 1).floor() deg = c.degree() coeffs = c.coefficients(sparse=False) lcoeff = coeffs[deg] coeffs.remove(lcoeff) - check1 = [(coeffs[i].valuation(p) - lcoeff.valuation(p))/(deg - i) for i in range(0,len(coeffs)) if coeffs[i] != 0] + check1 = [(coeffs[i].valuation(p) - lcoeff.valuation(p))/(deg - i) + for i in range(len(coeffs)) if coeffs[i] != 0] check2 = (val - lcoeff.valuation(p))/deg check1.append(check2) bval = min(check1) diff --git a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py index 766dff990e0..0a1a5ba1526 100644 --- a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py +++ b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py @@ -1200,7 +1200,7 @@ def sigmaX(self, P, **kwds): e = min(maxexp) #Fix L and Q - for i in range(0,2): + for i in range(2): while T[i].subs({w1:t1}) == 0: T[i] = T[i]/t T[i] = T[i].subs({w1:t1}) @@ -1435,7 +1435,8 @@ def sigmaY(self, P, **kwds): -phi(self.Hpoly(0, 1, 2))] maxexp = [] - #Find highest exponent that we can divide out by to get a nonzero answer + # Find highest exponent that we can divide out by to get a + # nonzero answer for i in range(2, len(T)): e = 0 while (T[i]/t**e).subs({w1:t1}) == 0: @@ -1444,7 +1445,7 @@ def sigmaY(self, P, **kwds): e = min(maxexp) - for i in range(0, 2): + for i in range(2): while T[i].subs({w1:t1}) == 0: T[i] = T[i]/t T[i] = T[i].subs({w1:t1}) diff --git a/src/sage/geometry/hyperplane_arrangement/library.py b/src/sage/geometry/hyperplane_arrangement/library.py index 9e2ca3336f6..2c731eba212 100644 --- a/src/sage/geometry/hyperplane_arrangement/library.py +++ b/src/sage/geometry/hyperplane_arrangement/library.py @@ -502,7 +502,8 @@ def Ish(self, n, K=QQ, names=None): A = H(*hyperplanes) x = polygen(QQ, 'x') charpoly = x * sum([(-1)**k * stirling_number2(n, n-k) * - prod([(x - 1 - j) for j in range(k, n-1)]) for k in range(0, n)]) + prod([(x - 1 - j) for j in range(k, n-1)]) + for k in range(n)]) A.characteristic_polynomial.set_cache(charpoly) return A diff --git a/src/sage/geometry/polyhedral_complex.py b/src/sage/geometry/polyhedral_complex.py index 0dc45748578..fa4aab394d4 100644 --- a/src/sage/geometry/polyhedral_complex.py +++ b/src/sage/geometry/polyhedral_complex.py @@ -412,7 +412,7 @@ def cell_iterator(self, increasing=True): 11 """ cells = self.cells() - dim_index = range(0, self.dimension() + 1) + dim_index = range(self.dimension() + 1) if not increasing: dim_index = reversed(dim_index) for d in dim_index: diff --git a/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py b/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py index 17fb5028df1..308a151fad3 100644 --- a/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py +++ b/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py @@ -276,11 +276,11 @@ class ParametrizedSurface3D(SageObject): sage: cc_array = [(ccc - K_min)/(K_max - K_min) for ccc in K_array] sage: points_array = [ellipsoid_equation(u_array[counter][0], ....: u_array[counter][1]) - ....: for counter in range(0,len(u_array))] + ....: for counter in range(len(u_array))] sage: curvature_ellipsoid_plot = sum(point([xx # needs sage.plot ....: for xx in points_array[counter]], ....: color=hue(cc_array[counter]/2)) - ....: for counter in range(0,len(u_array))) + ....: for counter in range(len(u_array))) sage: curvature_ellipsoid_plot.show(aspect_ratio=1) # needs sage.plot We can find the principal curvatures and principal directions of the diff --git a/src/sage/geometry/triangulation/base.pyx b/src/sage/geometry/triangulation/base.pyx index 55144d1623c..3bbbaddef6b 100644 --- a/src/sage/geometry/triangulation/base.pyx +++ b/src/sage/geometry/triangulation/base.pyx @@ -595,13 +595,13 @@ cdef class PointConfiguration_base(Parent): EXAMPLES:: sage: p = PointConfiguration([[1,0], [2,3], [3,2]]) - sage: [ p[i] for i in range(0,p.n_points()) ] + sage: [p[i] for i in range(p.n_points())] [P(1, 0), P(2, 3), P(3, 2)] sage: list(p) [P(1, 0), P(2, 3), P(3, 2)] sage: list(p.points()) [P(1, 0), P(2, 3), P(3, 2)] - sage: [ p.point(i) for i in range(0,p.n_points()) ] + sage: [p.point(i) for i in range(p.n_points())] [P(1, 0), P(2, 3), P(3, 2)] """ return self._pts[i] diff --git a/src/sage/interfaces/phc.py b/src/sage/interfaces/phc.py index 3aa5964352b..d687d456eaf 100644 --- a/src/sage/interfaces/phc.py +++ b/src/sage/interfaces/phc.py @@ -567,7 +567,7 @@ def _parse_path_file(self, input_filename, verbose=False): t_val = CC(m.group(2), m.group(3)) temp_dict = {} temp_dict["t"] = t_val - for i in range(0, count): + for i in range(count): a_line = fh.readline() m = sols_regex.match(a_line) if m: diff --git a/src/sage/interfaces/r.py b/src/sage/interfaces/r.py index b44fe1381ff..6bf0ddc6ab7 100644 --- a/src/sage/interfaces/r.py +++ b/src/sage/interfaces/r.py @@ -894,7 +894,7 @@ def available_packages(self): # The following was more structural, but breaks on my machine. (stein) # p = p._sage_() # s = p['_Dim'][0] - # l = [[p['DATA'][i],p['DATA'][s+1+i]] for i in range(0,s)] + # l = [[p['DATA'][i],p['DATA'][s+1+i]] for i in range(s)] # return l def _object_class(self): diff --git a/src/sage/knots/knot.py b/src/sage/knots/knot.py index 607c73085aa..d8c688b3c32 100644 --- a/src/sage/knots/knot.py +++ b/src/sage/knots/knot.py @@ -292,7 +292,7 @@ def dt_code(self): crossing = i break if not string_found: - for i in range(0, crossing): + for i in range(crossing): if abs(b[i]) == string or abs(b[i]) == string - 1: string_found = True crossing = i diff --git a/src/sage/libs/mpmath/ext_impl.pyx b/src/sage/libs/mpmath/ext_impl.pyx index fdbbfa80a3a..8996d6296cf 100644 --- a/src/sage/libs/mpmath/ext_impl.pyx +++ b/src/sage/libs/mpmath/ext_impl.pyx @@ -2116,7 +2116,7 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z, raise ZeroDivisionError # Multiply real factors - for k in range(0, cancellable_real): + for k in range(cancellable_real): sig_check() mpz_mul(PRE, PRE, AREAL[k]) mpz_fdiv_q(PRE, PRE, BREAL[k]) @@ -2129,7 +2129,7 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z, mpz_mul_2exp(PRE, PRE, wp) mpz_fdiv_q(PRE, PRE, BREAL[k]) if have_complex: - for k in range(0, cancellable_real): + for k in range(cancellable_real): sig_check() mpz_mul(PIM, PIM, AREAL[k]) mpz_fdiv_q(PIM, PIM, BREAL[k]) diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index d05196240a1..395735d469a 100644 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -4604,8 +4604,8 @@ def padic_elliptic_logarithm(self, Q, p): if Q.is_zero(): k = 0 else: - for k in range(0,p): - Eqp = EllipticCurve(Qp(p, 2), [ ZZ(t) + k * p for t in E.a_invariants() ]) + for k in range(p): + Eqp = EllipticCurve(Qp(p, 2), [ZZ(t) + k * p for t in E.a_invariants()]) P_Qps = Eqp.lift_x(ZZ(self.x()), all=True) for P_Qp in P_Qps: diff --git a/src/sage/structure/global_options.py b/src/sage/structure/global_options.py index cbf08174532..d27bda16658 100644 --- a/src/sage/structure/global_options.py +++ b/src/sage/structure/global_options.py @@ -130,7 +130,7 @@ ....: cake='waist begins again', ....: cream='fluffy, white stuff')) ....: tip = dict(default=10, description='Reward for good service', - ....: checker = lambda tip: tip in range(0,20)) + ....: checker = lambda tip: tip in range(20)) sage: Menu.options Current options for menu - dessert: espresso @@ -409,7 +409,7 @@ class options(GlobalOptions): ....: cake='waist begins again', ....: cream='fluffy, white stuff')), ....: tip=dict(default=10, description='Reward for good service', - ....: checker=lambda tip: tip in range(0,20)) + ....: checker=lambda tip: tip in range(20)) ....: ) sage: Menu.options Current options for menu @@ -908,7 +908,7 @@ class GlobalOptions(metaclass=GlobalOptionsMeta): ....: cake='waist begins again', ....: cream='fluffy white stuff')) ....: tip = dict(default=10, description='Reward for good service', - ....: checker=lambda tip: tip in range(0,20)) + ....: checker=lambda tip: tip in range(20)) sage: Menu.options Current options for menu - dessert: espresso @@ -1013,7 +1013,7 @@ def __init__(self, NAME=None, module='', option_class='', doc='', end_doc='', ** ....: cake='waist begins again', ....: cream='fluffy white stuff')) ....: tip = dict(default=10, description='Reward for good service', - ....: checker=lambda tip: tip in range(0,20)) + ....: checker=lambda tip: tip in range(20)) sage: menu._name # Default name is class name 'menu' sage: class specials(GlobalOptions): diff --git a/src/sage/tensor/modules/free_module_tensor.py b/src/sage/tensor/modules/free_module_tensor.py index 94974e6059b..19c42c53081 100644 --- a/src/sage/tensor/modules/free_module_tensor.py +++ b/src/sage/tensor/modules/free_module_tensor.py @@ -2801,12 +2801,12 @@ def contract(self, *args): # nb_cov_s = 0 # Number of covariant indices of self not involved in the # contraction - for pos in range(k1,k1+l1): + for pos in range(k1, k1 + l1): if pos not in pos1: nb_cov_s += 1 nb_con_o = 0 # Number of contravariant indices of other not involved # in the contraction - for pos in range(0,k2): + for pos in range(k2): if pos not in pos2: nb_con_o += 1 if nb_cov_s != 0 and nb_con_o != 0: diff --git a/src/sage/topology/delta_complex.py b/src/sage/topology/delta_complex.py index b9ce4d5fb62..338a6008931 100644 --- a/src/sage/topology/delta_complex.py +++ b/src/sage/topology/delta_complex.py @@ -304,7 +304,7 @@ def store_bdry(simplex, faces): # else a dictionary indexed by simplices dimension = max([f.dimension() for f in data]) old_data_by_dim = {} - for dim in range(0, dimension+1): + for dim in range(dimension + 1): old_data_by_dim[dim] = [] new_data[dim] = [] for x in data: @@ -466,7 +466,7 @@ def subcomplex(self, data): new_dict[d+1].append(tuple([translate[n] for n in f])) new_dict[d].append(cells[d][x]) cells_to_add.update(cells[d][x]) - new_cells = [new_dict[n] for n in range(0, max_dim+1)] + new_cells = [new_dict[n] for n in range(max_dim + 1)] sub = DeltaComplex(new_cells) sub._is_subcomplex_of = {self: new_data} return sub @@ -564,7 +564,7 @@ def cells(self, subcomplex=None): raise ValueError("this is not a subcomplex of self") else: subcomplex_cells = subcomplex._is_subcomplex_of[self] - for d in range(0, max(subcomplex_cells.keys())+1): + for d in range(max(subcomplex_cells.keys()) + 1): L = list(cells[d]) for c in subcomplex_cells[d]: L[c] = None @@ -1303,7 +1303,7 @@ def elementary_subdivision(self, idx=-1): # added_cells: dict indexed by (n-1)-cells, with value the # corresponding new n-cell. added_cells = {(): len(cells_dict[0])-1} - for n in range(0, dim): + for n in range(dim): new_cells = {} # for each n-cell in the standard simplex, add an # (n+1)-cell to the subdivided complex. diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index 54166cf4f1f..ac0af5dcd7b 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -1477,7 +1477,7 @@ def h_vector(self): d = self.dimension() f = self.f_vector() # indexed starting at 0, since it's a Python list h = [] - for j in range(0, d + 2): + for j in range(d + 2): s = 0 for i in range(-1, j): s += (-1)**(j-i-1) * binomial(d-i, j-i-1) * f[i+1] diff --git a/src/sage/topology/simplicial_complex_examples.py b/src/sage/topology/simplicial_complex_examples.py index 97958848bb0..99b8202777b 100644 --- a/src/sage/topology/simplicial_complex_examples.py +++ b/src/sage/topology/simplicial_complex_examples.py @@ -839,17 +839,13 @@ def RealProjectiveSpace(n): name='Minimal triangulation of RP^4') if n >= 5: # Use the construction given by Datta in Example 3.21. - V = set(range(0, n+2)) + V = set(range(n + 2)) S = Sphere(n).barycentric_subdivision() X = S.facets() facets = set() for f in X: - new = [] - for v in f: - if 0 in v: - new.append(tuple(V.difference(v))) - else: - new.append(v) + new = [tuple(V.difference(v)) if 0 in V else v + for v in f] facets.add(tuple(new)) return UniqueSimplicialComplex(list(facets), name='Triangulation of RP^{}'.format(n)) From 257e3d9193cdd0aed1f9b73d7f0f0fc0457afa20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 10 Jan 2025 08:26:27 +0100 Subject: [PATCH 139/175] undo change --- src/sage/topology/simplicial_complex_examples.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/sage/topology/simplicial_complex_examples.py b/src/sage/topology/simplicial_complex_examples.py index 99b8202777b..97958848bb0 100644 --- a/src/sage/topology/simplicial_complex_examples.py +++ b/src/sage/topology/simplicial_complex_examples.py @@ -839,13 +839,17 @@ def RealProjectiveSpace(n): name='Minimal triangulation of RP^4') if n >= 5: # Use the construction given by Datta in Example 3.21. - V = set(range(n + 2)) + V = set(range(0, n+2)) S = Sphere(n).barycentric_subdivision() X = S.facets() facets = set() for f in X: - new = [tuple(V.difference(v)) if 0 in V else v - for v in f] + new = [] + for v in f: + if 0 in v: + new.append(tuple(V.difference(v))) + else: + new.append(v) facets.add(tuple(new)) return UniqueSimplicialComplex(list(facets), name='Triangulation of RP^{}'.format(n)) From 7cf119c4954aa54074af9706e429dbda4252ba90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 10 Jan 2025 08:28:49 +0100 Subject: [PATCH 140/175] fix lint warnings --- src/sage/combinat/tableau.py | 1 - src/sage/graphs/matching_covered_graph.py | 1 - 2 files changed, 2 deletions(-) diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 4d8f738d001..6c2c4f6a2ab 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -8133,7 +8133,6 @@ def __iter__(self): yield self.element_class(self, tableau) - def list(self): r""" Return a list of the standard Young tableaux of the specified shape. diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 32432509a3f..370fc1f9cad 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2661,7 +2661,6 @@ def remove_loops(self, vertices=None): raise TypeError(f'\'{vertices.__class__.__name__}\' ' 'object is not iterable') - @doc_index('Miscellaneous methods') def update_matching(self, matching): r""" From 2b8f836d78cc53d50994f3d2af11eb447c5fe08d Mon Sep 17 00:00:00 2001 From: dcoudert Date: Fri, 10 Jan 2025 10:38:11 +0100 Subject: [PATCH 141/175] #39151: add missing doctests --- src/sage/graphs/generic_graph.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 7f0baac8a10..e3886c40f24 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -19021,6 +19021,10 @@ def breadth_first_search(self, start, ignore_direction=False, Traceback (most recent call last): ... ValueError: the start vertex is in the set of forbidden vertices + sage: list(G.breadth_first_search(0, forbidden_vertices=[0], distance=2)) + Traceback (most recent call last): + ... + ValueError: the start vertex is in the set of forbidden vertices sage: list(G.breadth_first_search([0, 1], forbidden_vertices=[1])) Traceback (most recent call last): ... @@ -19204,6 +19208,10 @@ def depth_first_search(self, start, ignore_direction=False, Traceback (most recent call last): ... ValueError: the start vertex is in the set of forbidden vertices + sage: list(G.depth_first_search(0, forbidden_vertices=[0], edges=True)) + Traceback (most recent call last): + ... + ValueError: the start vertex is in the set of forbidden vertices sage: list(G.depth_first_search([0, 1], forbidden_vertices=[1])) Traceback (most recent call last): ... From 13c7a89d6eef9d04ce54fffc8d2c3f5863765a51 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Fri, 10 Jan 2025 15:36:34 +0100 Subject: [PATCH 142/175] #39228: remove old method --- src/sage/graphs/base/c_graph.pyx | 199 ------------------------------- 1 file changed, 199 deletions(-) diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index f3db3dce905..46464a9835f 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -3869,205 +3869,6 @@ cdef class CGraphBackend(GenericGraphBackend): return shortest_path - def bidirectional_dijkstra_old(self, x, y, weight_function=None, - distance_flag=False): - r""" - Return the shortest path or distance from ``x`` to ``y`` using a - bidirectional version of Dijkstra's algorithm. - - INPUT: - - - ``x`` -- the starting vertex in the shortest path from ``x`` to ``y`` - - - ``y`` -- the end vertex in the shortest path from ``x`` to ``y`` - - - ``weight_function`` -- function (default: ``None``); a function that - inputs an edge ``(u, v, l)`` and outputs its weight. If ``None``, we - use the edge label ``l`` as a weight, if ``l`` is not ``None``, else - ``1`` as a weight. - - - ``distance_flag`` -- boolean (default: ``False``); when set to - ``True``, the shortest path distance from ``x`` to ``y`` is returned - instead of the path. - - OUTPUT: - - - A list of vertices in the shortest path from ``x`` to ``y`` or - distance from ``x`` to ``y`` is returned depending upon the value of - parameter ``distance_flag`` - - EXAMPLES:: - - sage: G = Graph(graphs.PetersenGraph()) - sage: for (u, v) in G.edges(sort=True, labels=None): - ....: G.set_edge_label(u, v, 1) - sage: G._backend.bidirectional_dijkstra_old(0, 1) - [0, 1] - sage: G._backend.bidirectional_dijkstra_old(0, 1, distance_flag=True) - 1 - sage: G = DiGraph([(1, 2, {'weight':1}), (1, 3, {'weight':5}), (2, 3, {'weight':1})]) - sage: G._backend.bidirectional_dijkstra_old(1, 3, weight_function=lambda e:e[2]['weight']) - [1, 2, 3] - sage: G._backend.bidirectional_dijkstra_old(1, 3, weight_function=lambda e:e[2]['weight'], distance_flag=True) - 2 - - TESTS: - - Bugfix from :issue:`7673` :: - - sage: G = Graph([(0, 1, 9), (0, 2, 8), (1, 2, 7)]) - sage: G._backend.bidirectional_dijkstra_old(0, 1, distance_flag=True) - 9 - - Bugfix from :issue:`28221` :: - - sage: G = Graph([(0, 1, 9.2), (0, 2, 4.5), (1, 2, 4.6)]) - sage: G._backend.bidirectional_dijkstra_old(0, 1, distance_flag=True) - 9.1 - - Bugfix from :issue:`27464` :: - - sage: G = DiGraph({0: [1, 2], 1: [4], 2: [3, 4], 4: [5], 5: [6]}, multiedges=True) - sage: for u, v in list(G.edges(labels=None, sort=False)): - ....: G.set_edge_label(u, v, 1) - sage: G._backend.bidirectional_dijkstra_old(0, 5, distance_flag=true) - 3 - """ - if x == y: - if distance_flag: - return 0 - else: - return [x] - - # As for shortest_path, the roles of x and y are symmetric, hence we - # define dictionaries like pred_current and pred_other, which - # represent alternatively pred_x or pred_y according to the side - # studied. - cdef int x_int = self.get_vertex(x) - cdef int y_int = self.get_vertex(y) - cdef int v = 0 - cdef int w = 0 - cdef int pred - cdef int side - cdef double distance - - # Each vertex knows its predecessors in the search, for each side - cdef dict pred_x = {} - cdef dict pred_y = {} - cdef dict pred_current - cdef dict pred_other - - # Stores the distances from x and y - cdef dict dist_x = {} - cdef dict dist_y = {} - cdef dict dist_current - cdef dict dist_other - - # Lists of vertices who are left to be explored. They are represented - # as pairs of pair and pair: ((distance, side), (predecessor, name)). - # 1 indicates x's side, -1 indicates y's, the distance being - # defined relatively. - cdef priority_queue[pair[pair[double, int], pair[int, int]]] pq - pq.push(((0, 1), (x_int, x_int))) - pq.push(((0, -1), (y_int, y_int))) - cdef list neighbors - - cdef list shortest_path = [] - - # Meeting_vertex is a vertex discovered through x and through y - # which defines the shortest path found - # (of length shortest_path_length). - cdef int meeting_vertex = -1 - - if weight_function is None: - def weight_function(e): - return 1 if e[2] is None else e[2] - - # As long as the current side (x or y) is not totally explored ... - while not pq.empty(): - (distance, side), (pred, v) = pq.top() - # priority_queue by default is max heap - # negative value of distance is stored in priority_queue to get - # minimum distance - distance = -distance - pq.pop() - if meeting_vertex != -1 and distance > shortest_path_length: - break - - if side == 1: - dist_current, dist_other = dist_x, dist_y - pred_current, pred_other = pred_x, pred_y - else: - dist_current, dist_other = dist_y, dist_x - pred_current, pred_other = pred_y, pred_x - - if v not in dist_current: - if not distance_flag: - pred_current[v] = pred - dist_current[v] = distance - - if v in dist_other: - f_tmp = distance + dist_other[v] - if meeting_vertex == -1 or f_tmp < shortest_path_length: - meeting_vertex = v - shortest_path_length = f_tmp - - if side == 1: - neighbors = self.cg().out_neighbors(v) - else: - neighbors = self.cg().in_neighbors(v) - for w in neighbors: - # If the neighbor is new, adds its non-found neighbors to - # the queue. - if w not in dist_current: - v_obj = self.vertex_label(v) - w_obj = self.vertex_label(w) - if side == -1: - v_obj, w_obj = w_obj, v_obj - if self._multiple_edges: - edge_label = min(weight_function((v_obj, w_obj, l)) for l in self.get_edge_label(v_obj, w_obj)) - else: - edge_label = weight_function((v_obj, w_obj, self.get_edge_label(v_obj, w_obj))) - if edge_label < 0: - raise ValueError("the graph contains an edge with negative weight") - # priority_queue is by default max_heap - # negative value of distance + edge_label is stored in - # priority_queue to get minimum distance - pq.push(((-(distance + edge_label), side), (v, w))) - - # No meeting point has been found - if meeting_vertex == -1: - if distance_flag: - from sage.rings.infinity import Infinity - return Infinity - return [] - else: - # build the shortest path and returns it. - if distance_flag: - if shortest_path_length in ZZ: - return int(shortest_path_length) - else: - return shortest_path_length - w = meeting_vertex - - while w != x_int: - shortest_path.append(self.vertex_label(w)) - w = pred_x[w] - - shortest_path.append(x) - shortest_path.reverse() - - if meeting_vertex == y_int: - return shortest_path - - w = pred_y[meeting_vertex] - while w != y_int: - shortest_path.append(self.vertex_label(w)) - w = pred_y[w] - shortest_path.append(y) - - return shortest_path - def bidirectional_dijkstra(self, x, y, weight_function=None, distance_flag=False): r""" From 8f541f4b1fddf4b3287bb6c15aa72cd19f8f0295 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Fri, 10 Jan 2025 19:00:54 +0100 Subject: [PATCH 143/175] use memory allocator in sage/coding/binary_code.pyx --- src/sage/coding/binary_code.pxd | 6 + src/sage/coding/binary_code.pyx | 234 ++++++++------------------------ 2 files changed, 60 insertions(+), 180 deletions(-) diff --git a/src/sage/coding/binary_code.pxd b/src/sage/coding/binary_code.pxd index 44a793d15df..6331dc84693 100644 --- a/src/sage/coding/binary_code.pxd +++ b/src/sage/coding/binary_code.pxd @@ -1,3 +1,5 @@ +from memory_allocator cimport MemoryAllocator + cdef int *hamming_weights() noexcept ctypedef unsigned int codeword @@ -11,6 +13,7 @@ cdef struct WordPermutation: codeword gate cdef class BinaryCode: + cdef MemoryAllocator mem cdef codeword *basis cdef codeword *words cdef int ncols @@ -34,6 +37,7 @@ cdef codeword permute_word_by_wp(WordPermutation *, codeword) noexcept cdef codeword *expand_to_ortho_basis(BinaryCode, int) noexcept cdef class OrbitPartition: + cdef MemoryAllocator mem cdef int nwords cdef int ncols cdef int *wd_parent @@ -52,6 +56,7 @@ cdef class OrbitPartition: cdef int merge_perm(self, int *, int *) noexcept cdef class PartitionStack: + cdef MemoryAllocator mem cdef int *wd_ents cdef int *wd_lvls cdef int *col_ents @@ -89,6 +94,7 @@ cdef class PartitionStack: cdef void get_permutation(self, PartitionStack, int *, int *) noexcept cdef class BinaryCodeClassifier: + cdef MemoryAllocator mem cdef int *ham_wts cdef int L cdef unsigned int *Phi diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index dd7b017fbe4..f7e87d8257e 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -123,8 +123,9 @@ def weight_dist(M): cdef bitset_t word cdef int i,j,k, dim=M.nrows(), deg=M.ncols() cdef list L - cdef int *LL = sig_malloc((deg+1) * sizeof(int)) - cdef bitset_s *basis = sig_malloc(dim * sizeof(bitset_s)) + cdef MemoryAllocator mem = MemoryAllocator() + cdef int *LL = mem.malloc((deg+1) * sizeof(int)) + cdef bitset_s *basis = mem.malloc(dim * sizeof(bitset_s)) for i from 0 <= i < dim: bitset_init(&basis[i], deg) bitset_zero(&basis[i]) @@ -150,8 +151,6 @@ def weight_dist(M): L = [int(LL[i]) for i from 0 <= i < deg+1] for i from 0 <= i < dim: bitset_free(&basis[i]) - sig_free(LL) - sig_free(basis) return L @@ -785,12 +784,9 @@ cdef class BinaryCode: if self.nrows >= self.radix or self.ncols > self.radix: raise NotImplementedError("Columns and rows are stored as ints. This code is too big.") - self.words = sig_malloc( nwords * sizeof(int) ) - self.basis = sig_malloc( nrows * sizeof(int) ) - if self.words is NULL or self.basis is NULL: - if self.words is not NULL: sig_free(self.words) - if self.basis is not NULL: sig_free(self.basis) - raise MemoryError("Memory.") + self.mem = MemoryAllocator() + self.words = self.mem.malloc(nwords * sizeof(int)) + self.basis = self.mem.malloc(nrows * sizeof(int)) self_words = self.words self_basis = self.basis @@ -830,8 +826,7 @@ cdef class BinaryCode: self_words[combination+other_nwords] = self_words[combination] ^ glue_word def __dealloc__(self): - sig_free(self.words) - sig_free(self.basis) + pass def __reduce__(self): """ @@ -1279,35 +1274,15 @@ 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)) - 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) - raise MemoryError("Memory.") + self.mem = MemoryAllocator() + self.wd_parent = self.mem.malloc(nwords * sizeof(int)) + self.wd_rank = self.mem.malloc(nwords * sizeof(int)) + self.wd_min_cell_rep = self.mem.malloc(nwords * sizeof(int)) + self.wd_size = self.mem.malloc(nwords * sizeof(int)) + self.col_parent = self.mem.malloc(ncols * sizeof(int)) + self.col_rank = self.mem.malloc(ncols * sizeof(int)) + self.col_min_cell_rep = self.mem.malloc(ncols * sizeof(int)) + self.col_size = self.mem.malloc(ncols * sizeof(int)) for word from 0 <= word < nwords: self.wd_parent[word] = word self.wd_rank[word] = 0 @@ -1320,14 +1295,7 @@ cdef class OrbitPartition: self.col_size[col] = 1 def __dealloc__(self): - sig_free(self.wd_parent) - sig_free(self.wd_rank) - sig_free(self.wd_min_cell_rep) - sig_free(self.wd_size) - sig_free(self.col_parent) - sig_free(self.col_rank) - sig_free(self.col_min_cell_rep) - sig_free(self.col_size) + pass def __repr__(self): """ @@ -1614,44 +1582,19 @@ 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.mem = MemoryAllocator() + self.wd_ents = self.mem.malloc(self.nwords * sizeof_int) + self.wd_lvls = self.mem.malloc(self.nwords * sizeof_int) + self.col_ents = self.mem.malloc(self.ncols * sizeof_int) + self.col_lvls = self.mem.malloc(self.ncols * sizeof_int) # scratch space - 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 ) - - 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) - raise MemoryError("Memory.") + self.col_degs = self.mem.malloc( self.ncols * sizeof_int ) + self.col_counts = self.mem.malloc( self.nwords * sizeof_int ) + self.col_output = self.mem.malloc( self.ncols * sizeof_int ) + self.wd_degs = self.mem.malloc( self.nwords * sizeof_int ) + self.wd_counts = self.mem.malloc( (self.ncols+1) * sizeof_int ) + self.wd_output = self.mem.malloc( self.nwords * sizeof_int ) nwords = self.nwords ncols = self.ncols @@ -1694,17 +1637,8 @@ cdef class PartitionStack: wd_output[k]=0 def __dealloc__(self): - if self.basis_locations: sig_free(self.basis_locations) - sig_free(self.wd_ents) - sig_free(self.wd_lvls) - sig_free(self.col_ents) - sig_free(self.col_lvls) - sig_free(self.col_degs) - sig_free(self.col_counts) - sig_free(self.col_output) - sig_free(self.wd_degs) - sig_free(self.wd_counts) - sig_free(self.wd_output) + if self.basis_locations: + sig_free(self.basis_locations) def print_data(self): """ @@ -3092,80 +3026,31 @@ 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.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) ) - - 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) - raise MemoryError("Memory.") + self.mem = MemoryAllocator() + self.w_gamma = self.mem.malloc(self.w_gamma_size * sizeof(int)) + self.alpha = self.mem.malloc(self.alpha_size * sizeof(int)) + self.Phi = self.mem.malloc(self.Phi_size * (self.L+1) * sizeof(unsigned int)) + self.Omega = self.mem.malloc(self.Phi_size * self.L * sizeof(unsigned int)) + self.W = self.mem.malloc(self.Phi_size * self.radix * 2 * sizeof(unsigned int)) + + self.base = self.mem.malloc(self.radix * sizeof(int)) + self.aut_gp_gens = self.mem.malloc(self.aut_gens_size * sizeof(int)) + self.c_gamma = self.mem.malloc(self.radix * sizeof(int)) + self.labeling = self.mem.malloc(self.radix * 3 * sizeof(int)) + self.Lambda1 = self.mem.malloc(self.radix * 2 * sizeof(int)) + self.Lambda2 = self.mem.malloc(self.radix * 2 * sizeof(int)) + self.Lambda3 = self.mem.malloc(self.radix * 2 * sizeof(int)) + self.v = self.mem.malloc(self.radix * 2 * sizeof(int)) + self.e = self.mem.malloc(self.radix * 2 * sizeof(int)) def __dealloc__(self): - sig_free(self.ham_wts) - sig_free(self.Phi) - sig_free(self.Omega) - sig_free(self.W) - sig_free(self.Lambda1) - sig_free(self.Lambda2) - sig_free(self.Lambda3) - sig_free(self.c_gamma) - sig_free(self.w_gamma) - sig_free(self.alpha) - sig_free(self.v) - sig_free(self.e) - sig_free(self.aut_gp_gens) - sig_free(self.labeling) - sig_free(self.base) + pass cdef void record_automorphism(self, int *gamma, int ncols) noexcept: cdef int i, j if self.aut_gp_index + ncols > self.aut_gens_size: self.aut_gens_size *= 2 - self.aut_gp_gens = sig_realloc( self.aut_gp_gens, self.aut_gens_size * sizeof(int) ) - if self.aut_gp_gens is NULL: - raise MemoryError("Memory.") + self.aut_gp_gens = self.mem.realloc(self.aut_gp_gens, self.aut_gens_size * sizeof(int)) j = self.aut_gp_index for i from 0 <= i < ncols: self.aut_gp_gens[i+j] = gamma[i] @@ -3404,23 +3289,12 @@ 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)) - 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) - raise MemoryError("Memory.") + self.w_gamma = self.mem.realloc(self.w_gamma, self.w_gamma_size * sizeof(int)) + self.alpha = self.mem.realloc(self.alpha, self.alpha_size * sizeof(int)) + self.Phi = self.mem.realloc(self.Phi, self.Phi_size * self.L * sizeof(int)) + self.Omega = self.mem.realloc(self.Omega, self.Phi_size * self.L * sizeof(int)) + self.W = self.mem.realloc(self.W, self.Phi_size * self.radix * 2 * sizeof(int)) + for i from 0 <= i < self.Phi_size * self.L: self.Omega[i] = 0 word_gamma = self.w_gamma From 0c35641da9d3e8fe44086a439ca05a12af9f615a Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 11 Jan 2025 09:15:07 +0100 Subject: [PATCH 144/175] #39228: use pairing heap in bidirectional_dijkstra_special --- src/sage/graphs/base/c_graph.pyx | 183 +++++++++++++-------------- src/sage/graphs/path_enumeration.pyx | 50 ++++---- 2 files changed, 114 insertions(+), 119 deletions(-) diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 46464a9835f..953c3983f2d 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -46,7 +46,7 @@ method :meth:`realloc `. from sage.data_structures.bitset_base cimport * from sage.rings.integer cimport smallInteger from sage.arith.long cimport pyobject_to_long -from libcpp.queue cimport priority_queue, queue +from libcpp.queue cimport queue from libcpp.stack cimport stack from libcpp.pair cimport pair from sage.rings.integer_ring import ZZ @@ -3738,7 +3738,6 @@ cdef class CGraphBackend(GenericGraphBackend): cdef dict pred_x = {} cdef dict pred_y = {} cdef dict pred_current - cdef dict pred_other # Stores the distances from x and y cdef dict dist_x = {} @@ -3746,95 +3745,90 @@ cdef class CGraphBackend(GenericGraphBackend): cdef dict dist_current cdef dict dist_other - # Lists of vertices who are left to be explored. They are represented - # as pairs of pair and pair: ((distance, side), (predecessor, name)). - # 1 indicates x's side, -1 indicates y's, the distance being - # defined relatively. - cdef priority_queue[pair[pair[double, int], pair[int, int]]] pq - pq.push(((0, 1), (x_int, x_int))) - pq.push(((0, -1), (y_int, y_int))) - cdef list neighbors - - cdef list shortest_path = [] + # We use 2 min-heap data structures (pairing heaps), one for the + # exploration from x and the other for the reverse exploration to y. + # Each heap associates to a vertex a pair (distance, pred). + cdef PairingHeap[int, pair[double, int]] px = PairingHeap[int, pair[double, int]]() + cdef PairingHeap[int, pair[double, int]] py = PairingHeap[int, pair[double, int]]() + cdef PairingHeap[int, pair[double, int]] * ptmp + px.push(x_int, (0, x_int)) + py.push(y_int, (0, y_int)) # Meeting_vertex is a vertex discovered through x and through y # which defines the shortest path found # (of length shortest_path_length). cdef int meeting_vertex = -1 + cdef double shortest_path_length + cdef double f_tmp if reduced_weight is not None: def weight_function(e): return reduced_weight[(e[0], e[1])] # As long as the current side (x or y) is not totally explored ... - while not pq.empty(): - (distance, side), (pred, v) = pq.top() - # priority_queue by default is max heap - # negative value of distance is stored in priority_queue to get - # minimum distance - distance = -distance - pq.pop() + while not (px.empty() and py.empty()): + if (px.empty() or + (not py.empty() and px.top_value().first > py.top_value().first)): + side = -1 + ptmp = &py + else: # px is not empty + side = 1 + ptmp = &px + v, (distance, pred) = ptmp.top() if meeting_vertex != -1 and distance > shortest_path_length: break + ptmp.pop() if side == 1: dist_current, dist_other = dist_x, dist_y - pred_current, pred_other = pred_x, pred_y + pred_current = pred_x + nbr_iter = self.cg().out_neighbors(v) else: dist_current, dist_other = dist_y, dist_x - pred_current, pred_other = pred_y, pred_x - - if v not in dist_current: - if not distance_flag: - pred_current[v] = pred - dist_current[v] = distance - - if v in dist_other: - f_tmp = distance + dist_other[v] - if meeting_vertex == -1 or f_tmp < shortest_path_length: - meeting_vertex = v - shortest_path_length = f_tmp - if side == 1: - nbr = self.cg().out_neighbors(v) - else: - nbr = self.cg().in_neighbors(v) + pred_current = pred_y + nbr_iter = self.cg().in_neighbors(v) - if not exclude_e and not exclude_v: - neighbors = [] - for n in nbr: - if include_v and n not in include_vertices_int: - continue - neighbors.append(n) - else: - neighbors = [] - for w in nbr: - if exclude_v and w in exclude_vertices_int: - continue - if (exclude_e and - ((side == 1 and (v, w) in exclude_edges_int) or - (side == -1 and (w, v) in exclude_edges_int))): - continue - if include_v and w not in include_vertices_int: - continue - neighbors.append(w) - for w in neighbors: - # If the neighbor is new, adds its non-found neighbors to - # the queue. - if w not in dist_current: - v_obj = self.vertex_label(v) - w_obj = self.vertex_label(w) - if side == -1: - v_obj, w_obj = w_obj, v_obj - if self._multiple_edges: - edge_label = min(weight_function((v_obj, w_obj, l)) for l in self.get_edge_label(v_obj, w_obj)) - else: - edge_label = weight_function((v_obj, w_obj, self.get_edge_label(v_obj, w_obj))) - if edge_label < 0: - raise ValueError("the graph contains an edge with negative weight") - # priority_queue is by default max_heap - # negative value of distance + edge_label is stored in - # priority_queue to get minimum distance - pq.push(((-(distance + edge_label), side), (v, w))) + dist_current[v] = distance + if not distance_flag: + pred_current[v] = pred + + if v in dist_other: + f_tmp = distance + dist_other[v] + if meeting_vertex == -1 or f_tmp < shortest_path_length: + meeting_vertex = v + shortest_path_length = f_tmp + + if not exclude_e and not exclude_v: + neighbors = (w for w in nbr_iter + if not include_v or w in include_vertices_int) + else: + neighbors = (w for w in nbr_iter + if ((not exclude_v or w not in exclude_vertices_int) and + (not exclude_e or + ((side == 1 and (v, w) not in exclude_edges_int) or + (side == -1 and (w, v) not in exclude_edges_int))) and + (not include_v or w in include_vertices_int))) + + for w in neighbors: + # If w has not yet been extracted from the heap, we check if we + # can improve its path + if w not in dist_current: + v_obj = self.vertex_label(v) + w_obj = self.vertex_label(w) + if side == -1: + v_obj, w_obj = w_obj, v_obj + if self._multiple_edges: + edge_label = min(weight_function((v_obj, w_obj, l)) for l in self.get_edge_label(v_obj, w_obj)) + else: + edge_label = weight_function((v_obj, w_obj, self.get_edge_label(v_obj, w_obj))) + if edge_label < 0: + raise ValueError("the graph contains an edge with negative weight") + f_tmp = distance + edge_label + if ptmp.contains(w): + if ptmp.value(w).first > f_tmp: + ptmp.decrease(w, (f_tmp, v)) + else: + ptmp.push(w, (f_tmp, v)) # No meeting point has been found if meeting_vertex == -1: @@ -3842,32 +3836,33 @@ cdef class CGraphBackend(GenericGraphBackend): from sage.rings.infinity import Infinity return Infinity return [] - else: - # build the shortest path and returns it. - if distance_flag: - if shortest_path_length in ZZ: - return int(shortest_path_length) - else: - return shortest_path_length - w = meeting_vertex - while w != x_int: - shortest_path.append(self.vertex_label(w)) - w = pred_x[w] + if distance_flag: + if shortest_path_length in ZZ: + return int(shortest_path_length) + return shortest_path_length - shortest_path.append(x) - shortest_path.reverse() + # build the shortest path and return it. + cdef list shortest_path = [] + w = meeting_vertex + while w != x_int: + shortest_path.append(self.vertex_label(w)) + w = pred_x[w] + + shortest_path.append(x) + shortest_path.reverse() - if meeting_vertex == y_int: - return shortest_path + if meeting_vertex == y_int: + return shortest_path - w = pred_y[meeting_vertex] - while w != y_int: - shortest_path.append(self.vertex_label(w)) - w = pred_y[w] - shortest_path.append(y) + w = pred_y[meeting_vertex] + while w != y_int: + shortest_path.append(self.vertex_label(w)) + w = pred_y[w] - return shortest_path + shortest_path.append(y) + + return shortest_path def bidirectional_dijkstra(self, x, y, weight_function=None, distance_flag=False): @@ -4050,7 +4045,7 @@ cdef class CGraphBackend(GenericGraphBackend): return int(shortest_path_length) return shortest_path_length - # build the shortest path and returns it. + # build the shortest path and return it. cdef list shortest_path = [] w = meeting_vertex while w != x_int: diff --git a/src/sage/graphs/path_enumeration.pyx b/src/sage/graphs/path_enumeration.pyx index 50b992692e4..aa16b1dc7b1 100644 --- a/src/sage/graphs/path_enumeration.pyx +++ b/src/sage/graphs/path_enumeration.pyx @@ -361,7 +361,7 @@ def shortest_simple_paths(self, source, target, weight_function=None, ....: report_edges=True, report_weight=True)) [(20, [(1, 3), (3, 5)]), (40, [(1, 2), (2, 5)]), (60, [(1, 4), (4, 5)])] sage: list(g.shortest_simple_paths(1, 5, report_edges=True, report_weight=True)) - [(2, [(1, 4), (4, 5)]), (2, [(1, 3), (3, 5)]), (2, [(1, 2), (2, 5)])] + [(2, [(1, 2), (2, 5)]), (2, [(1, 3), (3, 5)]), (2, [(1, 4), (4, 5)])] sage: list(g.shortest_simple_paths(1, 5, by_weight=True, report_edges=True)) [[(1, 3), (3, 5)], [(1, 2), (2, 5)], [(1, 4), (4, 5)]] sage: list(g.shortest_simple_paths(1, 5, by_weight=True, algorithm='Feng', @@ -432,12 +432,12 @@ def shortest_simple_paths(self, source, target, weight_function=None, ....: (6, 9, 1), (9, 5, 1), (4, 2, 1), (9, 3, 1), ....: (9, 10, 1), (10, 5, 1), (9, 11, 1), (11, 10, 1)]) sage: list(g.shortest_simple_paths(1, 5, algorithm='Feng')) - [[1, 7, 8, 5], - [1, 6, 9, 5], - [1, 6, 9, 10, 5], + [[1, 6, 9, 5], + [1, 7, 8, 5], [1, 2, 3, 4, 5], - [1, 6, 9, 3, 4, 5], - [1, 6, 9, 11, 10, 5]] + [1, 6, 9, 10, 5], + [1, 6, 9, 11, 10, 5], + [1, 6, 9, 3, 4, 5]] sage: # needs sage.combinat sage: G = digraphs.DeBruijn(2, 3) @@ -957,11 +957,11 @@ def feng_k_shortest_simple_paths(self, source, target, weight_function=None, sage: list(feng_k_shortest_simple_paths(g, 1, 5, by_weight=True)) [[1, 3, 5], [1, 2, 5], [1, 4, 5]] sage: list(feng_k_shortest_simple_paths(g, 1, 5)) - [[1, 4, 5], [1, 3, 5], [1, 2, 5]] + [[1, 2, 5], [1, 3, 5], [1, 4, 5]] sage: list(feng_k_shortest_simple_paths(g, 1, 1)) [[1]] sage: list(feng_k_shortest_simple_paths(g, 1, 5, report_edges=True, labels=True)) - [[(1, 4, 30), (4, 5, 30)], [(1, 3, 10), (3, 5, 10)], [(1, 2, 20), (2, 5, 20)]] + [[(1, 2, 20), (2, 5, 20)], [(1, 3, 10), (3, 5, 10)], [(1, 4, 30), (4, 5, 30)]] sage: list(feng_k_shortest_simple_paths(g, 1, 5, report_edges=True, labels=True, by_weight=True)) [[(1, 3, 10), (3, 5, 10)], [(1, 2, 20), (2, 5, 20)], [(1, 4, 30), (4, 5, 30)]] sage: list(feng_k_shortest_simple_paths(g, 1, 5, report_edges=True, labels=True, by_weight=True, report_weight=True)) @@ -974,7 +974,7 @@ def feng_k_shortest_simple_paths(self, source, target, weight_function=None, sage: list(feng_k_shortest_simple_paths(g, 1, 6, by_weight = True)) [[1, 3, 5, 6], [1, 2, 5, 6], [1, 4, 5, 6], [1, 6]] sage: list(feng_k_shortest_simple_paths(g, 1, 6)) - [[1, 6], [1, 4, 5, 6], [1, 3, 5, 6], [1, 2, 5, 6]] + [[1, 6], [1, 2, 5, 6], [1, 3, 5, 6], [1, 4, 5, 6]] sage: list(feng_k_shortest_simple_paths(g, 1, 6, report_edges=True, labels=True, by_weight=True, report_weight=True)) [(25, [(1, 3, 10), (3, 5, 10), (5, 6, 5)]), (45, [(1, 2, 20), (2, 5, 20), (5, 6, 5)]), @@ -982,9 +982,9 @@ def feng_k_shortest_simple_paths(self, source, target, weight_function=None, (100, [(1, 6, 100)])] sage: list(feng_k_shortest_simple_paths(g, 1, 6, report_edges=True, labels=True, report_weight=True)) [(1, [(1, 6, 100)]), - (3, [(1, 4, 30), (4, 5, 30), (5, 6, 5)]), + (3, [(1, 2, 20), (2, 5, 20), (5, 6, 5)]), (3, [(1, 3, 10), (3, 5, 10), (5, 6, 5)]), - (3, [(1, 2, 20), (2, 5, 20), (5, 6, 5)])] + (3, [(1, 4, 30), (4, 5, 30), (5, 6, 5)])] sage: from sage.graphs.path_enumeration import feng_k_shortest_simple_paths sage: g = DiGraph([(1, 2, 5), (2, 3, 0), (1, 4, 2), (4, 5, 1), (5, 3, 0)]) sage: list(feng_k_shortest_simple_paths(g, 1, 3, by_weight=True)) @@ -1031,30 +1031,30 @@ def feng_k_shortest_simple_paths(self, source, target, weight_function=None, (27, [(1, 2, 1), (2, 3, 1), (3, 8, 5), (8, 9, 2), (9, 11, 10), (11, 6, 8)]), (105, [(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 5, 2), (5, 6, 100)])] sage: list(feng_k_shortest_simple_paths(g, 1, 6)) - [[1, 2, 3, 8, 9, 6], + [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 7, 6], - [1, 2, 3, 4, 5, 6], - [1, 2, 3, 8, 9, 10, 6], - [1, 2, 3, 8, 9, 11, 6]] + [1, 2, 3, 8, 9, 6], + [1, 2, 3, 8, 9, 11, 6], + [1, 2, 3, 8, 9, 10, 6]] sage: from sage.graphs.path_enumeration import feng_k_shortest_simple_paths sage: g = DiGraph([(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 5, 1), ....: (1, 7, 1), (7, 8, 1), (8, 5, 1), (1, 6, 1), ....: (6, 9, 1), (9, 5, 1), (4, 2, 1), (9, 3, 1), ....: (9, 10, 1), (10, 5, 1), (9, 11, 1), (11, 10, 1)]) sage: list(feng_k_shortest_simple_paths(g, 1, 5)) - [[1, 7, 8, 5], - [1, 6, 9, 5], - [1, 6, 9, 10, 5], + [[1, 6, 9, 5], + [1, 7, 8, 5], [1, 2, 3, 4, 5], - [1, 6, 9, 3, 4, 5], - [1, 6, 9, 11, 10, 5]] - sage: list(feng_k_shortest_simple_paths(g, 1, 5, by_weight=True)) - [[1, 7, 8, 5], - [1, 6, 9, 5], [1, 6, 9, 10, 5], + [1, 6, 9, 11, 10, 5], + [1, 6, 9, 3, 4, 5]] + sage: list(feng_k_shortest_simple_paths(g, 1, 5, by_weight=True)) + [[1, 6, 9, 5], + [1, 7, 8, 5], [1, 2, 3, 4, 5], - [1, 6, 9, 3, 4, 5], - [1, 6, 9, 11, 10, 5]] + [1, 6, 9, 10, 5], + [1, 6, 9, 11, 10, 5], + [1, 6, 9, 3, 4, 5]] sage: from sage.graphs.path_enumeration import feng_k_shortest_simple_paths sage: g = DiGraph([(1, 2, 5), (6, 3, 0), (2, 6, 6), (1, 4, 15), ....: (4, 5, 1), (4, 3, 0), (7, 1, 2), (8, 7, 1)]) From 4abac57821fc7b6bd03e9f4a380581d8f31efa79 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 11 Jan 2025 09:26:30 +0100 Subject: [PATCH 145/175] #39228: reorder imports --- src/sage/graphs/base/c_graph.pyx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 953c3983f2d..87ef188cc9c 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -43,16 +43,18 @@ method :meth:`realloc `. # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.data_structures.bitset_base cimport * -from sage.rings.integer cimport smallInteger -from sage.arith.long cimport pyobject_to_long +from cysignals.memory cimport check_allocarray, sig_free +from libcpp.pair cimport pair from libcpp.queue cimport queue from libcpp.stack cimport stack -from libcpp.pair cimport pair -from sage.rings.integer_ring import ZZ -from cysignals.memory cimport check_allocarray, sig_free + +from sage.arith.long cimport pyobject_to_long from sage.data_structures.bitset cimport FrozenBitset +from sage.data_structures.bitset_base cimport * from sage.data_structures.pairing_heap cimport PairingHeap +from sage.rings.integer cimport smallInteger + +from sage.rings.integer_ring import ZZ cdef extern from "Python.h": From 3962a937238ee4b2fbc3271c34e2839428b40ff0 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 11 Jan 2025 09:34:17 +0100 Subject: [PATCH 146/175] #39228: remove trailing whitespaces --- src/sage/graphs/base/c_graph.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 87ef188cc9c..982dc51cca7 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -3850,7 +3850,7 @@ cdef class CGraphBackend(GenericGraphBackend): while w != x_int: shortest_path.append(self.vertex_label(w)) w = pred_x[w] - + shortest_path.append(x) shortest_path.reverse() From eb3695fd1f9b61cdacbad625576f4a5f17a9115e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 11 Jan 2025 10:03:50 +0100 Subject: [PATCH 147/175] partial pep8 cleanup in Lie conformal algebras --- .../abelian_lie_conformal_algebra.py | 11 ++--- .../affine_lie_conformal_algebra.py | 4 +- .../bosonic_ghosts_lie_conformal_algebra.py | 4 +- .../fermionic_ghosts_lie_conformal_algebra.py | 4 +- .../free_bosons_lie_conformal_algebra.py | 28 ++++++------ .../free_fermions_lie_conformal_algebra.py | 43 +++++++++---------- .../freely_generated_lie_conformal_algebra.py | 4 +- .../lie_conformal_algebra.py | 2 +- ..._conformal_algebra_with_structure_coefs.py | 32 ++++++++------ 9 files changed, 69 insertions(+), 63 deletions(-) diff --git a/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py index 6027dee4a95..3cfa3343d80 100644 --- a/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py @@ -89,16 +89,17 @@ def __init__(self, R, ngens=1, weights=None, names = 'a' self._latex_names = tuple(r'a_{%d}' % i for i in range(ngens)) - names,index_set = standardize_names_index_set(names=names, - index_set=index_set, - ngens=ngens) + names, index_set = standardize_names_index_set(names=names, + index_set=index_set, + ngens=ngens) abeliandict = {} GradedLieConformalAlgebra.__init__(self, R, abeliandict, names=names, - index_set=index_set, weights=weights, + index_set=index_set, + weights=weights, parity=parity) - def _repr_(self): + def _repr_(self) -> str: """ String representation. diff --git a/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py index e9f697e8257..66d4fe6da5c 100644 --- a/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py @@ -142,7 +142,7 @@ def cartan_type(self): """ return self._ct - def _repr_(self): + def _repr_(self) -> str: """ The name of this Lie conformal algebra. @@ -152,4 +152,4 @@ def _repr_(self): The affine Lie conformal algebra of type ['A', 1] over Rational Field """ return "The affine Lie conformal algebra of type {} over {}".format( - self._ct,self.base_ring()) + self._ct, self.base_ring()) diff --git a/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py index 2e689ee4c60..a3db3b8334e 100644 --- a/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py @@ -120,7 +120,7 @@ def __init__(self, R, ngens=2, names=None, index_set=None): weights=weights, central_elements=('K',)) - def _repr_(self): + def _repr_(self) -> str: """ String representation. @@ -130,4 +130,4 @@ def _repr_(self): The Bosonic ghosts Lie conformal algebra with generators (beta, gamma, K) over Algebraic Field """ return "The Bosonic ghosts Lie conformal algebra with generators {} "\ - "over {}".format(self.gens(),self.base_ring()) + "over {}".format(self.gens(), self.base_ring()) diff --git a/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py index 6c4418e4751..787310885c3 100644 --- a/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py @@ -117,7 +117,7 @@ def __init__(self, R, ngens=2, names=None, index_set=None): parity=parity, central_elements=('K',)) - def _repr_(self): + def _repr_(self) -> str: """ String representation. @@ -127,4 +127,4 @@ def _repr_(self): The Fermionic ghosts Lie conformal algebra with generators (b, c, K) over Rational Field """ return "The Fermionic ghosts Lie conformal algebra with generators {} "\ - "over {}".format(self.gens(),self.base_ring()) + "over {}".format(self.gens(), self.base_ring()) diff --git a/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py index e66489d49ca..215cabd83e8 100644 --- a/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py @@ -114,37 +114,39 @@ def __init__(self, R, ngens=None, gram_matrix=None, names=None, if ngens is None: ngens = gram_matrix.dimensions()[0] try: - assert (gram_matrix in MatrixSpace(R,ngens,ngens)) + assert (gram_matrix in MatrixSpace(R, ngens, ngens)) except AssertionError: raise ValueError("the gram_matrix should be a symmetric " + - "{0} x {0} matrix, got {1}".format(ngens,gram_matrix)) + "{0} x {0} matrix, got {1}".format(ngens, gram_matrix)) if not gram_matrix.is_symmetric(): raise ValueError("the gram_matrix should be a symmetric " + - "{0} x {0} matrix, got {1}".format(ngens,gram_matrix)) + "{0} x {0} matrix, got {1}".format(ngens, gram_matrix)) else: if ngens is None: ngens = 1 gram_matrix = identity_matrix(R, ngens, ngens) latex_names = None - if (names is None) and (index_set is None): + if names is None and index_set is None: names = 'alpha' latex_names = tuple(r'\alpha_{%d}' % i for i in range(ngens)) + ('K',) - names,index_set = standardize_names_index_set(names=names, - index_set=index_set, - ngens=ngens) - bosondict = {(i,j): {1: {('K',0): gram_matrix[index_set.rank(i), - index_set.rank(j)]}} for i in index_set for j in index_set} - - GradedLieConformalAlgebra.__init__(self,R,bosondict,names=names, + names, index_set = standardize_names_index_set(names=names, + index_set=index_set, + ngens=ngens) + bosondict = {(i, j): {1: {('K', 0): gram_matrix[index_set.rank(i), + index_set.rank(j)]}} + for i in index_set for j in index_set} + + GradedLieConformalAlgebra.__init__(self, R, bosondict, + names=names, latex_names=latex_names, index_set=index_set, central_elements=('K',)) self._gram_matrix = gram_matrix - def _repr_(self): + def _repr_(self) -> str: """ String representation. @@ -154,7 +156,7 @@ def _repr_(self): The free Bosons Lie conformal algebra with generators (alpha, K) over Algebraic Real Field """ return "The free Bosons Lie conformal algebra with generators {}"\ - " over {}".format(self.gens(),self.base_ring()) + " over {}".format(self.gens(), self.base_ring()) def gram_matrix(self): r""" diff --git a/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py index 40810602ac4..32d8f65e8d9 100644 --- a/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py @@ -94,17 +94,17 @@ def __init__(self, R, ngens=None, gram_matrix=None, names=None, """ from sage.matrix.matrix_space import MatrixSpace from sage.matrix.special import identity_matrix - if (gram_matrix is not None): + if gram_matrix is not None: if ngens is None: ngens = gram_matrix.dimensions()[0] try: - assert (gram_matrix in MatrixSpace(R,ngens,ngens)) + assert (gram_matrix in MatrixSpace(R, ngens, ngens)) except AssertionError: raise ValueError("The gram_matrix should be a symmetric " + - "{0} x {0} matrix, got {1}".format(ngens,gram_matrix)) + "{0} x {0} matrix, got {1}".format(ngens, gram_matrix)) if not gram_matrix.is_symmetric(): raise ValueError("The gram_matrix should be a symmetric " + - "{0} x {0} matrix, got {1}".format(ngens,gram_matrix)) + "{0} x {0} matrix, got {1}".format(ngens, gram_matrix)) else: if ngens is None: ngens = 1 @@ -112,34 +112,33 @@ def __init__(self, R, ngens=None, gram_matrix=None, names=None, latex_names = None - if (names is None) and (index_set is None): - if ngens == 1: - names = 'psi' - else: - names = 'psi_' + if names is None and index_set is None: + names = 'psi' if ngens == 1 else 'psi_' latex_names = tuple(r"\psi_{%d}" % i for i in range(ngens)) + ('K',) from sage.structure.indexed_generators import \ - standardize_names_index_set - names,index_set = standardize_names_index_set(names=names, - index_set=index_set, - ngens=ngens) - fermiondict = {(i,j): {0: {('K', 0): gram_matrix[index_set.rank(i), - index_set.rank(j)]}} for i in index_set for j in index_set} + standardize_names_index_set + names, index_set = standardize_names_index_set(names=names, + index_set=index_set, + ngens=ngens) + fermiondict = {(i, j): {0: {('K', 0): gram_matrix[index_set.rank(i), + index_set.rank(j)]}} + for i in index_set for j in index_set} from sage.rings.rational_field import QQ - weights = (QQ(1/2),)*ngens - parity = (1,)*ngens - GradedLieConformalAlgebra.__init__(self,R,fermiondict,names=names, + weights = (QQ((1, 2)),) * ngens + parity = (1,) * ngens + GradedLieConformalAlgebra.__init__(self, R, fermiondict, names=names, latex_names=latex_names, - index_set=index_set,weights=weights, + index_set=index_set, + weights=weights, parity=parity, central_elements=('K',)) self._gram_matrix = gram_matrix - def _repr_(self): + def _repr_(self) -> str: """ String representation. @@ -149,8 +148,8 @@ def _repr_(self): The free Fermions super Lie conformal algebra with generators (psi, K) over Rational Field """ return "The free Fermions super Lie conformal algebra "\ - "with generators {} over {}".format(self.gens(), - self.base_ring()) + "with generators {} over {}".format(self.gens(), + self.base_ring()) def gram_matrix(self): r""" diff --git a/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py index 0b77dd91854..803c2997271 100644 --- a/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py @@ -81,8 +81,8 @@ def lie_conformal_algebra_generators(self): (B[alpha[1]], B[alphacheck[1]], B[-alpha[1]], B['K']) """ F = Family(self._generators, - lambda i: self.monomial((i,Integer(0))), - name="generator map") + lambda i: self.monomial((i, Integer(0))), + name="generator map") from sage.categories.sets_cat import Sets if F in Sets().Finite(): return tuple(F) diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py index 528a587d795..9248927e242 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py @@ -331,7 +331,7 @@ def __classcall_private__(cls, R=None, arg0=None, index_set=None, if key not in known_keywords: raise ValueError("got an unexpected keyword argument '%s'" % key) - if isinstance(arg0,dict) and arg0: + if isinstance(arg0, dict) and arg0: graded = kwds.pop("graded", False) if weights is not None or graded: from .graded_lie_conformal_algebra import \ diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py index 3cb8f645cd5..97fc71e09a6 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py @@ -148,7 +148,7 @@ def _standardize_s_coeff(s_coeff, index_set, ce, parity=None): index_to_parity = dict(zip(index_set, parity)) sc = {} # mypair has a pair of generators - for mypair in s_coeff.keys(): + for mypair, v in s_coeff.items(): # e.g. v = { 0: { (L,2):3, (G,3):1}, 1:{(L,1),2} } v = s_coeff[mypair] key = tuple(mypair) @@ -186,7 +186,7 @@ def _standardize_s_coeff(s_coeff, index_set, ce, parity=None): kth_product[(i[0], i[1] + j)] = \ kth_product.get((i[0], i[1] + j), 0) kth_product[(i[0], i[1] + j)] += parsgn *\ - v[k+j][i]*(-1)**(k+j+1)*binomial(i[1]+j,j) + v[k+j][i]*(-1)**(k+j+1)*binomial(i[1]+j, j) kth_product = {k: v for k, v in kth_product.items() if v} if kth_product: vals[k] = kth_product @@ -212,7 +212,7 @@ def __init__(self, R, s_coeff, index_set=None, central_elements=None, sage: V = lie_conformal_algebras.NeveuSchwarz(QQ) sage: TestSuite(V).run() """ - names, index_set = standardize_names_index_set(names,index_set) + names, index_set = standardize_names_index_set(names, index_set) if central_elements is None: central_elements = () @@ -220,13 +220,14 @@ def __init__(self, R, s_coeff, index_set=None, central_elements=None, names2 = names + tuple(central_elements) index_set2 = DisjointUnionEnumeratedSets((index_set, Family(tuple(central_elements)))) - d = {x:index_set2[i] for i,x in enumerate(names2)} + d = {x: index_set2[i] for i, x in enumerate(names2)} try: - #If we are given a dictionary with names as keys, - #convert to index_set as keys - s_coeff = {(d[k[0]],d[k[1]]):{a:{(d[x[1]],x[2]): - s_coeff[k][a][x] for x in - s_coeff[k][a]} for a in s_coeff[k]} for k in s_coeff.keys()} + # If we are given a dictionary with names as keys, + # convert to index_set as keys + s_coeff = {(d[k[0]], d[k[1]]): + {a: {(d[x[1]], x[2]): sck[a][x] for x in sck[a]} + for a in s_coeff[k]} + for k, sck in s_coeff.items()} except KeyError: # We assume the dictionary was given with keys in the @@ -274,9 +275,12 @@ def __init__(self, R, s_coeff, index_set=None, central_elements=None, prefix=prefix, names=names, latex_names=latex_names, **kwds) s_coeff = dict(s_coeff) - self._s_coeff = Family({k: tuple((j, sum(c*self.monomial(i) - for i,c in v)) for j,v in s_coeff[k]) for k in s_coeff}) - self._parity = dict(zip(self.gens(),parity+(0,)*len(central_elements))) + self._s_coeff = Family({k: + tuple((j, sum(c * self.monomial(i) + for i, c in v)) for j, v in sck) + for k, sck in s_coeff.items()}) + self._parity = dict(zip(self.gens(), + parity + (0,) * len(central_elements))) def structure_coefficients(self): """ @@ -293,7 +297,7 @@ def structure_coefficients(self): """ return self._s_coeff - def _repr_generator(self, x): + def _repr_generator(self, x) -> str: """ String representation of the generator ``x``. @@ -316,4 +320,4 @@ def _repr_generator(self, x): """ if x in self: return repr(x) - return IndexedGenerators._repr_generator(self,x) + return IndexedGenerators._repr_generator(self, x) From 7764003a291d1b762431f3a0c03d7db975117fd0 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 11 Jan 2025 10:30:19 +0100 Subject: [PATCH 148/175] use memory allocator in sage/combinat/designs/designs_pyx.pyx --- src/sage/combinat/designs/designs_pyx.pyx | 52 +++++------------------ 1 file changed, 11 insertions(+), 41 deletions(-) diff --git a/src/sage/combinat/designs/designs_pyx.pyx b/src/sage/combinat/designs/designs_pyx.pyx index 99f2d87574b..a3b5297c9a8 100644 --- a/src/sage/combinat/designs/designs_pyx.pyx +++ b/src/sage/combinat/designs/designs_pyx.pyx @@ -11,7 +11,8 @@ from sage.data_structures.bitset_base cimport * from libc.string cimport memset -from cysignals.memory cimport sig_malloc, sig_calloc, sig_realloc, sig_free +from cysignals.memory cimport sig_malloc, sig_realloc, sig_free +from memory_allocator cimport MemoryAllocator from sage.misc.unknown import Unknown @@ -305,7 +306,8 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology='O cdef int i,j,l # A copy of OA - cdef unsigned short * OAc = sig_malloc(k*n2*sizeof(unsigned short)) + cdef MemoryAllocator mem = MemoryAllocator() + cdef unsigned short * OAc = mem.malloc(k*n2*sizeof(unsigned short)) cdef unsigned short * C1 cdef unsigned short * C2 @@ -321,7 +323,6 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology='O if verbose: print({"OA": "{} is not in the interval [0..{}]".format(x,n-1), "MOLS": "Entry {} was expected to be in the interval [0..{}]".format(x,n-1)}[terminology]) - sig_free(OAc) return False OAc[j*n2+i] = x @@ -338,14 +339,12 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology='O bitset_add(seen,n*C1[l]+C2[l]) if bitset_len(seen) != n2: # Have we seen all pairs ? - sig_free(OAc) bitset_free(seen) if verbose: print({"OA": "Columns {} and {} are not orthogonal".format(i,j), "MOLS": "Squares {} and {} are not orthogonal".format(i,j)}[terminology]) return False - sig_free(OAc) bitset_free(seen) return True @@ -469,7 +468,8 @@ def is_group_divisible_design(groups, blocks, v, G=None, K=None, lambd=1, verbos print("{} does not belong to [0,...,{}]".format(x, n-1)) return False - cdef unsigned short * matrix = sig_calloc(n*n, sizeof(unsigned short)) + cdef MemoryAllocator mem = MemoryAllocator() + cdef unsigned short * matrix = mem.calloc(n*n, sizeof(unsigned short)) if matrix is NULL: raise MemoryError @@ -500,7 +500,6 @@ def is_group_divisible_design(groups, blocks, v, G=None, K=None, lambd=1, verbos if not len(g) in G: if verbose: print("a group has size {} while G={}".format(len(g),list(G))) - sig_free(matrix) return False # Checks that two points of the same group were never covered @@ -513,7 +512,6 @@ def is_group_divisible_design(groups, blocks, v, G=None, K=None, lambd=1, verbos if matrix[ii*n+jj] != 0: if verbose: print("the pair ({},{}) belongs to a group but appears in some block".format(ii, jj)) - sig_free(matrix) return False # We fill the entries with what is expected by the next loop @@ -526,11 +524,8 @@ def is_group_divisible_design(groups, blocks, v, G=None, K=None, lambd=1, verbos if matrix[i*n+j] != l: if verbose: print("the pair ({},{}) has been seen {} times but lambda={}".format(i,j,matrix[i*n+j],l)) - sig_free(matrix) return False - sig_free(matrix) - return True if not guess_groups else (True, groups) @@ -836,16 +831,11 @@ 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)) - 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) - sig_free(G_seen) - sig_free(M_c) - raise MemoryError + cdef MemoryAllocator mem = MemoryAllocator() + cdef int ** x_minus_y = mem.malloc((n+1)*sizeof(int *)) + cdef int * x_minus_y_data = mem.malloc((n+1)*(n+1)*sizeof(int)) + cdef int * M_c = mem.malloc(k*M_nrows*sizeof(int)) + cdef int * G_seen = mem.malloc((n+1)*sizeof(int)) # The "x-y" table. If g_i, g_j \in G, then x_minus_y[i][j] is equal to # group_to_int[g_i-g_j]. @@ -883,10 +873,6 @@ def is_quasi_difference_matrix(M, G, int k, int lmbda, int mu, int u, verbose=Fa if bit: if verbose: print("Row {} contains more than one empty entry".format(i)) - sig_free(x_minus_y_data) - sig_free(x_minus_y) - sig_free(G_seen) - sig_free(M_c) return False bit = True @@ -900,10 +886,6 @@ def is_quasi_difference_matrix(M, G, int k, int lmbda, int mu, int u, verbose=Fa if verbose: print("Column {} contains {} empty entries instead of the expected " "lambda.u={}.{}={}".format(j, ii, lmbda, u, lmbda*u)) - sig_free(x_minus_y_data) - sig_free(x_minus_y) - sig_free(G_seen) - sig_free(M_c) return False # We are now ready to test every pair of columns @@ -917,10 +899,6 @@ def is_quasi_difference_matrix(M, G, int k, int lmbda, int mu, int u, verbose=Fa if verbose: print("Columns {} and {} generate 0 exactly {} times " "instead of the expected mu(={})".format(i,j,G_seen[0],mu)) - sig_free(x_minus_y_data) - sig_free(x_minus_y) - sig_free(G_seen) - sig_free(M_c) return False for ii in range(1,n): # bad number of g_ii\in G @@ -929,16 +907,8 @@ def is_quasi_difference_matrix(M, G, int k, int lmbda, int mu, int u, verbose=Fa print("Columns {} and {} do not generate all elements of G " "exactly lambda(={}) times. The element {} appeared {} " "times as a difference.".format(i,j,lmbda,int_to_group[ii],G_seen[ii])) - sig_free(x_minus_y_data) - sig_free(x_minus_y) - sig_free(G_seen) - sig_free(M_c) return False - sig_free(x_minus_y_data) - sig_free(x_minus_y) - sig_free(G_seen) - sig_free(M_c) return True From 597aefd0868f7558a0ac55704f17ff99fe44bde2 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 11 Jan 2025 10:47:20 +0100 Subject: [PATCH 149/175] use memory allocator in sage/combinat/designs/evenly_distributed_sets.pyx --- src/sage/combinat/designs/designs_pyx.pyx | 2 +- .../designs/evenly_distributed_sets.pyx | 38 +++++++++---------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/sage/combinat/designs/designs_pyx.pyx b/src/sage/combinat/designs/designs_pyx.pyx index a3b5297c9a8..be952682e95 100644 --- a/src/sage/combinat/designs/designs_pyx.pyx +++ b/src/sage/combinat/designs/designs_pyx.pyx @@ -471,7 +471,7 @@ def is_group_divisible_design(groups, blocks, v, G=None, K=None, lambd=1, verbos cdef MemoryAllocator mem = MemoryAllocator() cdef unsigned short * matrix = mem.calloc(n*n, sizeof(unsigned short)) if matrix is NULL: - raise MemoryError + raise MemoryError(f"{n}") # Counts the number of occurrences of each pair of points for b in blocks: diff --git a/src/sage/combinat/designs/evenly_distributed_sets.pyx b/src/sage/combinat/designs/evenly_distributed_sets.pyx index 510c73d51df..083ae585055 100644 --- a/src/sage/combinat/designs/evenly_distributed_sets.pyx +++ b/src/sage/combinat/designs/evenly_distributed_sets.pyx @@ -18,14 +18,15 @@ Classes and methods cimport cython -from sage.categories.fields import Fields from libc.limits cimport UINT_MAX from libc.string cimport memset, memcpy - -from cysignals.memory cimport check_malloc, check_calloc, sig_free +from memory_allocator cimport MemoryAllocator from sage.rings.integer cimport smallInteger +from sage.categories.fields import Fields + + cdef class EvenlyDistributedSetsBacktracker: r""" Set of evenly distributed subsets in finite fields. @@ -168,17 +169,11 @@ cdef class EvenlyDistributedSetsBacktracker: cdef unsigned int * cosets # e array: cosets of differences of elts in B cdef unsigned int * t # e array: temporary variable for updates + # MANAGEMENT OF MEMORY + cdef MemoryAllocator mem + def __dealloc__(self): - if self.diff != NULL: - sig_free(self.diff[0]) - sig_free(self.diff) - if self.ratio != NULL: - sig_free(self.ratio[0]) - sig_free(self.ratio) - sig_free(self.min_orb) - sig_free(self.B) - sig_free(self.cosets) - sig_free(self.t) + pass def __init__(self, K, k, up_to_isomorphism=True, check=False): r""" @@ -228,20 +223,21 @@ 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.mem = MemoryAllocator() + self.diff = self.mem.calloc(q, sizeof(unsigned int *)) + self.diff[0] = self.mem.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 = self.mem.calloc(q, sizeof(unsigned int *)) + self.ratio[0] = self.mem.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.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.B = self.mem.malloc(k*sizeof(unsigned int)) + self.min_orb = self.mem.malloc(q*sizeof(unsigned int)) + self.cosets = self.mem.malloc(e*sizeof(unsigned int)) + self.t = self.mem.malloc(e*sizeof(unsigned int)) x = K.multiplicative_generator() list_K = [] From fff86ea0d76827401cb4b4092000e84865857c25 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 11 Jan 2025 11:02:25 +0100 Subject: [PATCH 150/175] fix issue in sage/combinat/designs/designs_pyx.pyx --- src/sage/combinat/designs/designs_pyx.pyx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/combinat/designs/designs_pyx.pyx b/src/sage/combinat/designs/designs_pyx.pyx index be952682e95..571d7e27c35 100644 --- a/src/sage/combinat/designs/designs_pyx.pyx +++ b/src/sage/combinat/designs/designs_pyx.pyx @@ -470,8 +470,6 @@ def is_group_divisible_design(groups, blocks, v, G=None, K=None, lambd=1, verbos cdef MemoryAllocator mem = MemoryAllocator() cdef unsigned short * matrix = mem.calloc(n*n, sizeof(unsigned short)) - if matrix is NULL: - raise MemoryError(f"{n}") # Counts the number of occurrences of each pair of points for b in blocks: From 14d64f9069b22f10600b06c548b47e358a094ec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 11 Jan 2025 17:57:45 +0100 Subject: [PATCH 151/175] fix suggested details --- .../lie_conformal_algebra_with_structure_coefs.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py index 97fc71e09a6..2e7f31cee27 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py @@ -87,9 +87,11 @@ class LieConformalAlgebraWithStructureCoefficients( `\lambda`-brackets of the generators:: sage: betagamma_dict = {('b','a'):{0:{('K',0):1}}} - sage: V = LieConformalAlgebra(QQ, betagamma_dict, names=('a','b'), weights=(1,0), central_elements=('K',)) + sage: V = LieConformalAlgebra(QQ, betagamma_dict, names=('a','b'), + ....: weights=(1,0), central_elements=('K',)) sage: V.category() - Category of H-graded finitely generated Lie conformal algebras with basis over Rational Field + Category of H-graded finitely generated Lie conformal algebras + with basis over Rational Field sage: V.inject_variables() Defining a, b, K sage: a.bracket(b) @@ -150,7 +152,6 @@ def _standardize_s_coeff(s_coeff, index_set, ce, parity=None): # mypair has a pair of generators for mypair, v in s_coeff.items(): # e.g. v = { 0: { (L,2):3, (G,3):1}, 1:{(L,1),2} } - v = s_coeff[mypair] key = tuple(mypair) vals = {} for l in v: @@ -293,7 +294,10 @@ def structure_coefficients(self): Finite family {('L', 'L'): ((0, TL), (1, 2*L), (3, 1/2*C))} sage: lie_conformal_algebras.NeveuSchwarz(QQ).structure_coefficients() - Finite family {('G', 'G'): ((0, 2*L), (2, 2/3*C)), ('G', 'L'): ((0, 1/2*TG), (1, 3/2*G)), ('L', 'G'): ((0, TG), (1, 3/2*G)), ('L', 'L'): ((0, TL), (1, 2*L), (3, 1/2*C))} + Finite family {('G', 'G'): ((0, 2*L), (2, 2/3*C)), + ('G', 'L'): ((0, 1/2*TG), (1, 3/2*G)), + ('L', 'G'): ((0, TG), (1, 3/2*G)), + ('L', 'L'): ((0, TL), (1, 2*L), (3, 1/2*C))} """ return self._s_coeff From 54138041f25381a89b27df894336d0a513e33ceb Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 11 Jan 2025 23:21:21 +0530 Subject: [PATCH 152/175] Edited meson.build --- src/sage/categories/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/categories/meson.build b/src/sage/categories/meson.build index affc2034df2..5b41d52548b 100644 --- a/src/sage/categories/meson.build +++ b/src/sage/categories/meson.build @@ -119,6 +119,7 @@ py.install_sources( 'integral_domains.py', 'isomorphic_objects.py', 'j_trivial_semigroups.py', + 'kahler_algebras.py' 'kac_moody_algebras.py', 'l_trivial_semigroups.py', 'lambda_bracket_algebras.py', From 78dfd703ed97a21039d9a91ce5c042c0aa7edd1f Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 12 Jan 2025 10:02:17 +0530 Subject: [PATCH 153/175] Edited meson.build --- src/sage/categories/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/meson.build b/src/sage/categories/meson.build index 5b41d52548b..b5c6a46f038 100644 --- a/src/sage/categories/meson.build +++ b/src/sage/categories/meson.build @@ -119,8 +119,8 @@ py.install_sources( 'integral_domains.py', 'isomorphic_objects.py', 'j_trivial_semigroups.py', - 'kahler_algebras.py' 'kac_moody_algebras.py', + 'kahler_algebras.py', 'l_trivial_semigroups.py', 'lambda_bracket_algebras.py', 'lambda_bracket_algebras_with_basis.py', From c63b0f179e51d448b7a19ddd93d07177683725cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 12 Jan 2025 14:05:12 +0100 Subject: [PATCH 154/175] fix suggested details --- src/sage/combinat/posets/hasse_diagram.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 8a872fa39ac..5e10563794d 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -2104,11 +2104,13 @@ def orthocomplementations_iterator(self): mt = self.meet_matrix() jn = self.join_matrix() + items = ((e, dual_isomorphism[e]) for e in range(n)) + # Fix following after issue #20727 comps = [[x for x in range(n) if mt[e, x] == 0 and jn[e, x] == n - 1 and x in orbits[orbit_number[dual_e]]] - for e, dual_e in dual_isomorphism.items()] + for e, dual_e in items] # Fitting is done by this recursive function: def recursive_fit(orthocomplements, unbinded): From 415145a00c42176cede5c6daf2ced9d68081b309 Mon Sep 17 00:00:00 2001 From: "Rusydi H. Makarim" Date: Sun, 12 Jan 2025 22:44:56 +0700 Subject: [PATCH 155/175] Implement the chi function --- src/sage/crypto/sboxes.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/sage/crypto/sboxes.py b/src/sage/crypto/sboxes.py index ab0f2759573..5b96eee6ce5 100644 --- a/src/sage/crypto/sboxes.py +++ b/src/sage/crypto/sboxes.py @@ -166,8 +166,10 @@ """ import sys +from sage.all import ZZ, vector, GF from sage.crypto.sbox import SBox from sage.misc.functional import is_odd, is_even +from sage.rings.finite_rings.integer_mod_ring import IntegerModRing def bracken_leander(n): @@ -398,6 +400,37 @@ def monomial_function(n, e): X = R.gen() return SBox(X**e) +def chi(n): + r""" + Return the `\chi` function defined over `\GF{2^n}` used in the nonlinear layer of Keccak and Xoodyak + + INPUT: + + - ``n`` -- size of the S-Box + + EXAMPLES:: + + sage: from sage.crypto.sboxes import chi + sage: chi(3) + (0, 3, 6, 1, 5, 4, 2, 7) + sage: chi(3).is_permutation() + True + sage: chi(4).is_permutation() + False + sage: chi(5) + (0, 9, 18, 11, 5, 12, 22, 15, 10, 3, 24, 1, 13, 4, 30, 7, 20, 21, 6, 23, 17, 16, 2, 19, 26, 27, 8, 25, 29, 28, 14, 31) + """ + Zn = IntegerModRing(n) + table = [0]*(1 << n) + + for x in range(1 << n): + vx = vector(GF(2), ZZ(x).digits(base=2, padto=n)) + vy = [vx[i] + (vx[i+1] + 1)*vx[i+2] for i in Zn] + y = ZZ(vy, base=2) + table[x] = y + + return SBox(table) + # Bijective S-Boxes mapping 9 bits to 9 # ===================================== From 050883a6ea2d47206de3b21ed27d9ab10ca9ab10 Mon Sep 17 00:00:00 2001 From: "Rusydi H. Makarim" Date: Mon, 13 Jan 2025 10:20:55 +0700 Subject: [PATCH 156/175] Update chi implementation --- src/sage/crypto/sboxes.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/crypto/sboxes.py b/src/sage/crypto/sboxes.py index 5b96eee6ce5..3e1b7f8b707 100644 --- a/src/sage/crypto/sboxes.py +++ b/src/sage/crypto/sboxes.py @@ -166,10 +166,11 @@ """ import sys -from sage.all import ZZ, vector, GF +from sage.rings.integer_ring import ZZ +from sage.rings.finite_rings.finite_field_constructor import GF +from sage.modules.free_module_element import vector from sage.crypto.sbox import SBox from sage.misc.functional import is_odd, is_even -from sage.rings.finite_rings.integer_mod_ring import IntegerModRing def bracken_leander(n): @@ -402,7 +403,7 @@ def monomial_function(n, e): def chi(n): r""" - Return the `\chi` function defined over `\GF{2^n}` used in the nonlinear layer of Keccak and Xoodyak + Return the `\chi` function defined over `\GF{2^n}` used in the nonlinear layer of Keccak and Xoodyak. INPUT: @@ -420,12 +421,11 @@ def chi(n): sage: chi(5) (0, 9, 18, 11, 5, 12, 22, 15, 10, 3, 24, 1, 13, 4, 30, 7, 20, 21, 6, 23, 17, 16, 2, 19, 26, 27, 8, 25, 29, 28, 14, 31) """ - Zn = IntegerModRing(n) table = [0]*(1 << n) for x in range(1 << n): vx = vector(GF(2), ZZ(x).digits(base=2, padto=n)) - vy = [vx[i] + (vx[i+1] + 1)*vx[i+2] for i in Zn] + vy = [vx[i] + (vx[(i+1) % n] + 1)*vx[(i+2) % n] for i in range(n)] y = ZZ(vy, base=2) table[x] = y From 8eab3619bb9685f55e717359b186de4b89a5186e Mon Sep 17 00:00:00 2001 From: "Rusydi H. Makarim" Date: Mon, 13 Jan 2025 10:33:09 +0700 Subject: [PATCH 157/175] Fix newline issue --- src/sage/crypto/sboxes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/crypto/sboxes.py b/src/sage/crypto/sboxes.py index 3e1b7f8b707..4fcc38b5797 100644 --- a/src/sage/crypto/sboxes.py +++ b/src/sage/crypto/sboxes.py @@ -401,6 +401,7 @@ def monomial_function(n, e): X = R.gen() return SBox(X**e) + def chi(n): r""" Return the `\chi` function defined over `\GF{2^n}` used in the nonlinear layer of Keccak and Xoodyak. From 3d01c522b6f56f42f4c70fbe12bf655b432fba40 Mon Sep 17 00:00:00 2001 From: "Rusydi H. Makarim" Date: Mon, 13 Jan 2025 13:31:35 +0700 Subject: [PATCH 158/175] PEP8 fix --- src/sage/crypto/sboxes.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/crypto/sboxes.py b/src/sage/crypto/sboxes.py index 4fcc38b5797..b61117cd2fd 100644 --- a/src/sage/crypto/sboxes.py +++ b/src/sage/crypto/sboxes.py @@ -404,7 +404,8 @@ def monomial_function(n, e): def chi(n): r""" - Return the `\chi` function defined over `\GF{2^n}` used in the nonlinear layer of Keccak and Xoodyak. + Return the `\chi` function defined over `\GF{2^n}` used in the nonlinear + layer of Keccak and Xoodyak. INPUT: @@ -420,7 +421,8 @@ def chi(n): sage: chi(4).is_permutation() False sage: chi(5) - (0, 9, 18, 11, 5, 12, 22, 15, 10, 3, 24, 1, 13, 4, 30, 7, 20, 21, 6, 23, 17, 16, 2, 19, 26, 27, 8, 25, 29, 28, 14, 31) + (0, 9, 18, 11, 5, 12, 22, 15, 10, 3, 24, 1, 13, 4, 30, 7, 20, 21, 6, + 23, 17, 16, 2, 19, 26, 27, 8, 25, 29, 28, 14, 31) """ table = [0]*(1 << n) From e85cf3aae28b7b04bb6fd59506c27b59392495e1 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Mon, 13 Jan 2025 08:37:56 +0100 Subject: [PATCH 159/175] #39312: remove dealloc --- src/sage/coding/binary_code.pyx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index f7e87d8257e..023410b99fc 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -3043,9 +3043,6 @@ cdef class BinaryCodeClassifier: self.v = self.mem.malloc(self.radix * 2 * sizeof(int)) self.e = self.mem.malloc(self.radix * 2 * sizeof(int)) - def __dealloc__(self): - pass - cdef void record_automorphism(self, int *gamma, int ncols) noexcept: cdef int i, j if self.aut_gp_index + ncols > self.aut_gens_size: From 5b5e7bca62ac8f4923487093aad690f791455496 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Mon, 13 Jan 2025 08:42:36 +0100 Subject: [PATCH 160/175] #39316: remove dealloc --- src/sage/combinat/designs/evenly_distributed_sets.pyx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sage/combinat/designs/evenly_distributed_sets.pyx b/src/sage/combinat/designs/evenly_distributed_sets.pyx index 083ae585055..61b44cc5da1 100644 --- a/src/sage/combinat/designs/evenly_distributed_sets.pyx +++ b/src/sage/combinat/designs/evenly_distributed_sets.pyx @@ -172,9 +172,6 @@ cdef class EvenlyDistributedSetsBacktracker: # MANAGEMENT OF MEMORY cdef MemoryAllocator mem - def __dealloc__(self): - pass - def __init__(self, K, k, up_to_isomorphism=True, check=False): r""" TESTS:: From fa64c38951161c1b967151c6ea6e2df511074954 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Mon, 13 Jan 2025 08:44:52 +0100 Subject: [PATCH 161/175] #39312: remove another dealloc --- src/sage/coding/binary_code.pyx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index 023410b99fc..f7fa6898864 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -825,9 +825,6 @@ cdef class BinaryCode: for combination from 0 <= combination < other_nwords: self_words[combination+other_nwords] = self_words[combination] ^ glue_word - def __dealloc__(self): - pass - def __reduce__(self): """ Method for pickling and unpickling BinaryCodes. From f1b62451571cf0efee024fba97ffc44366a62184 Mon Sep 17 00:00:00 2001 From: "Rusydi H. Makarim" Date: Mon, 13 Jan 2025 15:19:48 +0700 Subject: [PATCH 162/175] Move import statements inside function body --- src/sage/crypto/sboxes.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/crypto/sboxes.py b/src/sage/crypto/sboxes.py index b61117cd2fd..d60d2fa064a 100644 --- a/src/sage/crypto/sboxes.py +++ b/src/sage/crypto/sboxes.py @@ -166,9 +166,6 @@ """ import sys -from sage.rings.integer_ring import ZZ -from sage.rings.finite_rings.finite_field_constructor import GF -from sage.modules.free_module_element import vector from sage.crypto.sbox import SBox from sage.misc.functional import is_odd, is_even @@ -424,6 +421,10 @@ def chi(n): (0, 9, 18, 11, 5, 12, 22, 15, 10, 3, 24, 1, 13, 4, 30, 7, 20, 21, 6, 23, 17, 16, 2, 19, 26, 27, 8, 25, 29, 28, 14, 31) """ + from sage.rings.integer_ring import ZZ + from sage.rings.finite_rings.finite_field_constructor import GF + from sage.modules.free_module_element import vector + table = [0]*(1 << n) for x in range(1 << n): From 03bb2883b709fdb53943c41f369e1e454672cf1c Mon Sep 17 00:00:00 2001 From: "Rusydi H. Makarim" Date: Mon, 13 Jan 2025 15:26:29 +0700 Subject: [PATCH 163/175] Update sboxes.py --- src/sage/crypto/sboxes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/crypto/sboxes.py b/src/sage/crypto/sboxes.py index d60d2fa064a..1e7911364a8 100644 --- a/src/sage/crypto/sboxes.py +++ b/src/sage/crypto/sboxes.py @@ -424,7 +424,7 @@ def chi(n): from sage.rings.integer_ring import ZZ from sage.rings.finite_rings.finite_field_constructor import GF from sage.modules.free_module_element import vector - + table = [0]*(1 << n) for x in range(1 << n): From 46ff10fed3f5964ac2a41d7bceeab6551e4b3fe1 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Mon, 13 Jan 2025 10:46:59 +0100 Subject: [PATCH 164/175] #39312: remove yet another dealloc --- src/sage/coding/binary_code.pyx | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index f7fa6898864..f2eb22c046a 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -1291,9 +1291,6 @@ cdef class OrbitPartition: self.col_min_cell_rep[col] = col self.col_size[col] = 1 - def __dealloc__(self): - pass - def __repr__(self): """ Return a string representation of the orbit partition. @@ -2976,17 +2973,12 @@ cdef class PartitionStack: ([0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 8, 9, 10, 11], [0, 1, 2, 3, 5, 4, 7, 6]) """ cdef int i - cdef int *word_g = sig_malloc( self.nwords * sizeof(int) ) - cdef int *col_g = sig_malloc( self.ncols * sizeof(int) ) - if word_g is NULL or col_g is NULL: - if word_g is not NULL: sig_free(word_g) - if col_g is not NULL: sig_free(col_g) - raise MemoryError("Memory.") + cdef MemoryAllocator loc_mem = MemoryAllocator() + cdef int *word_g = loc_mem.malloc(self.nwords * sizeof(int)) + cdef int *col_g = loc_mem.malloc(self.ncols * sizeof(int)) self.get_permutation(other, word_g, col_g) word_l = [word_g[i] for i from 0 <= i < self.nwords] col_l = [col_g[i] for i from 0 <= i < self.ncols] - sig_free(word_g) - sig_free(col_g) return word_l, col_l cdef void get_permutation(self, PartitionStack other, int *word_gamma, int *col_gamma) noexcept: From e4710a2c55bc753fb3acef3e6474619e6921ea80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 13 Jan 2025 14:36:48 +0100 Subject: [PATCH 165/175] less use of ParentWithGens --- src/sage/rings/fraction_field_element.pyx | 6 +++--- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 5 +---- src/sage/rings/quotient_ring.py | 5 ++--- src/sage/rings/ring.pyx | 2 -- src/sage/structure/element.pyx | 6 +++--- 5 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/sage/rings/fraction_field_element.pyx b/src/sage/rings/fraction_field_element.pyx index bd8718da968..c8c91e88808 100644 --- a/src/sage/rings/fraction_field_element.pyx +++ b/src/sage/rings/fraction_field_element.pyx @@ -348,9 +348,9 @@ cdef class FractionFieldElement(FieldElement): This function hashes in a special way to ensure that generators of a ring `R` and generators of a fraction field of `R` have the same hash. This enables them to be used as keys interchangeably in a - dictionary (since ``==`` will claim them equal). This is particularly - useful for methods like ``subs`` on ``ParentWithGens`` if you are - passing a dictionary of substitutions. + dictionary (since ``==`` will claim them equal). + + This is useful for substitution using dicts. EXAMPLES:: diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 3f963e28cb7..8baa8b40b24 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -90,14 +90,11 @@ cdef class MPolynomialRing_base(CommutativeRing): self._term_order = order self._has_singular = False # cannot convert to Singular by default self._magma_cache = {} - # Ring.__init__ already does assign the names. - # It would be a mistake to call ParentWithGens.__init__ - # as well, assigning the names twice. - # ParentWithGens.__init__(self, base_ring, names) if base_ring.is_zero(): category = categories.rings.Rings().Finite() else: category = polynomial_default_category(base_ring.category(), n) + # Ring.__init__ assigns the names. Ring.__init__(self, base_ring, names, category=category) from sage.combinat.integer_vector import IntegerVectors self._indices = IntegerVectors(self._ngens) diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index 7e3dd8c6d53..1def443ec1e 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -383,7 +383,7 @@ def is_QuotientRing(x): @richcmp_method -class QuotientRing_nc(ring.Ring, sage.structure.parent_gens.ParentWithGens): +class QuotientRing_nc(ring.Ring): """ The quotient ring of `R` by a twosided ideal `I`. @@ -495,8 +495,7 @@ def __init__(self, R, I, names, category=None): raise TypeError("The second argument must be an ideal of the given ring, but %s is not" % I) self.__R = R self.__I = I - #sage.structure.parent_gens.ParentWithGens.__init__(self, R.base_ring(), names) - ## + # Unfortunately, computing the join of categories, which is done in # check_default_category, is very expensive. # However, we don't just want to use the given category without mixing in diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index 0891853efba..e6c64296e15 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -253,8 +253,6 @@ cdef class Ring(ParentWithGens): # yield an infinite recursion. But when we call it from here, it works. # This is done in order to ensure that __init_extra__ is called. # - # ParentWithGens.__init__(self, base, names=names, normalize=normalize) - # # This is a low-level class. For performance, we trust that the category # is fine, if it is provided. If it isn't, we use the category of rings. if category is None: diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 9fd976fdfc7..f8faa8a7737 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -817,9 +817,9 @@ cdef class Element(SageObject): ngens = parent.ngens() except (AttributeError, NotImplementedError, TypeError): return self - variables=[] - # use "gen" instead of "gens" as a ParentWithGens is not - # required to have the latter + variables = [] + + # using gen instead of gens for i in range(ngens): gen = parent.gen(i) if str(gen) in kwds: From ac5a31e714938f7d3955fc11aa702de72184956a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Tue, 14 Jan 2025 12:19:12 +0100 Subject: [PATCH 166/175] src/doc/**/conf.py: let a_tour_of_sage.pdf wrap long decimal expansions --- src/doc/de/a_tour_of_sage/conf.py | 6 ++++++ src/doc/el/a_tour_of_sage/conf.py | 6 ++++++ src/doc/en/a_tour_of_sage/conf.py | 6 ++++++ src/doc/es/a_tour_of_sage/conf.py | 6 ++++++ src/doc/fr/a_tour_of_sage/conf.py | 8 +++++--- src/doc/hu/a_tour_of_sage/conf.py | 6 ++++++ src/doc/it/a_tour_of_sage/conf.py | 11 +++++++++-- src/doc/ja/a_tour_of_sage/conf.py | 6 ++++++ src/doc/pt/a_tour_of_sage/conf.py | 6 ++++++ src/doc/tr/a_tour_of_sage/conf.py | 6 ++++++ 10 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/doc/de/a_tour_of_sage/conf.py b/src/doc/de/a_tour_of_sage/conf.py index fb960f06ffd..d3a34a85e5f 100644 --- a/src/doc/de/a_tour_of_sage/conf.py +++ b/src/doc/de/a_tour_of_sage/conf.py @@ -52,3 +52,9 @@ ("index", name + ".tex", "Ein Rundgang durch Sage", "The Sage Development Team", "manual"), ] + +# PDF output: let long decimal expansions in code-blocks wrap rather than +# overflow beyond page margin +latex_elements = { + 'sphinxsetup': 'verbatimforcewraps=true', +} diff --git a/src/doc/el/a_tour_of_sage/conf.py b/src/doc/el/a_tour_of_sage/conf.py index ff4e9436313..8d3eba858ed 100644 --- a/src/doc/el/a_tour_of_sage/conf.py +++ b/src/doc/el/a_tour_of_sage/conf.py @@ -49,3 +49,9 @@ ('index', name + '.tex', project, 'The Sage Development Team', 'manual'), ] + +# PDF output: let long decimal expansions in code-blocks wrap rather than +# overflow beyond page margin +latex_elements = { + 'sphinxsetup': 'verbatimforcewraps=true', +} diff --git a/src/doc/en/a_tour_of_sage/conf.py b/src/doc/en/a_tour_of_sage/conf.py index 689eed59af3..ed452f2938c 100644 --- a/src/doc/en/a_tour_of_sage/conf.py +++ b/src/doc/en/a_tour_of_sage/conf.py @@ -48,3 +48,9 @@ ('index', 'a_tour_of_sage.tex', 'A Tour Of Sage', 'The Sage Development Team', 'manual'), ] + +# PDF output: let long decimal expansions in code-blocks wrap rather than +# overflow beyond page margin +latex_elements = { + 'sphinxsetup': 'verbatimforcewraps=true', +} diff --git a/src/doc/es/a_tour_of_sage/conf.py b/src/doc/es/a_tour_of_sage/conf.py index 801f7cadb95..eb73443fa60 100644 --- a/src/doc/es/a_tour_of_sage/conf.py +++ b/src/doc/es/a_tour_of_sage/conf.py @@ -54,3 +54,9 @@ 'A Tour Of Sage', 'The Sage Development Team', 'manual')] + +# PDF output: let long decimal expansions in code-blocks wrap rather than +# overflow beyond page margin +latex_elements = { + 'sphinxsetup': 'verbatimforcewraps=true', +} diff --git a/src/doc/fr/a_tour_of_sage/conf.py b/src/doc/fr/a_tour_of_sage/conf.py index 9cca4b7d1f8..44b567b6ccb 100644 --- a/src/doc/fr/a_tour_of_sage/conf.py +++ b/src/doc/fr/a_tour_of_sage/conf.py @@ -50,6 +50,8 @@ 'The Sage Development Team', 'manual'), ] -# the definition of \\at in the standard preamble of the sphinx doc -# conflicts with that in babel/french[b] -latex_elements['preamble'] += '\\let\\at\\undefined' +# PDF output: let long decimal expansions in code-blocks wrap rather than +# overflow beyond page margin +latex_elements = { + 'sphinxsetup': 'verbatimforcewraps=true', +} diff --git a/src/doc/hu/a_tour_of_sage/conf.py b/src/doc/hu/a_tour_of_sage/conf.py index 2e5215fcf5d..81cc815ad96 100644 --- a/src/doc/hu/a_tour_of_sage/conf.py +++ b/src/doc/hu/a_tour_of_sage/conf.py @@ -53,3 +53,9 @@ ('index', name + '.tex', 'A Tour Of Sage', 'The Sage Development Team', 'manual'), ] + +# PDF output: let long decimal expansions in code-blocks wrap rather than +# overflow beyond page margin +latex_elements = { + 'sphinxsetup': 'verbatimforcewraps=true', +} diff --git a/src/doc/it/a_tour_of_sage/conf.py b/src/doc/it/a_tour_of_sage/conf.py index 48a568cc4d1..b57654feb5a 100644 --- a/src/doc/it/a_tour_of_sage/conf.py +++ b/src/doc/it/a_tour_of_sage/conf.py @@ -51,12 +51,19 @@ 'The Sage Development Team', 'manual'), ] + +# PDF output: let long decimal expansions in code-blocks wrap rather than +# overflow beyond page margin +latex_elements = { + 'sphinxsetup': 'verbatimforcewraps=true', +# TODO: check if the following is valid currently # Our Sphinx expects the older behavior of babel-italian where double # quotes are active -latex_elements['preamble'] += r""" + 'preamble': r""" % old babel-italian does not have setactivedoublequote, % avoid "undefined control sequence" error \providecommand{\setactivedoublequote}{} % switch new babel-italian to the old behavior \setactivedoublequote -""" +""", +} diff --git a/src/doc/ja/a_tour_of_sage/conf.py b/src/doc/ja/a_tour_of_sage/conf.py index eef0eba83b3..0129cb3db2f 100644 --- a/src/doc/ja/a_tour_of_sage/conf.py +++ b/src/doc/ja/a_tour_of_sage/conf.py @@ -53,3 +53,9 @@ ('index', name + '.tex', project, 'The Sage Group', 'manual'), ] + +# PDF output: let long decimal expansions in code-blocks wrap rather than +# overflow beyond page margin +latex_elements = { + 'sphinxsetup': 'verbatimforcewraps=true', +} diff --git a/src/doc/pt/a_tour_of_sage/conf.py b/src/doc/pt/a_tour_of_sage/conf.py index 806bc1b77c8..5a15b93b6ab 100644 --- a/src/doc/pt/a_tour_of_sage/conf.py +++ b/src/doc/pt/a_tour_of_sage/conf.py @@ -50,3 +50,9 @@ ('index', name + '.tex', 'A Tour Of Sage', 'The Sage Development Team', 'manual'), ] + +# PDF output: let long decimal expansions in code-blocks wrap rather than +# overflow beyond page margin +latex_elements = { + 'sphinxsetup': 'verbatimforcewraps=true', +} diff --git a/src/doc/tr/a_tour_of_sage/conf.py b/src/doc/tr/a_tour_of_sage/conf.py index 9d2a503d78d..9f01d2219ec 100644 --- a/src/doc/tr/a_tour_of_sage/conf.py +++ b/src/doc/tr/a_tour_of_sage/conf.py @@ -49,3 +49,9 @@ ('index', name + '.tex', 'Sage Turu', 'The Sage Development Team', 'manual'), ] + +# PDF output: let long decimal expansions in code-blocks wrap rather than +# overflow beyond page margin +latex_elements = { + 'sphinxsetup': 'verbatimforcewraps=true', +} From 9bbd06eada82e98ebc9114292e96c99e4ee0caea Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Tue, 14 Jan 2025 12:19:22 -0700 Subject: [PATCH 167/175] No need for list creation --- src/sage/graphs/graph_plot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 6b968128849..17a056ddaf6 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -753,9 +753,9 @@ def set_edges(self, **edge_options): style_key_edges = None thickness_key_edges = None if isinstance(self._options['edge_styles'], dict): - style_key_edges = list(self._options['edge_styles'])[0] in self._graph.edges() + style_key_edges = next(iter(self._options['edge_styles'])) in self._graph.edges() if isinstance(self._options['edge_thicknesses'], dict): - thickness_key_edges = list(self._options['edge_thicknesses'])[0] in self._graph.edges() + thickness_key_edges = next(iter(self._options['edge_thicknesses'])) in self._graph.edges() eoptions = {} if 'arrowsize' in self._options: From b75aca871be729a89219e27d7711efd451566830 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian Date: Tue, 14 Jan 2025 17:07:28 -0700 Subject: [PATCH 168/175] Add doctests --- src/sage/graphs/graph_plot.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 17a056ddaf6..5102c92120d 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -1480,12 +1480,12 @@ def plot(self, **kwds): :: sage: D = DiGraph({0:[1,2,3], 2:[1,4], 3:[0]}) - sage: D.graphplot(label_fontsize=20).show() + sage: D.graphplot(label_fontsize=20, arrowsize=10).show() .. PLOT:: D = DiGraph({0:[1,2,3], 2:[1,4], 3:[0]}) - sphinx_plot(D.graphplot(label_fontsize=20)) + sphinx_plot(D.graphplot(label_fontsize=20, arrowsize=10)) :: @@ -1565,6 +1565,31 @@ def plot(self, **kwds): GP.set_edges(edge_styles={'a':'dashed', 'g':'dotted'}) sphinx_plot(GP) + :: + + sage: g = Graph(loops=True, multiedges=True, sparse=True) + sage: g.add_edges([(0, 0, 'a'), (0, 0, 'b'), (0, 1, 'c'), + ....: (0, 1, 'd'), (0, 1, 'e'), (0, 1, 'f'), + ....: (0, 1, 'f'), (2, 1, 'g'), (2, 2, 'h')]) + sage: GP = g.graphplot(vertex_size=100, edge_labels=True, + ....: color_by_label=True, edge_thickness=3) + sage: GP.set_edges(edge_thicknesses={'a':1, 'g':5}) + sage: GP.plot() + Graphics object consisting of 22 graphics primitives + + .. PLOT:: + + g = Graph(loops=True, multiedges=True, sparse=True) + g.add_edges([(0, 0, 'a'), (0, 0, 'b'), (0, 1, 'c'), + (0, 1, 'd'), (0, 1, 'e'), (0, 1, 'f'), + (0, 1, 'f'), (2, 1, 'g'), (2, 2, 'h')]) + GP = g.graphplot(vertex_size=100, edge_labels=True, + color_by_label=True, edge_thickness=3) + GP.set_edges(edge_style='solid') + GP.set_edges(edge_color='black') + GP.set_edges(edge_thicknesses={'a':1, 'g':5}) + sphinx_plot(GP) + TESTS: Make sure that show options work with plot also:: From 84bcce6b456720fe50c897a3e6d17a1f4e9fa767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:58:01 +0100 Subject: [PATCH 169/175] Revert "src/doc/**/conf.py: let a_tour_of_sage.pdf wrap long decimal expansions" This reverts commit ac5a31e714938f7d3955fc11aa702de72184956a. --- src/doc/de/a_tour_of_sage/conf.py | 6 ------ src/doc/el/a_tour_of_sage/conf.py | 6 ------ src/doc/en/a_tour_of_sage/conf.py | 6 ------ src/doc/es/a_tour_of_sage/conf.py | 6 ------ src/doc/fr/a_tour_of_sage/conf.py | 8 +++----- src/doc/hu/a_tour_of_sage/conf.py | 6 ------ src/doc/it/a_tour_of_sage/conf.py | 11 ++--------- src/doc/ja/a_tour_of_sage/conf.py | 6 ------ src/doc/pt/a_tour_of_sage/conf.py | 6 ------ src/doc/tr/a_tour_of_sage/conf.py | 6 ------ 10 files changed, 5 insertions(+), 62 deletions(-) diff --git a/src/doc/de/a_tour_of_sage/conf.py b/src/doc/de/a_tour_of_sage/conf.py index d3a34a85e5f..fb960f06ffd 100644 --- a/src/doc/de/a_tour_of_sage/conf.py +++ b/src/doc/de/a_tour_of_sage/conf.py @@ -52,9 +52,3 @@ ("index", name + ".tex", "Ein Rundgang durch Sage", "The Sage Development Team", "manual"), ] - -# PDF output: let long decimal expansions in code-blocks wrap rather than -# overflow beyond page margin -latex_elements = { - 'sphinxsetup': 'verbatimforcewraps=true', -} diff --git a/src/doc/el/a_tour_of_sage/conf.py b/src/doc/el/a_tour_of_sage/conf.py index 8d3eba858ed..ff4e9436313 100644 --- a/src/doc/el/a_tour_of_sage/conf.py +++ b/src/doc/el/a_tour_of_sage/conf.py @@ -49,9 +49,3 @@ ('index', name + '.tex', project, 'The Sage Development Team', 'manual'), ] - -# PDF output: let long decimal expansions in code-blocks wrap rather than -# overflow beyond page margin -latex_elements = { - 'sphinxsetup': 'verbatimforcewraps=true', -} diff --git a/src/doc/en/a_tour_of_sage/conf.py b/src/doc/en/a_tour_of_sage/conf.py index ed452f2938c..689eed59af3 100644 --- a/src/doc/en/a_tour_of_sage/conf.py +++ b/src/doc/en/a_tour_of_sage/conf.py @@ -48,9 +48,3 @@ ('index', 'a_tour_of_sage.tex', 'A Tour Of Sage', 'The Sage Development Team', 'manual'), ] - -# PDF output: let long decimal expansions in code-blocks wrap rather than -# overflow beyond page margin -latex_elements = { - 'sphinxsetup': 'verbatimforcewraps=true', -} diff --git a/src/doc/es/a_tour_of_sage/conf.py b/src/doc/es/a_tour_of_sage/conf.py index eb73443fa60..801f7cadb95 100644 --- a/src/doc/es/a_tour_of_sage/conf.py +++ b/src/doc/es/a_tour_of_sage/conf.py @@ -54,9 +54,3 @@ 'A Tour Of Sage', 'The Sage Development Team', 'manual')] - -# PDF output: let long decimal expansions in code-blocks wrap rather than -# overflow beyond page margin -latex_elements = { - 'sphinxsetup': 'verbatimforcewraps=true', -} diff --git a/src/doc/fr/a_tour_of_sage/conf.py b/src/doc/fr/a_tour_of_sage/conf.py index 44b567b6ccb..9cca4b7d1f8 100644 --- a/src/doc/fr/a_tour_of_sage/conf.py +++ b/src/doc/fr/a_tour_of_sage/conf.py @@ -50,8 +50,6 @@ 'The Sage Development Team', 'manual'), ] -# PDF output: let long decimal expansions in code-blocks wrap rather than -# overflow beyond page margin -latex_elements = { - 'sphinxsetup': 'verbatimforcewraps=true', -} +# the definition of \\at in the standard preamble of the sphinx doc +# conflicts with that in babel/french[b] +latex_elements['preamble'] += '\\let\\at\\undefined' diff --git a/src/doc/hu/a_tour_of_sage/conf.py b/src/doc/hu/a_tour_of_sage/conf.py index 81cc815ad96..2e5215fcf5d 100644 --- a/src/doc/hu/a_tour_of_sage/conf.py +++ b/src/doc/hu/a_tour_of_sage/conf.py @@ -53,9 +53,3 @@ ('index', name + '.tex', 'A Tour Of Sage', 'The Sage Development Team', 'manual'), ] - -# PDF output: let long decimal expansions in code-blocks wrap rather than -# overflow beyond page margin -latex_elements = { - 'sphinxsetup': 'verbatimforcewraps=true', -} diff --git a/src/doc/it/a_tour_of_sage/conf.py b/src/doc/it/a_tour_of_sage/conf.py index b57654feb5a..48a568cc4d1 100644 --- a/src/doc/it/a_tour_of_sage/conf.py +++ b/src/doc/it/a_tour_of_sage/conf.py @@ -51,19 +51,12 @@ 'The Sage Development Team', 'manual'), ] - -# PDF output: let long decimal expansions in code-blocks wrap rather than -# overflow beyond page margin -latex_elements = { - 'sphinxsetup': 'verbatimforcewraps=true', -# TODO: check if the following is valid currently # Our Sphinx expects the older behavior of babel-italian where double # quotes are active - 'preamble': r""" +latex_elements['preamble'] += r""" % old babel-italian does not have setactivedoublequote, % avoid "undefined control sequence" error \providecommand{\setactivedoublequote}{} % switch new babel-italian to the old behavior \setactivedoublequote -""", -} +""" diff --git a/src/doc/ja/a_tour_of_sage/conf.py b/src/doc/ja/a_tour_of_sage/conf.py index 0129cb3db2f..eef0eba83b3 100644 --- a/src/doc/ja/a_tour_of_sage/conf.py +++ b/src/doc/ja/a_tour_of_sage/conf.py @@ -53,9 +53,3 @@ ('index', name + '.tex', project, 'The Sage Group', 'manual'), ] - -# PDF output: let long decimal expansions in code-blocks wrap rather than -# overflow beyond page margin -latex_elements = { - 'sphinxsetup': 'verbatimforcewraps=true', -} diff --git a/src/doc/pt/a_tour_of_sage/conf.py b/src/doc/pt/a_tour_of_sage/conf.py index 5a15b93b6ab..806bc1b77c8 100644 --- a/src/doc/pt/a_tour_of_sage/conf.py +++ b/src/doc/pt/a_tour_of_sage/conf.py @@ -50,9 +50,3 @@ ('index', name + '.tex', 'A Tour Of Sage', 'The Sage Development Team', 'manual'), ] - -# PDF output: let long decimal expansions in code-blocks wrap rather than -# overflow beyond page margin -latex_elements = { - 'sphinxsetup': 'verbatimforcewraps=true', -} diff --git a/src/doc/tr/a_tour_of_sage/conf.py b/src/doc/tr/a_tour_of_sage/conf.py index 9f01d2219ec..9d2a503d78d 100644 --- a/src/doc/tr/a_tour_of_sage/conf.py +++ b/src/doc/tr/a_tour_of_sage/conf.py @@ -49,9 +49,3 @@ ('index', name + '.tex', 'Sage Turu', 'The Sage Development Team', 'manual'), ] - -# PDF output: let long decimal expansions in code-blocks wrap rather than -# overflow beyond page margin -latex_elements = { - 'sphinxsetup': 'verbatimforcewraps=true', -} From 4e0e9a83f7eca36273650c200a6d193ead63bcbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Wed, 15 Jan 2025 19:18:31 +0100 Subject: [PATCH 170/175] Add 'verbatimforcewraps=true' to LaTeX sage_docbuild/conf.py --- src/sage_docbuild/conf.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py index 6c8f2d923e9..dab2531bac3 100644 --- a/src/sage_docbuild/conf.py +++ b/src/sage_docbuild/conf.py @@ -647,6 +647,11 @@ def linkcode_resolve(domain, info): \makeatother """ +# Enable "hard wrapping" long code lines (only applies if breaking +# long codelines at spaces or other suitable places failed, typically +# this is for long decimal expansions or possibly long string identifiers) +latex_elements['sphinxsetup'] = "verbatimforcewraps=true" + # Documents to append as an appendix to all manuals. # latex_appendices = [] From c823039e01f8740866a1869cf459c6c31ba67f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 15 Jan 2025 20:40:41 +0100 Subject: [PATCH 171/175] fix a bunch of typos and add some spaces after commas --- src/sage/algebras/fusion_rings/f_matrix.py | 2 +- src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py | 4 ++-- src/sage/homology/homology_vector_space_with_basis.py | 4 ++-- src/sage/rings/complex_interval.pyx | 2 +- src/sage/rings/polynomial/polynomial_element.pyx | 2 +- src/sage/schemes/elliptic_curves/ell_number_field.py | 7 ++++--- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/sage/algebras/fusion_rings/f_matrix.py b/src/sage/algebras/fusion_rings/f_matrix.py index b832a520fec..e48a89fc664 100644 --- a/src/sage/algebras/fusion_rings/f_matrix.py +++ b/src/sage/algebras/fusion_rings/f_matrix.py @@ -1991,7 +1991,7 @@ def _get_explicit_solution(self, eqns=None, verbose=True): def find_orthogonal_solution(self, checkpoint=False, save_results='', warm_start='', use_mp=True, verbose=True): r""" - Solve the the hexagon and pentagon relations, along with + Solve the hexagon and pentagon relations, along with orthogonality constraints, to evaluate an orthogonal F-matrix. INPUT: diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py index 9aa6fa63ff2..5ee2125a510 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py @@ -352,7 +352,7 @@ def matrix(self, subdivide=False, representation_type=None, original=False): [(-2*a + u)*b - 2*a^2 + 2*u*a - v b 0] [ b 1 a] - using the the ``representation_type`` option:: + using the ``representation_type`` option:: sage: CHA3. = algebras.CubicHecke(3) # optional gap3 sage: chevie = CHA3.repr_type.SplitIrredChevie # optional gap3 @@ -364,7 +364,7 @@ def matrix(self, subdivide=False, representation_type=None, original=False): [ b 0] [a^2 - u*a + v -b - a + u] - using the the ``original`` option:: + using the ``original`` option:: sage: c0mo = c0.matrix(original=True) sage: c0mo_ch = c0.matrix(representation_type=chevie, original=True) # optional gap3 diff --git a/src/sage/homology/homology_vector_space_with_basis.py b/src/sage/homology/homology_vector_space_with_basis.py index ee30f144282..977968fdcb3 100644 --- a/src/sage/homology/homology_vector_space_with_basis.py +++ b/src/sage/homology/homology_vector_space_with_basis.py @@ -1253,7 +1253,7 @@ def _acted_upon_(self, a, self_on_left): ret = CombinatorialFreeModule.Element._acted_upon_(self, a, self_on_left) if ret is not None: # did the scalar action return ret - if self_on_left: # i.e., module element on left + if self_on_left: # i.e., module element on left a = a.antipode() b = a.change_basis('adem') ans = self.parent().zero() @@ -1283,7 +1283,7 @@ def steenrod_module_map(self, deg_domain, deg_codomain, side='left'): the action as a left module action or a right module We will write this with respect to the left action; - for the right action, just switch all of the the tensors. + for the right action, just switch all of the tensors. Writing `m` for ``deg_domain`` and `n` for ``deg_codomain``, this returns `A^{n-m} \otimes H^{m} \to H^{n}`, one single component of the map making `H` into an `A`-module. diff --git a/src/sage/rings/complex_interval.pyx b/src/sage/rings/complex_interval.pyx index c050d794055..4fd7e6bbcf3 100644 --- a/src/sage/rings/complex_interval.pyx +++ b/src/sage/rings/complex_interval.pyx @@ -2237,7 +2237,7 @@ cdef _circle_invert_standard( # Consider the images # f(xmin + ymin * I), ..., f(xmax + ymax * I) # of the four corners of the input rect under inversion f. - # Now consider the the axis-parallel rectangle R that these images span. + # Now consider the axis-parallel rectangle R that these images span. # In general, the image of the input rect might not be contained in R. # In case 1, however, (and only in case 1) it is and we furthermore know # which image is mapped to which edge of R. Thus, we have: diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 3c057d49a6f..b8445edeb20 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -2280,7 +2280,7 @@ cdef class Polynomial(CommutativePolynomial): - ``degree`` -- ``None`` or positive integer (default: ``None``). Used for polynomials over finite fields. If ``None``, returns - the the first factor found (usually the smallest). Otherwise, + the first factor found (usually the smallest). Otherwise, attempts to return an irreducible factor of ``self`` of chosen degree ``degree``. diff --git a/src/sage/schemes/elliptic_curves/ell_number_field.py b/src/sage/schemes/elliptic_curves/ell_number_field.py index 8af221880b6..518fda03481 100644 --- a/src/sage/schemes/elliptic_curves/ell_number_field.py +++ b/src/sage/schemes/elliptic_curves/ell_number_field.py @@ -290,7 +290,8 @@ def simon_two_descent(self, verbose=0, lim1=2, lim3=4, limtriv=2, # time (when known_points may have increased) will not cause # another execution of simon_two_descent. try: - result = self._simon_two_descent_data[lim1,lim3,limtriv,maxprob,limbigprime] + result = self._simon_two_descent_data[lim1, lim3, limtriv, + maxprob, limbigprime] if verbose == 0: return result except AttributeError: @@ -2343,7 +2344,7 @@ def gens(self, **kwds): sage: gg=E.gens(lim3=13); gg # long time (about 4s) [(... : 1)] - Check that the the point found has infinite order, and that it is on the curve:: + Check that the point found has infinite order, and that it is on the curve:: sage: P=gg[0]; P.order() # long time +Infinity @@ -2447,7 +2448,7 @@ def period_lattice(self, embedding): -0.14934463314391922099120107422 - 2.0661954627294548995621225062*I) """ from sage.schemes.elliptic_curves.period_lattice import PeriodLattice_ell - return PeriodLattice_ell(self,embedding) + return PeriodLattice_ell(self, embedding) def real_components(self, embedding): """ From 139bd3085b9f53d938d2fe98450e3b24be953fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 16 Jan 2025 13:57:58 +0100 Subject: [PATCH 172/175] some changes about dict in combinat (ruff PLC0206) --- src/sage/combinat/binary_recurrence_sequences.py | 4 ++-- src/sage/combinat/chas/wqsym.py | 6 +++--- src/sage/combinat/designs/bibd.py | 10 +++++----- src/sage/combinat/designs/difference_family.py | 4 ++-- src/sage/combinat/parallelogram_polyomino.py | 3 +-- src/sage/combinat/posets/incidence_algebras.py | 4 ++-- src/sage/combinat/posets/posets.py | 4 ++-- .../combinat/rigged_configurations/kleber_tree.py | 4 ++-- src/sage/combinat/root_system/weyl_characters.py | 11 +++-------- src/sage/combinat/sf/classical.py | 12 ++++++++---- src/sage/combinat/sf/kfpoly.py | 5 +---- src/sage/combinat/sine_gordon.py | 10 +++++----- src/sage/combinat/tableau.py | 11 ++++------- 13 files changed, 40 insertions(+), 48 deletions(-) diff --git a/src/sage/combinat/binary_recurrence_sequences.py b/src/sage/combinat/binary_recurrence_sequences.py index df8de0ada86..fd695c83e0d 100644 --- a/src/sage/combinat/binary_recurrence_sequences.py +++ b/src/sage/combinat/binary_recurrence_sequences.py @@ -729,8 +729,8 @@ def pthpowers(self, p, Bound): # Check how long each element has persisted, if it is for at least 7 cycles, # then we check to see if it is actually a perfect power - for i in Possible_count: - if Possible_count[i] == 7: + for i, pci in Possible_count.items(): + if pci == 7: n = Integer(i) if n < Bound: if _is_p_power(self(n), p): diff --git a/src/sage/combinat/chas/wqsym.py b/src/sage/combinat/chas/wqsym.py index 50811f08cb8..8e100ebcf2e 100644 --- a/src/sage/combinat/chas/wqsym.py +++ b/src/sage/combinat/chas/wqsym.py @@ -986,12 +986,12 @@ def union(X, Y): cur = {data[0]: 1} for B in data[1:]: ret = {} - for A in cur: + for A, curA in cur.items(): for C in ShuffleProduct_overlapping(A, B, element_constructor=OSP, add=union): if C in ret: - ret[C] += cur[A] + ret[C] += curA else: - ret[C] = cur[A] + ret[C] = curA cur = ret # Return the result in the X basis diff --git a/src/sage/combinat/designs/bibd.py b/src/sage/combinat/designs/bibd.py index 09785c3d1da..02391553032 100644 --- a/src/sage/combinat/designs/bibd.py +++ b/src/sage/combinat/designs/bibd.py @@ -1277,14 +1277,14 @@ def BIBD_5q_5_for_q_prime_power(q): d = (q-1)//4 B = [] - F = FiniteField(q,'x') + F = FiniteField(q, 'x') a = F.primitive_element() - L = {b:i for i,b in enumerate(F)} - for b in L: - B.append([i*q + L[b] for i in range(5)]) + L = {b: i for i, b in enumerate(F)} + for b, Lb in L.items(): + B.append([i*q + Lb for i in range(5)]) for i in range(5): for j in range(d): - B.append([ i*q + L[b ], + B.append([ i*q + Lb, ((i+1) % 5)*q + L[ a**j+b ], ((i+1) % 5)*q + L[-a**j+b ], ((i+4) % 5)*q + L[ a**(j+d)+b], diff --git a/src/sage/combinat/designs/difference_family.py b/src/sage/combinat/designs/difference_family.py index 83bfce22eb3..3cb8c96d827 100644 --- a/src/sage/combinat/designs/difference_family.py +++ b/src/sage/combinat/designs/difference_family.py @@ -292,8 +292,8 @@ def is_difference_family(G, D, v=None, k=None, l=None, verbose=False): # Normalized number of occurrences added to counter stabi = len(stab[i]) - for gg in tmp_counter: - counter[gg] += tmp_counter[gg]//stabi + for gg, tmp_gg in tmp_counter.items(): + counter[gg] += tmp_gg // stabi # Check the counter and report any error too_few = [] diff --git a/src/sage/combinat/parallelogram_polyomino.py b/src/sage/combinat/parallelogram_polyomino.py index ac2e7ea6e4d..bbc599aed0c 100644 --- a/src/sage/combinat/parallelogram_polyomino.py +++ b/src/sage/combinat/parallelogram_polyomino.py @@ -311,8 +311,7 @@ def __call__(self, *get_values, **options): {'diagram': 'diagram representation', 'list': 'list representation'}} """ - for key in options: - value = options[key] + for key, value in options.items(): self.__setitem__(key, value) for key in get_values: return self.__getitem__(key) diff --git a/src/sage/combinat/posets/incidence_algebras.py b/src/sage/combinat/posets/incidence_algebras.py index 3fc3f2a0b76..8a5655d0c0f 100644 --- a/src/sage/combinat/posets/incidence_algebras.py +++ b/src/sage/combinat/posets/incidence_algebras.py @@ -456,9 +456,9 @@ def __init__(self, I, prefix='R') -> None: for i in self._ambient.basis().keys(): S = P.subposet(P.interval(*i)) added = False - for k in EC: + for k, ECk in EC.items(): if S._hasse_diagram.is_isomorphic(k._hasse_diagram): - EC[k].append(i) + ECk.append(i) added = True break if not added: diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 389a3ee0061..eb99019506c 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -2058,10 +2058,10 @@ def plot(self, label_elements=True, element_labels=None, 'cover_colors': 'edge_colors', 'cover_style': 'edge_style', 'border': 'graph_border'} - for param in rename: + for param, value in rename.items(): tmp = kwds.pop(param, None) if tmp is not None: - kwds[rename[param]] = tmp + kwds[value] = tmp heights = kwds.pop('heights', None) if heights is None: diff --git a/src/sage/combinat/rigged_configurations/kleber_tree.py b/src/sage/combinat/rigged_configurations/kleber_tree.py index 551c975ce76..e0c16db6553 100644 --- a/src/sage/combinat/rigged_configurations/kleber_tree.py +++ b/src/sage/combinat/rigged_configurations/kleber_tree.py @@ -666,8 +666,8 @@ def latex_options(self, **options): if not options: from copy import copy return copy(self._latex_options) - for k in options: - self._latex_options[k] = options[k] + for key, value in options.items(): + self._latex_options[key] = value def _latex_(self): r""" diff --git a/src/sage/combinat/root_system/weyl_characters.py b/src/sage/combinat/root_system/weyl_characters.py index c8c44224741..2fb2f90bb2e 100644 --- a/src/sage/combinat/root_system/weyl_characters.py +++ b/src/sage/combinat/root_system/weyl_characters.py @@ -761,14 +761,9 @@ def _demazure_helper(self, dd, word='long', debug=False): next[mu] = next.get(mu, 0) - accum[v] if debug: print(" mu=%s, next[mu]=%s" % (mu, next[mu])) - accum = {} - for v in next: - accum[v] = next[v] - ret = {} - for v in accum: - if accum[v]: - ret[self._space.from_vector_notation(v, style='coroots')] = accum[v] - return ret + accum = dict(next) + return {self._space.from_vector_notation(v, style='coroots'): val + for v, val in accum.items() if val} @cached_method def _weight_multiplicities(self, x): diff --git a/src/sage/combinat/sf/classical.py b/src/sage/combinat/sf/classical.py index badea76a0c5..d499ef94143 100644 --- a/src/sage/combinat/sf/classical.py +++ b/src/sage/combinat/sf/classical.py @@ -30,7 +30,11 @@ from . import jack from . import orthotriang -translate = {'monomial':'MONOMIAL', 'homogeneous':'HOMSYM', 'powersum':'POWSYM', 'elementary':'ELMSYM', 'Schur':'SCHUR'} +translate = {'monomial': 'MONOMIAL', + 'homogeneous': 'HOMSYM', + 'powersum': 'POWSYM', + 'elementary': 'ELMSYM', + 'Schur': 'SCHUR'} conversion_functions = {} @@ -55,11 +59,11 @@ def init(): s[1, 1, 1, 1] - s[2, 1, 1] + 2*s[2, 2] - s[3, 1] + s[4] """ import sage.libs.symmetrica.all as symmetrica - for other_basis in translate: - for basis in translate: + for other_basis, other_name in translate.items(): + for basis, name in translate.items(): try: conversion_functions[(other_basis, basis)] = getattr(symmetrica, - 't_{}_{}'.format(translate[other_basis], translate[basis])) + f't_{other_name}_{name}') except AttributeError: pass diff --git a/src/sage/combinat/sf/kfpoly.py b/src/sage/combinat/sf/kfpoly.py index d58fb746780..df42f685ddd 100644 --- a/src/sage/combinat/sf/kfpoly.py +++ b/src/sage/combinat/sf/kfpoly.py @@ -197,10 +197,7 @@ def schur_to_hl(mu, t=None): for rg in riggings(mu): res[rg[0]] = res.get(rg[0], 0) + weight(rg, t) - d = {} - for key in res: - d[ key.conjugate() ] = res[key] - return d + return {key.conjugate(): res[key] for key in res} def riggings(part): diff --git a/src/sage/combinat/sine_gordon.py b/src/sage/combinat/sine_gordon.py index 1891f172d38..f3b8ac496a9 100644 --- a/src/sage/combinat/sine_gordon.py +++ b/src/sage/combinat/sine_gordon.py @@ -598,11 +598,11 @@ def vertex_to_angle(v): **triangulation_opts) P += point((0, 0), zorder=len(P), **points_opts) # Vertices - v_points = {x: (radius * cos(vertex_to_angle(x)), - radius * sin(vertex_to_angle(x))) - for x in self.vertices()} - for v in v_points: - P += point(v_points[v], zorder=len(P), **points_opts) + v_points = [(radius * cos(vertex_to_angle(x)), + radius * sin(vertex_to_angle(x))) + for x in self.vertices()] + for coords in v_points: + P += point(coords, zorder=len(P), **points_opts) # Reflection axes P += line([(0, 1.1 * radius), (0, -1.1 * radius)], zorder=len(P), **reflections_opts) diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index cb912e67409..e33815dbf8f 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -6973,15 +6973,12 @@ def __contains__(self, x): for row in x: for i in row: content[i] = content.get(i, 0) + 1 - content_list = [0]*int(max(content)) + content_list = [0] * int(max(content)) - for key in content: - content_list[key-1] = content[key] + for key, c in content.items(): + content_list[key - 1] = c - if content_list != self.weight: - return False - - return True + return content_list == self.weight def cardinality(self): """ From ee1385ac4da43e3ecce9fecf5f3f95f2870be304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 16 Jan 2025 14:39:29 +0100 Subject: [PATCH 173/175] some ruff suggestions in algebras/ --- src/sage/algebras/cluster_algebra.py | 8 ++++---- src/sage/algebras/fusion_rings/fusion_ring.py | 7 +++---- .../hecke_algebras/ariki_koike_algebra.py | 16 +++++++--------- src/sage/algebras/lie_algebras/verma_module.py | 14 ++++++++------ src/sage/algebras/rational_cherednik_algebra.py | 17 +++++++++-------- src/sage/algebras/steenrod/steenrod_algebra.py | 7 +++---- 6 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/sage/algebras/cluster_algebra.py b/src/sage/algebras/cluster_algebra.py index 6772673cbcb..ca34a34acfc 100644 --- a/src/sage/algebras/cluster_algebra.py +++ b/src/sage/algebras/cluster_algebra.py @@ -572,12 +572,12 @@ def homogeneous_components(self) -> dict: components[g_vect] += self.parent().retract(x.monomial_coefficient(m) * m) else: components[g_vect] = self.parent().retract(x.monomial_coefficient(m) * m) - for g_vect in components: - components[g_vect]._is_homogeneous = True - components[g_vect]._g_vector = g_vect + for g_vect, compo in components.items(): + compo._is_homogeneous = True + compo._g_vector = g_vect self._is_homogeneous = (len(components) == 1) if self._is_homogeneous: - self._g_vector = list(components.keys())[0] + self._g_vector = next(iter(components)) return components def theta_basis_decomposition(self): diff --git a/src/sage/algebras/fusion_rings/fusion_ring.py b/src/sage/algebras/fusion_rings/fusion_ring.py index 56045d2dce6..e454b07dfcb 100644 --- a/src/sage/algebras/fusion_rings/fusion_ring.py +++ b/src/sage/algebras/fusion_rings/fusion_ring.py @@ -1564,15 +1564,14 @@ def q_dimension(self, base_coercion=True): R = ZZ['q'] q = R.gen() expr = R.fraction_field().one() - for val in powers: - exp = powers[val] + for val, exp in powers.items(): if exp > 0: expr *= q_int(P._nf * val, q)**exp elif exp < 0: expr /= q_int(P._nf * val, q)**(-exp) expr = R(expr) - expr = expr.substitute(q=q**4) / (q**(2*expr.degree())) - zet = P.field().gen() ** (P._cyclotomic_order/P._l) + expr = expr.substitute(q=q**4) / (q**(2 * expr.degree())) + zet = P.field().gen() ** (P._cyclotomic_order / P._l) ret = expr.substitute(q=zet) if (not base_coercion) or (self.parent()._basecoer is None): diff --git a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py index 8d674d0aaf1..e6368ea8389 100644 --- a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py +++ b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py @@ -954,9 +954,8 @@ def _product_LTwTv(self, L, w, v): ret = {v: self.base_ring().one()} qm1 = self._q - self.base_ring().one() for i in reversed(w.reduced_word()): - temp = {} # start from 0 - for p in ret: - c = ret[p] + temp = {} # start from 0 + for p, c in ret.items(): # We have to flip the side due to Sage's # convention for multiplying permutations pi = p.apply_simple_reflection(i, side='left') @@ -965,7 +964,7 @@ def _product_LTwTv(self, L, w, v): else: iaxpy(1, {pi: c}, temp) ret = temp - return {(L, p): ret[p] for p in ret} + return {(L, p): c for p, c in ret.items()} def _product_Tw_L(self, w, L): r""" @@ -1011,10 +1010,9 @@ def _product_Tw_L(self, w, L): q = self._q one = q.parent().one() for i in w.reduced_word()[::-1]: - iL = {} # this will become T_i * L, written in standard form - for lv in wL: - c = wL[lv] - L = list(lv[0]) # make a copy + iL = {} # this will become T_i * L, written in standard form + for lv, c in wL.items(): + L = list(lv[0]) # make a copy v = lv[1] a, b = L[i-1], L[i] L[i-1], L[i] = L[i], L[i-1] # swap L_i=L[i-1] and L_{i+1}=L[i] @@ -1038,7 +1036,7 @@ def _product_Tw_L(self, w, L): c *= (one - q) iaxpy(1, {(tuple(l), v): c for l in Ls}, iL) - wL = iL # replace wL with iL and repeat + wL = iL # replace wL with iL and repeat return self._from_dict(wL, remove_zeros=False, coerce=False) @cached_method diff --git a/src/sage/algebras/lie_algebras/verma_module.py b/src/sage/algebras/lie_algebras/verma_module.py index 01320616c5a..71ea8e68cb9 100644 --- a/src/sage/algebras/lie_algebras/verma_module.py +++ b/src/sage/algebras/lie_algebras/verma_module.py @@ -701,21 +701,23 @@ def _homogeneous_component_f(self, d): """ if not d: return frozenset([self.highest_weight_vector()]) - f = {i: self._pbw(g) for i,g in enumerate(self._g.f())} - basis = d.parent().basis() # Standard basis vectors + f = {i: self._pbw(g) for i, g in enumerate(self._g.f())} + basis = d.parent().basis() # Standard basis vectors ret = set() def degree(m): m = m.dict() if not m: return d.parent().zero() - return sum(e * self._g.degree_on_basis(k) for k,e in m.items()).to_vector() - for i in f: + return sum(e * self._g.degree_on_basis(k) + for k, e in m.items()).to_vector() + for i, fi in f.items(): if d[i] == 0: continue for b in self._homogeneous_component_f(d + basis[i]): - temp = f[i] * b - ret.update([self.monomial(m) for m in temp.support() if degree(m) == d]) + temp = fi * b + ret.update([self.monomial(m) for m in temp.support() + if degree(m) == d]) return frozenset(ret) def _Hom_(self, Y, category=None, **options): diff --git a/src/sage/algebras/rational_cherednik_algebra.py b/src/sage/algebras/rational_cherednik_algebra.py index 1ded26a1112..537f39e8f68 100644 --- a/src/sage/algebras/rational_cherednik_algebra.py +++ b/src/sage/algebras/rational_cherednik_algebra.py @@ -369,18 +369,19 @@ def commute_w_hd(w, al): # al is given as a dictionary # so we must commute Lac Rs = Rs Lac' # and obtain La (Ls Rs) (Lac' Rac) ret = P.one() - for k in dl: + r1_red = right[1].reduced_word() + for k, dlk in dl.items(): x = sum(c * gens_dict[i] - for i,c in alphacheck[k].weyl_action(right[1].reduced_word(), - inverse=True)) - ret *= x**dl[k] + for i, c in alphacheck[k].weyl_action(r1_red, + inverse=True)) + ret *= x**dlk ret = ret.monomial_coefficients() - w = left[1]*right[1] + w = left[1] * right[1] return self._from_dict({(left[0], w, - self._h({I[i]: e for i,e in enumerate(k) - if e != 0}) * right[2] + self._h({I[i]: e for i, e in enumerate(k) + if e != 0}) * right[2] ): ret[k] - for k in ret}) + for k in ret}) # Otherwise dr is non-trivial and we have La Ls Ra Rs Rac, # so we must commute Ls Ra = Ra' Ls diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index 540cb6ee92d..63b9ac3d9b4 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -1346,10 +1346,9 @@ def coprod_list(t): right_q = sorted(all_q - a) sign = Permutation(convert_perm(left_q + right_q)).signature() tens_q[(tuple(left_q), tuple(right_q))] = sign - tens = {} - for l, r in zip(left_p, right_p): - for q in tens_q: - tens[((q[0], l), (q[1], r))] = tens_q[q] + tens = {((q[0], l), (q[1], r)): tq + for l, r in zip(left_p, right_p) + for q, tq in tens_q.items()} return self.tensor_square()._from_dict(tens, coerce=True) elif basis == 'serre-cartan': result = self.tensor_square().one() From 1a0a16d2c6cb3d1b3a98f0a31eafe4f3f71bb8c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 16 Jan 2025 18:09:01 +0100 Subject: [PATCH 174/175] sugegsted detail --- src/sage/combinat/sf/kfpoly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/sf/kfpoly.py b/src/sage/combinat/sf/kfpoly.py index df42f685ddd..01470a24b5a 100644 --- a/src/sage/combinat/sf/kfpoly.py +++ b/src/sage/combinat/sf/kfpoly.py @@ -197,7 +197,7 @@ def schur_to_hl(mu, t=None): for rg in riggings(mu): res[rg[0]] = res.get(rg[0], 0) + weight(rg, t) - return {key.conjugate(): res[key] for key in res} + return {key.conjugate(): value for key, value in res.items()} def riggings(part): From 5188024881df509aee12e59e4d8ebf003c675e4a Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sat, 18 Jan 2025 12:16:57 +0100 Subject: [PATCH 175/175] Updated SageMath version to 10.6.beta4 --- 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 9cc52984028..1a4f50ce0c0 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.beta3 +version: 10.6.beta4 doi: 10.5281/zenodo.8042260 -date-released: 2025-01-04 +date-released: 2025-01-18 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 7530113eb48..c6b18bd1ad9 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.6.beta3, Release Date: 2025-01-04 +SageMath version 10.6.beta4, Release Date: 2025-01-18 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index f53f99cbe10..8adc17b1426 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,3 +1,3 @@ tarball=configure-VERSION.tar.gz -sha1=0c3839396c1925ed5f34ae2332f2af284d42bd4f -sha256=f15f6168285c6503516ab8787770f805324f8b3a74414cd4409ad382b9859328 +sha1=f9c1bea6113a6a09430ee1f1aca16c75ed427d48 +sha256=c1e0826fb54dd60e78f19e6fcad0b0ef90b33e1771fbbc2165a54c9297a89557 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 8d202f6a3ee..0597496b77d 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -9b7fe9ce8099decea34168e2dc536ce64465ceda +5eb37241946a9ef9130ce36eff7e4f135d980eaf diff --git a/build/pkgs/sage_conf/version_requirements.txt b/build/pkgs/sage_conf/version_requirements.txt index 89c6b32ac8e..0a47bcf1281 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.6b3 +sage-conf ~= 10.6b4 diff --git a/build/pkgs/sage_docbuild/version_requirements.txt b/build/pkgs/sage_docbuild/version_requirements.txt index 0db09dcea0c..2986652773e 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.6b3 +sage-docbuild ~= 10.6b4 diff --git a/build/pkgs/sage_setup/version_requirements.txt b/build/pkgs/sage_setup/version_requirements.txt index 48a5d6a2975..3d739f2c183 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.6b3 +sage-setup ~= 10.6b4 diff --git a/build/pkgs/sage_sws2rst/version_requirements.txt b/build/pkgs/sage_sws2rst/version_requirements.txt index 10fe0a5d243..a1c57461d38 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.6b3 +sage-sws2rst ~= 10.6b4 diff --git a/build/pkgs/sagelib/version_requirements.txt b/build/pkgs/sagelib/version_requirements.txt index 9955b423733..09e6e070dbf 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.6b3 +sagemath-standard ~= 10.6b4 diff --git a/build/pkgs/sagemath_bliss/version_requirements.txt b/build/pkgs/sagemath_bliss/version_requirements.txt index 07444bffe02..370e9dc8d11 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.6b3 +sagemath-bliss ~= 10.6b4 diff --git a/build/pkgs/sagemath_categories/version_requirements.txt b/build/pkgs/sagemath_categories/version_requirements.txt index 3693bc6b268..6e0f464e560 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.6b3 +sagemath-categories ~= 10.6b4 diff --git a/build/pkgs/sagemath_coxeter3/version_requirements.txt b/build/pkgs/sagemath_coxeter3/version_requirements.txt index 218445145e4..825ad688d44 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.6b3 +sagemath-coxeter3 ~= 10.6b4 diff --git a/build/pkgs/sagemath_environment/version_requirements.txt b/build/pkgs/sagemath_environment/version_requirements.txt index f8afafd91b2..27e9c97c883 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.6b3 +sagemath-environment ~= 10.6b4 diff --git a/build/pkgs/sagemath_mcqd/version_requirements.txt b/build/pkgs/sagemath_mcqd/version_requirements.txt index c2a89dc2f8b..32529957f70 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.6b3 +sagemath-mcqd ~= 10.6b4 diff --git a/build/pkgs/sagemath_meataxe/version_requirements.txt b/build/pkgs/sagemath_meataxe/version_requirements.txt index 2347bb33a2a..f579dd099c5 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.6b3 +sagemath-meataxe ~= 10.6b4 diff --git a/build/pkgs/sagemath_objects/version_requirements.txt b/build/pkgs/sagemath_objects/version_requirements.txt index f332b86d4c1..92754c524f1 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.6b3 +sagemath-objects ~= 10.6b4 diff --git a/build/pkgs/sagemath_repl/version_requirements.txt b/build/pkgs/sagemath_repl/version_requirements.txt index 334e1a9cd4c..ca8348f0f76 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.6b3 +sagemath-repl ~= 10.6b4 diff --git a/build/pkgs/sagemath_sirocco/version_requirements.txt b/build/pkgs/sagemath_sirocco/version_requirements.txt index 83304b67094..881707ea9d5 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.6b3 +sagemath-sirocco ~= 10.6b4 diff --git a/build/pkgs/sagemath_tdlib/version_requirements.txt b/build/pkgs/sagemath_tdlib/version_requirements.txt index 162e0933241..8110525f3b7 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.6b3 +sagemath-tdlib ~= 10.6b4 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/src/VERSION.txt b/src/VERSION.txt index 4b1bf4be363..8595985e4bf 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.6.beta3 +10.6.beta4 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 873f0e5daf9..ddaee05e046 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.beta3' -SAGE_RELEASE_DATE='2025-01-04' -SAGE_VERSION_BANNER='SageMath version 10.6.beta3, Release Date: 2025-01-04' +SAGE_VERSION='10.6.beta4' +SAGE_RELEASE_DATE='2025-01-18' +SAGE_VERSION_BANNER='SageMath version 10.6.beta4, Release Date: 2025-01-18' diff --git a/src/sage/version.py b/src/sage/version.py index b25d448757f..16c67de2983 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.beta3' -date = '2025-01-04' -banner = 'SageMath version 10.6.beta3, Release Date: 2025-01-04' +version = '10.6.beta4' +date = '2025-01-18' +banner = 'SageMath version 10.6.beta4, Release Date: 2025-01-18'